Codebase list libcryptx-perl / 964d0bf
rename src dirs Karel Miko 10 years ago
834 changed file(s) with 62462 addition(s) and 62464 deletion(s). Raw diff Collapse all Expand all
33 use Module::Build;
44 use Config;
55
6 my $src = 'libtom-src';
7 my $flags = '-Ilibtom-src/headers -DLTC_SOURCE -DLTC_NO_TEST -DLTC_NO_PROTOTYPES -Ilibtom-src -DLTM_DESC';
8
6 my $flags = '-Isrc/ltc/headers -Isrc/ltm -DLTC_SOURCE -DLTC_NO_TEST -DLTC_NO_PROTOTYPES -DLTM_DESC';
97 #$flags .= ' -DLTC_NO_ASM';
108 #$flags .= ' -Wall';
119
6058 license => 'perl',
6159 create_readme => 1,
6260 extra_compiler_flags => $flags,
63 c_source => $src,
61 c_source => 'src',
6462 requires => {
6563 'perl' => '5.006',
6664 'MIME::Base64' => '3.11', # we need: encode_base64url
00 @echo off
11 echo STARTED...
2 xcopy /Y y:\_repos\libtommath\*.c y:\_repos\_mygit\perl-cryptx\libtommath-src
3 xcopy /Y y:\_repos\libtommath\*.h y:\_repos\_mygit\perl-cryptx\libtommath-src
4 xcopy /Y /E y:\_repos\libtomcrypt\src\* y:\_repos\_mygit\perl-cryptx\libtomcrypt-src
2 xcopy /Y y:\_repos\libtommath\*.c d:\git\cryptx\src\ltm
3 xcopy /Y y:\_repos\libtommath\*.h d:\git\cryptx\src\ltm
4 xcopy /Y /E y:\_repos\libtomcrypt\src\* d:\git\cryptx\src\ltc
55 perl fix_src.pl
66 echo DONE!
77 pause
3434
3535 ### MAIN
3636
37 my $srcdir = catdir($FindBin::Bin, "..", "libtomcrypt-src");
37 my $srcdir = catdir($FindBin::Bin, "..", "src/ltc");
3838
3939 my @lines = read_file("$srcdir/headers/tomcrypt_custom.h");
4040 @lines = map { s|^([\t\s]*)#define LTC_YARROW_AES \d+|$1#define LTC_YARROW_AES 3|; $_ } @lines;
33 use File::Find 'find';
44
55 my @files;
6 find({ wanted=>sub { push @files, $_ if /\.o$/ }, no_chdir=>1 }, 'libtom-src');
6 find({ wanted=>sub { push @files, $_ if /\.o$/ }, no_chdir=>1 }, 'src/ltc');
77
88 system('ar', 'csr', 'libjumbo.a', @files);
99 system('ranlib', 'libjumbo.a');
+0
-47
libtom-src/bn_error.c less more
0 #include <tommath.h>
1 #ifdef BN_ERROR_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 static const struct {
18 int code;
19 const char *msg;
20 } msgs[] = {
21 { MP_OKAY, "Successful" },
22 { MP_MEM, "Out of heap" },
23 { MP_VAL, "Value out of range" }
24 };
25
26 /* return a char * string for a given code */
27 const char *mp_error_to_string(int code)
28 {
29 int x;
30
31 /* scan the lookup table for the given message */
32 for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
33 if (msgs[x].code == code) {
34 return msgs[x].msg;
35 }
36 }
37
38 /* generic reply for invalid code */
39 return "Invalid error code";
40 }
41
42 #endif
43
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
+0
-148
libtom-src/bn_fast_mp_invmod.c less more
0 #include <tommath.h>
1 #ifdef BN_FAST_MP_INVMOD_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 /* computes the modular inverse via binary extended euclidean algorithm,
18 * that is c = 1/a mod b
19 *
20 * Based on slow invmod except this is optimized for the case where b is
21 * odd as per HAC Note 14.64 on pp. 610
22 */
23 int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
24 {
25 mp_int x, y, u, v, B, D;
26 int res, neg;
27
28 /* 2. [modified] b must be odd */
29 if (mp_iseven (b) == 1) {
30 return MP_VAL;
31 }
32
33 /* init all our temps */
34 if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
35 return res;
36 }
37
38 /* x == modulus, y == value to invert */
39 if ((res = mp_copy (b, &x)) != MP_OKAY) {
40 goto LBL_ERR;
41 }
42
43 /* we need y = |a| */
44 if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
45 goto LBL_ERR;
46 }
47
48 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
49 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
50 goto LBL_ERR;
51 }
52 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 mp_set (&D, 1);
56
57 top:
58 /* 4. while u is even do */
59 while (mp_iseven (&u) == 1) {
60 /* 4.1 u = u/2 */
61 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
62 goto LBL_ERR;
63 }
64 /* 4.2 if B is odd then */
65 if (mp_isodd (&B) == 1) {
66 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
67 goto LBL_ERR;
68 }
69 }
70 /* B = B/2 */
71 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
72 goto LBL_ERR;
73 }
74 }
75
76 /* 5. while v is even do */
77 while (mp_iseven (&v) == 1) {
78 /* 5.1 v = v/2 */
79 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
80 goto LBL_ERR;
81 }
82 /* 5.2 if D is odd then */
83 if (mp_isodd (&D) == 1) {
84 /* D = (D-x)/2 */
85 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
86 goto LBL_ERR;
87 }
88 }
89 /* D = D/2 */
90 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
91 goto LBL_ERR;
92 }
93 }
94
95 /* 6. if u >= v then */
96 if (mp_cmp (&u, &v) != MP_LT) {
97 /* u = u - v, B = B - D */
98 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
99 goto LBL_ERR;
100 }
101
102 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
103 goto LBL_ERR;
104 }
105 } else {
106 /* v - v - u, D = D - B */
107 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
108 goto LBL_ERR;
109 }
110
111 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
112 goto LBL_ERR;
113 }
114 }
115
116 /* if not zero goto step 4 */
117 if (mp_iszero (&u) == 0) {
118 goto top;
119 }
120
121 /* now a = C, b = D, gcd == g*v */
122
123 /* if v != 1 then there is no inverse */
124 if (mp_cmp_d (&v, 1) != MP_EQ) {
125 res = MP_VAL;
126 goto LBL_ERR;
127 }
128
129 /* b is now the inverse */
130 neg = a->sign;
131 while (D.sign == MP_NEG) {
132 if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
133 goto LBL_ERR;
134 }
135 }
136 mp_exch (&D, c);
137 c->sign = neg;
138 res = MP_OKAY;
139
140 LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
141 return res;
142 }
143 #endif
144
145 /* $Source$ */
146 /* $Revision$ */
147 /* $Date$ */
+0
-172
libtom-src/bn_fast_mp_montgomery_reduce.c less more
0 #include <tommath.h>
1 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_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 /* computes xR**-1 == x (mod N) via Montgomery Reduction
18 *
19 * This is an optimized implementation of montgomery_reduce
20 * which uses the comba method to quickly calculate the columns of the
21 * reduction.
22 *
23 * Based on Algorithm 14.32 on pp.601 of HAC.
24 */
25 int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
26 {
27 int ix, res, olduse;
28 mp_word W[MP_WARRAY];
29
30 /* get old used count */
31 olduse = x->used;
32
33 /* grow a as required */
34 if (x->alloc < n->used + 1) {
35 if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
36 return res;
37 }
38 }
39
40 /* first we have to get the digits of the input into
41 * an array of double precision words W[...]
42 */
43 {
44 register mp_word *_W;
45 register mp_digit *tmpx;
46
47 /* alias for the W[] array */
48 _W = W;
49
50 /* alias for the digits of x*/
51 tmpx = x->dp;
52
53 /* copy the digits of a into W[0..a->used-1] */
54 for (ix = 0; ix < x->used; ix++) {
55 *_W++ = *tmpx++;
56 }
57
58 /* zero the high words of W[a->used..m->used*2] */
59 for (; ix < n->used * 2 + 1; ix++) {
60 *_W++ = 0;
61 }
62 }
63
64 /* now we proceed to zero successive digits
65 * from the least significant upwards
66 */
67 for (ix = 0; ix < n->used; ix++) {
68 /* mu = ai * m' mod b
69 *
70 * We avoid a double precision multiplication (which isn't required)
71 * by casting the value down to a mp_digit. Note this requires
72 * that W[ix-1] have the carry cleared (see after the inner loop)
73 */
74 register mp_digit mu;
75 mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
76
77 /* a = a + mu * m * b**i
78 *
79 * This is computed in place and on the fly. The multiplication
80 * by b**i is handled by offseting which columns the results
81 * are added to.
82 *
83 * Note the comba method normally doesn't handle carries in the
84 * inner loop In this case we fix the carry from the previous
85 * column since the Montgomery reduction requires digits of the
86 * result (so far) [see above] to work. This is
87 * handled by fixing up one carry after the inner loop. The
88 * carry fixups are done in order so after these loops the
89 * first m->used words of W[] have the carries fixed
90 */
91 {
92 register int iy;
93 register mp_digit *tmpn;
94 register mp_word *_W;
95
96 /* alias for the digits of the modulus */
97 tmpn = n->dp;
98
99 /* Alias for the columns set by an offset of ix */
100 _W = W + ix;
101
102 /* inner loop */
103 for (iy = 0; iy < n->used; iy++) {
104 *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
105 }
106 }
107
108 /* now fix carry for next digit, W[ix+1] */
109 W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
110 }
111
112 /* now we have to propagate the carries and
113 * shift the words downward [all those least
114 * significant digits we zeroed].
115 */
116 {
117 register mp_digit *tmpx;
118 register mp_word *_W, *_W1;
119
120 /* nox fix rest of carries */
121
122 /* alias for current word */
123 _W1 = W + ix;
124
125 /* alias for next word, where the carry goes */
126 _W = W + ++ix;
127
128 for (; ix <= n->used * 2 + 1; ix++) {
129 *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
130 }
131
132 /* copy out, A = A/b**n
133 *
134 * The result is A/b**n but instead of converting from an
135 * array of mp_word to mp_digit than calling mp_rshd
136 * we just copy them in the right order
137 */
138
139 /* alias for destination word */
140 tmpx = x->dp;
141
142 /* alias for shifted double precision result */
143 _W = W + n->used;
144
145 for (ix = 0; ix < n->used + 1; ix++) {
146 *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
147 }
148
149 /* zero oldused digits, if the input a was larger than
150 * m->used+1 we'll have to clear the digits
151 */
152 for (; ix < olduse; ix++) {
153 *tmpx++ = 0;
154 }
155 }
156
157 /* set the max used and clamp */
158 x->used = n->used + 1;
159 mp_clamp (x);
160
161 /* if A >= m then A = A - m */
162 if (mp_cmp_mag (x, n) != MP_LT) {
163 return s_mp_sub (x, n, x);
164 }
165 return MP_OKAY;
166 }
167 #endif
168
169 /* $Source$ */
170 /* $Revision$ */
171 /* $Date$ */
+0
-107
libtom-src/bn_fast_s_mp_mul_digs.c less more
0 #include <tommath.h>
1 #ifdef BN_FAST_S_MP_MUL_DIGS_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 /* Fast (comba) multiplier
18 *
19 * This is the fast column-array [comba] multiplier. It is
20 * designed to compute the columns of the product first
21 * then handle the carries afterwards. This has the effect
22 * of making the nested loops that compute the columns very
23 * simple and schedulable on super-scalar processors.
24 *
25 * This has been modified to produce a variable number of
26 * digits of output so if say only a half-product is required
27 * you don't have to compute the upper half (a feature
28 * required for fast Barrett reduction).
29 *
30 * Based on Algorithm 14.12 on pp.595 of HAC.
31 *
32 */
33 int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
34 {
35 int olduse, res, pa, ix, iz;
36 mp_digit W[MP_WARRAY];
37 register mp_word _W;
38
39 /* grow the destination as required */
40 if (c->alloc < digs) {
41 if ((res = mp_grow (c, digs)) != MP_OKAY) {
42 return res;
43 }
44 }
45
46 /* number of output digits to produce */
47 pa = MIN(digs, a->used + b->used);
48
49 /* clear the carry */
50 _W = 0;
51 for (ix = 0; ix < pa; ix++) {
52 int tx, ty;
53 int iy;
54 mp_digit *tmpx, *tmpy;
55
56 /* get offsets into the two bignums */
57 ty = MIN(b->used-1, ix);
58 tx = ix - ty;
59
60 /* setup temp aliases */
61 tmpx = a->dp + tx;
62 tmpy = b->dp + ty;
63
64 /* this is the number of times the loop will iterrate, essentially
65 while (tx++ < a->used && ty-- >= 0) { ... }
66 */
67 iy = MIN(a->used-tx, ty+1);
68
69 /* execute loop */
70 for (iz = 0; iz < iy; ++iz) {
71 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
72
73 }
74
75 /* store term */
76 W[ix] = ((mp_digit)_W) & MP_MASK;
77
78 /* make next carry */
79 _W = _W >> ((mp_word)DIGIT_BIT);
80 }
81
82 /* setup dest */
83 olduse = c->used;
84 c->used = pa;
85
86 {
87 register mp_digit *tmpc;
88 tmpc = c->dp;
89 for (ix = 0; ix < pa+1; ix++) {
90 /* now extract the previous digit [below the carry] */
91 *tmpc++ = W[ix];
92 }
93
94 /* clear unused digits [that existed in the old copy of c] */
95 for (; ix < olduse; ix++) {
96 *tmpc++ = 0;
97 }
98 }
99 mp_clamp (c);
100 return MP_OKAY;
101 }
102 #endif
103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
+0
-98
libtom-src/bn_fast_s_mp_mul_high_digs.c less more
0 #include <tommath.h>
1 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_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 /* this is a modified version of fast_s_mul_digs that only produces
18 * output digits *above* digs. See the comments for fast_s_mul_digs
19 * to see how it works.
20 *
21 * This is used in the Barrett reduction since for one of the multiplications
22 * only the higher digits were needed. This essentially halves the work.
23 *
24 * Based on Algorithm 14.12 on pp.595 of HAC.
25 */
26 int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
27 {
28 int olduse, res, pa, ix, iz;
29 mp_digit W[MP_WARRAY];
30 mp_word _W;
31
32 /* grow the destination as required */
33 pa = a->used + b->used;
34 if (c->alloc < pa) {
35 if ((res = mp_grow (c, pa)) != MP_OKAY) {
36 return res;
37 }
38 }
39
40 /* number of output digits to produce */
41 pa = a->used + b->used;
42 _W = 0;
43 for (ix = digs; ix < pa; ix++) {
44 int tx, ty, iy;
45 mp_digit *tmpx, *tmpy;
46
47 /* get offsets into the two bignums */
48 ty = MIN(b->used-1, ix);
49 tx = ix - ty;
50
51 /* setup temp aliases */
52 tmpx = a->dp + tx;
53 tmpy = b->dp + ty;
54
55 /* this is the number of times the loop will iterrate, essentially its
56 while (tx++ < a->used && ty-- >= 0) { ... }
57 */
58 iy = MIN(a->used-tx, ty+1);
59
60 /* execute loop */
61 for (iz = 0; iz < iy; iz++) {
62 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
63 }
64
65 /* store term */
66 W[ix] = ((mp_digit)_W) & MP_MASK;
67
68 /* make next carry */
69 _W = _W >> ((mp_word)DIGIT_BIT);
70 }
71
72 /* setup dest */
73 olduse = c->used;
74 c->used = pa;
75
76 {
77 register mp_digit *tmpc;
78
79 tmpc = c->dp + digs;
80 for (ix = digs; ix < pa; ix++) {
81 /* now extract the previous digit [below the carry] */
82 *tmpc++ = W[ix];
83 }
84
85 /* clear unused digits [that existed in the old copy of c] */
86 for (; ix < olduse; ix++) {
87 *tmpc++ = 0;
88 }
89 }
90 mp_clamp (c);
91 return MP_OKAY;
92 }
93 #endif
94
95 /* $Source$ */
96 /* $Revision$ */
97 /* $Date$ */
+0
-114
libtom-src/bn_fast_s_mp_sqr.c less more
0 #include <tommath.h>
1 #ifdef BN_FAST_S_MP_SQR_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 /* the jist of squaring...
18 * you do like mult except the offset of the tmpx [one that
19 * starts closer to zero] can't equal the offset of tmpy.
20 * So basically you set up iy like before then you min it with
21 * (ty-tx) so that it never happens. You double all those
22 * you add in the inner loop
23
24 After that loop you do the squares and add them in.
25 */
26
27 int fast_s_mp_sqr (mp_int * a, mp_int * b)
28 {
29 int olduse, res, pa, ix, iz;
30 mp_digit W[MP_WARRAY], *tmpx;
31 mp_word W1;
32
33 /* grow the destination as required */
34 pa = a->used + a->used;
35 if (b->alloc < pa) {
36 if ((res = mp_grow (b, pa)) != MP_OKAY) {
37 return res;
38 }
39 }
40
41 /* number of output digits to produce */
42 W1 = 0;
43 for (ix = 0; ix < pa; ix++) {
44 int tx, ty, iy;
45 mp_word _W;
46 mp_digit *tmpy;
47
48 /* clear counter */
49 _W = 0;
50
51 /* get offsets into the two bignums */
52 ty = MIN(a->used-1, ix);
53 tx = ix - ty;
54
55 /* setup temp aliases */
56 tmpx = a->dp + tx;
57 tmpy = a->dp + ty;
58
59 /* this is the number of times the loop will iterrate, essentially
60 while (tx++ < a->used && ty-- >= 0) { ... }
61 */
62 iy = MIN(a->used-tx, ty+1);
63
64 /* now for squaring tx can never equal ty
65 * we halve the distance since they approach at a rate of 2x
66 * and we have to round because odd cases need to be executed
67 */
68 iy = MIN(iy, (ty-tx+1)>>1);
69
70 /* execute loop */
71 for (iz = 0; iz < iy; iz++) {
72 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
73 }
74
75 /* double the inner product and add carry */
76 _W = _W + _W + W1;
77
78 /* even columns have the square term in them */
79 if ((ix&1) == 0) {
80 _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
81 }
82
83 /* store it */
84 W[ix] = (mp_digit)(_W & MP_MASK);
85
86 /* make next carry */
87 W1 = _W >> ((mp_word)DIGIT_BIT);
88 }
89
90 /* setup dest */
91 olduse = b->used;
92 b->used = a->used+a->used;
93
94 {
95 mp_digit *tmpb;
96 tmpb = b->dp;
97 for (ix = 0; ix < pa; ix++) {
98 *tmpb++ = W[ix] & MP_MASK;
99 }
100
101 /* clear unused digits [that existed in the old copy of c] */
102 for (; ix < olduse; ix++) {
103 *tmpb++ = 0;
104 }
105 }
106 mp_clamp (b);
107 return MP_OKAY;
108 }
109 #endif
110
111 /* $Source$ */
112 /* $Revision$ */
113 /* $Date$ */
+0
-48
libtom-src/bn_mp_2expt.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_2EXPT_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 /* computes a = 2**b
18 *
19 * Simple algorithm which zeroes the int, grows it then just sets one bit
20 * as required.
21 */
22 int
23 mp_2expt (mp_int * a, int b)
24 {
25 int res;
26
27 /* zero a as per default */
28 mp_zero (a);
29
30 /* grow a to accomodate the single bit */
31 if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
32 return res;
33 }
34
35 /* set the used count of where the bit will go */
36 a->used = b / DIGIT_BIT + 1;
37
38 /* put the single bit in its place */
39 a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
40
41 return MP_OKAY;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
+0
-43
libtom-src/bn_mp_abs.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_ABS_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 /* b = |a|
18 *
19 * Simple function copies the input and fixes the sign to positive
20 */
21 int
22 mp_abs (mp_int * a, mp_int * b)
23 {
24 int res;
25
26 /* copy a to b */
27 if (a != b) {
28 if ((res = mp_copy (a, b)) != MP_OKAY) {
29 return res;
30 }
31 }
32
33 /* force the sign of b to positive */
34 b->sign = MP_ZPOS;
35
36 return MP_OKAY;
37 }
38 #endif
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
+0
-53
libtom-src/bn_mp_add.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_ADD_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 /* high level addition (handles signs) */
18 int mp_add (mp_int * a, mp_int * b, mp_int * c)
19 {
20 int sa, sb, res;
21
22 /* get sign of both inputs */
23 sa = a->sign;
24 sb = b->sign;
25
26 /* handle two cases, not four */
27 if (sa == sb) {
28 /* both positive or both negative */
29 /* add their magnitudes, copy the sign */
30 c->sign = sa;
31 res = s_mp_add (a, b, c);
32 } else {
33 /* one positive, the other negative */
34 /* subtract the one with the greater magnitude from */
35 /* the one of the lesser magnitude. The result gets */
36 /* the sign of the one with the greater magnitude. */
37 if (mp_cmp_mag (a, b) == MP_LT) {
38 c->sign = sb;
39 res = s_mp_sub (b, a, c);
40 } else {
41 c->sign = sa;
42 res = s_mp_sub (a, b, c);
43 }
44 }
45 return res;
46 }
47
48 #endif
49
50 /* $Source$ */
51 /* $Revision$ */
52 /* $Date$ */
+0
-112
libtom-src/bn_mp_add_d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_ADD_D_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 /* single digit addition */
18 int
19 mp_add_d (mp_int * a, mp_digit b, mp_int * c)
20 {
21 int res, ix, oldused;
22 mp_digit *tmpa, *tmpc, mu;
23
24 /* grow c as required */
25 if (c->alloc < a->used + 1) {
26 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27 return res;
28 }
29 }
30
31 /* if a is negative and |a| >= b, call c = |a| - b */
32 if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
33 /* temporarily fix sign of a */
34 a->sign = MP_ZPOS;
35
36 /* c = |a| - b */
37 res = mp_sub_d(a, b, c);
38
39 /* fix sign */
40 a->sign = c->sign = MP_NEG;
41
42 /* clamp */
43 mp_clamp(c);
44
45 return res;
46 }
47
48 /* old number of used digits in c */
49 oldused = c->used;
50
51 /* sign always positive */
52 c->sign = MP_ZPOS;
53
54 /* source alias */
55 tmpa = a->dp;
56
57 /* destination alias */
58 tmpc = c->dp;
59
60 /* if a is positive */
61 if (a->sign == MP_ZPOS) {
62 /* add digit, after this we're propagating
63 * the carry.
64 */
65 *tmpc = *tmpa++ + b;
66 mu = *tmpc >> DIGIT_BIT;
67 *tmpc++ &= MP_MASK;
68
69 /* now handle rest of the digits */
70 for (ix = 1; ix < a->used; ix++) {
71 *tmpc = *tmpa++ + mu;
72 mu = *tmpc >> DIGIT_BIT;
73 *tmpc++ &= MP_MASK;
74 }
75 /* set final carry */
76 ix++;
77 *tmpc++ = mu;
78
79 /* setup size */
80 c->used = a->used + 1;
81 } else {
82 /* a was negative and |a| < b */
83 c->used = 1;
84
85 /* the result is a single digit */
86 if (a->used == 1) {
87 *tmpc++ = b - a->dp[0];
88 } else {
89 *tmpc++ = b;
90 }
91
92 /* setup count so the clearing of oldused
93 * can fall through correctly
94 */
95 ix = 1;
96 }
97
98 /* now zero to oldused */
99 while (ix++ < oldused) {
100 *tmpc++ = 0;
101 }
102 mp_clamp(c);
103
104 return MP_OKAY;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
+0
-41
libtom-src/bn_mp_addmod.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_ADDMOD_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 /* d = a + b (mod c) */
18 int
19 mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
20 {
21 int res;
22 mp_int t;
23
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
27
28 if ((res = mp_add (a, b, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
32 res = mp_mod (&t, c, d);
33 mp_clear (&t);
34 return res;
35 }
36 #endif
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
+0
-57
libtom-src/bn_mp_and.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_AND_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 /* AND two ints together */
18 int
19 mp_and (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int res, ix, px;
22 mp_int t, *x;
23
24 if (a->used > b->used) {
25 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
37
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] &= x->dp[ix];
40 }
41
42 /* zero digits above the last from the smallest mp_int */
43 for (; ix < t.used; ix++) {
44 t.dp[ix] = 0;
45 }
46
47 mp_clamp (&t);
48 mp_exch (c, &t);
49 mp_clear (&t);
50 return MP_OKAY;
51 }
52 #endif
53
54 /* $Source$ */
55 /* $Revision$ */
56 /* $Date$ */
+0
-44
libtom-src/bn_mp_clamp.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_CLAMP_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 /* trim unused digits
18 *
19 * This is used to ensure that leading zero digits are
20 * trimed and the leading "used" digit will be non-zero
21 * Typically very fast. Also fixes the sign if there
22 * are no more leading digits
23 */
24 void
25 mp_clamp (mp_int * a)
26 {
27 /* decrease used while the most significant digit is
28 * zero.
29 */
30 while (a->used > 0 && a->dp[a->used - 1] == 0) {
31 --(a->used);
32 }
33
34 /* reset the sign flag if used == 0 */
35 if (a->used == 0) {
36 a->sign = MP_ZPOS;
37 }
38 }
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-44
libtom-src/bn_mp_clear.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_CLEAR_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 /* clear one (frees) */
18 void
19 mp_clear (mp_int * a)
20 {
21 int i;
22
23 /* only do anything if a hasn't been freed previously */
24 if (a->dp != NULL) {
25 /* first zero the digits */
26 for (i = 0; i < a->used; i++) {
27 a->dp[i] = 0;
28 }
29
30 /* free ram */
31 XFREE(a->dp);
32
33 /* reset members to make debugging easier */
34 a->dp = NULL;
35 a->alloc = a->used = 0;
36 a->sign = MP_ZPOS;
37 }
38 }
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-34
libtom-src/bn_mp_clear_multi.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_CLEAR_MULTI_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 #include <stdarg.h>
17
18 void mp_clear_multi(mp_int *mp, ...)
19 {
20 mp_int* next_mp = mp;
21 va_list args;
22 va_start(args, mp);
23 while (next_mp != NULL) {
24 mp_clear(next_mp);
25 next_mp = va_arg(args, mp_int*);
26 }
27 va_end(args);
28 }
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
+0
-43
libtom-src/bn_mp_cmp.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_CMP_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 /* compare two ints (signed)*/
18 int
19 mp_cmp (mp_int * a, mp_int * b)
20 {
21 /* compare based on sign */
22 if (a->sign != b->sign) {
23 if (a->sign == MP_NEG) {
24 return MP_LT;
25 } else {
26 return MP_GT;
27 }
28 }
29
30 /* compare digits */
31 if (a->sign == MP_NEG) {
32 /* if negative compare opposite direction */
33 return mp_cmp_mag(b, a);
34 } else {
35 return mp_cmp_mag(a, b);
36 }
37 }
38 #endif
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
+0
-44
libtom-src/bn_mp_cmp_d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_CMP_D_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 /* compare a digit */
18 int mp_cmp_d(mp_int * a, mp_digit b)
19 {
20 /* compare based on sign */
21 if (a->sign == MP_NEG) {
22 return MP_LT;
23 }
24
25 /* compare based on magnitude */
26 if (a->used > 1) {
27 return MP_GT;
28 }
29
30 /* compare the only digit of a to b */
31 if (a->dp[0] > b) {
32 return MP_GT;
33 } else if (a->dp[0] < b) {
34 return MP_LT;
35 } else {
36 return MP_EQ;
37 }
38 }
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-55
libtom-src/bn_mp_cmp_mag.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_CMP_MAG_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 /* compare maginitude of two ints (unsigned) */
18 int mp_cmp_mag (mp_int * a, mp_int * b)
19 {
20 int n;
21 mp_digit *tmpa, *tmpb;
22
23 /* compare based on # of non-zero digits */
24 if (a->used > b->used) {
25 return MP_GT;
26 }
27
28 if (a->used < b->used) {
29 return MP_LT;
30 }
31
32 /* alias for a */
33 tmpa = a->dp + (a->used - 1);
34
35 /* alias for b */
36 tmpb = b->dp + (a->used - 1);
37
38 /* compare based on digits */
39 for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
40 if (*tmpa > *tmpb) {
41 return MP_GT;
42 }
43
44 if (*tmpa < *tmpb) {
45 return MP_LT;
46 }
47 }
48 return MP_EQ;
49 }
50 #endif
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
+0
-53
libtom-src/bn_mp_cnt_lsb.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_CNT_LSB_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 static const int lnz[16] = {
18 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
19 };
20
21 /* Counts the number of lsbs which are zero before the first zero bit */
22 int mp_cnt_lsb(mp_int *a)
23 {
24 int x;
25 mp_digit q, qq;
26
27 /* easy out */
28 if (mp_iszero(a) == 1) {
29 return 0;
30 }
31
32 /* scan lower digits until non-zero */
33 for (x = 0; x < a->used && a->dp[x] == 0; x++);
34 q = a->dp[x];
35 x *= DIGIT_BIT;
36
37 /* now scan this digit until a 1 is found */
38 if ((q & 1) == 0) {
39 do {
40 qq = q & 15;
41 x += lnz[qq];
42 q >>= 4;
43 } while (qq == 0);
44 }
45 return x;
46 }
47
48 #endif
49
50 /* $Source$ */
51 /* $Revision$ */
52 /* $Date$ */
+0
-68
libtom-src/bn_mp_copy.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_COPY_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 /* copy, b = a */
18 int
19 mp_copy (mp_int * a, mp_int * b)
20 {
21 int res, n;
22
23 /* if dst == src do nothing */
24 if (a == b) {
25 return MP_OKAY;
26 }
27
28 /* grow dest */
29 if (b->alloc < a->used) {
30 if ((res = mp_grow (b, a->used)) != MP_OKAY) {
31 return res;
32 }
33 }
34
35 /* zero b and copy the parameters over */
36 {
37 register mp_digit *tmpa, *tmpb;
38
39 /* pointer aliases */
40
41 /* source */
42 tmpa = a->dp;
43
44 /* destination */
45 tmpb = b->dp;
46
47 /* copy all the digits */
48 for (n = 0; n < a->used; n++) {
49 *tmpb++ = *tmpa++;
50 }
51
52 /* clear high digits */
53 for (; n < b->used; n++) {
54 *tmpb++ = 0;
55 }
56 }
57
58 /* copy used count and sign */
59 b->used = a->used;
60 b->sign = a->sign;
61 return MP_OKAY;
62 }
63 #endif
64
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
+0
-45
libtom-src/bn_mp_count_bits.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_COUNT_BITS_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 /* returns the number of bits in an int */
18 int
19 mp_count_bits (mp_int * a)
20 {
21 int r;
22 mp_digit q;
23
24 /* shortcut */
25 if (a->used == 0) {
26 return 0;
27 }
28
29 /* get number of digits and add that */
30 r = (a->used - 1) * DIGIT_BIT;
31
32 /* take the last digit and count the bits in it */
33 q = a->dp[a->used - 1];
34 while (q > ((mp_digit) 0)) {
35 ++r;
36 q >>= ((mp_digit) 1);
37 }
38 return r;
39 }
40 #endif
41
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
+0
-292
libtom-src/bn_mp_div.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_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 #ifdef BN_MP_DIV_SMALL
18
19 /* slower bit-bang division... also smaller */
20 int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
21 {
22 mp_int ta, tb, tq, q;
23 int res, n, n2;
24
25 /* is divisor zero ? */
26 if (mp_iszero (b) == 1) {
27 return MP_VAL;
28 }
29
30 /* if a < b then q=0, r = a */
31 if (mp_cmp_mag (a, b) == MP_LT) {
32 if (d != NULL) {
33 res = mp_copy (a, d);
34 } else {
35 res = MP_OKAY;
36 }
37 if (c != NULL) {
38 mp_zero (c);
39 }
40 return res;
41 }
42
43 /* init our temps */
44 if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
45 return res;
46 }
47
48
49 mp_set(&tq, 1);
50 n = mp_count_bits(a) - mp_count_bits(b);
51 if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
52 ((res = mp_abs(b, &tb)) != MP_OKAY) ||
53 ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
54 ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
55 goto LBL_ERR;
56 }
57
58 while (n-- >= 0) {
59 if (mp_cmp(&tb, &ta) != MP_GT) {
60 if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
61 ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
62 goto LBL_ERR;
63 }
64 }
65 if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
66 ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
67 goto LBL_ERR;
68 }
69 }
70
71 /* now q == quotient and ta == remainder */
72 n = a->sign;
73 n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
74 if (c != NULL) {
75 mp_exch(c, &q);
76 c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
77 }
78 if (d != NULL) {
79 mp_exch(d, &ta);
80 d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
81 }
82 LBL_ERR:
83 mp_clear_multi(&ta, &tb, &tq, &q, NULL);
84 return res;
85 }
86
87 #else
88
89 /* integer signed division.
90 * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
91 * HAC pp.598 Algorithm 14.20
92 *
93 * Note that the description in HAC is horribly
94 * incomplete. For example, it doesn't consider
95 * the case where digits are removed from 'x' in
96 * the inner loop. It also doesn't consider the
97 * case that y has fewer than three digits, etc..
98 *
99 * The overall algorithm is as described as
100 * 14.20 from HAC but fixed to treat these cases.
101 */
102 int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
103 {
104 mp_int q, x, y, t1, t2;
105 int res, n, t, i, norm, neg;
106
107 /* is divisor zero ? */
108 if (mp_iszero (b) == 1) {
109 return MP_VAL;
110 }
111
112 /* if a < b then q=0, r = a */
113 if (mp_cmp_mag (a, b) == MP_LT) {
114 if (d != NULL) {
115 res = mp_copy (a, d);
116 } else {
117 res = MP_OKAY;
118 }
119 if (c != NULL) {
120 mp_zero (c);
121 }
122 return res;
123 }
124
125 if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
126 return res;
127 }
128 q.used = a->used + 2;
129
130 if ((res = mp_init (&t1)) != MP_OKAY) {
131 goto LBL_Q;
132 }
133
134 if ((res = mp_init (&t2)) != MP_OKAY) {
135 goto LBL_T1;
136 }
137
138 if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
139 goto LBL_T2;
140 }
141
142 if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
143 goto LBL_X;
144 }
145
146 /* fix the sign */
147 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
148 x.sign = y.sign = MP_ZPOS;
149
150 /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
151 norm = mp_count_bits(&y) % DIGIT_BIT;
152 if (norm < (int)(DIGIT_BIT-1)) {
153 norm = (DIGIT_BIT-1) - norm;
154 if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
155 goto LBL_Y;
156 }
157 if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
158 goto LBL_Y;
159 }
160 } else {
161 norm = 0;
162 }
163
164 /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
165 n = x.used - 1;
166 t = y.used - 1;
167
168 /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
169 if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
170 goto LBL_Y;
171 }
172
173 while (mp_cmp (&x, &y) != MP_LT) {
174 ++(q.dp[n - t]);
175 if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
176 goto LBL_Y;
177 }
178 }
179
180 /* reset y by shifting it back down */
181 mp_rshd (&y, n - t);
182
183 /* step 3. for i from n down to (t + 1) */
184 for (i = n; i >= (t + 1); i--) {
185 if (i > x.used) {
186 continue;
187 }
188
189 /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
190 * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
191 if (x.dp[i] == y.dp[t]) {
192 q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
193 } else {
194 mp_word tmp;
195 tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
196 tmp |= ((mp_word) x.dp[i - 1]);
197 tmp /= ((mp_word) y.dp[t]);
198 if (tmp > (mp_word) MP_MASK)
199 tmp = MP_MASK;
200 q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
201 }
202
203 /* while (q{i-t-1} * (yt * b + y{t-1})) >
204 xi * b**2 + xi-1 * b + xi-2
205
206 do q{i-t-1} -= 1;
207 */
208 q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
209 do {
210 q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
211
212 /* find left hand */
213 mp_zero (&t1);
214 t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
215 t1.dp[1] = y.dp[t];
216 t1.used = 2;
217 if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
218 goto LBL_Y;
219 }
220
221 /* find right hand */
222 t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
223 t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
224 t2.dp[2] = x.dp[i];
225 t2.used = 3;
226 } while (mp_cmp_mag(&t1, &t2) == MP_GT);
227
228 /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
229 if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
230 goto LBL_Y;
231 }
232
233 if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
234 goto LBL_Y;
235 }
236
237 if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
238 goto LBL_Y;
239 }
240
241 /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
242 if (x.sign == MP_NEG) {
243 if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
244 goto LBL_Y;
245 }
246 if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
247 goto LBL_Y;
248 }
249 if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
250 goto LBL_Y;
251 }
252
253 q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
254 }
255 }
256
257 /* now q is the quotient and x is the remainder
258 * [which we have to normalize]
259 */
260
261 /* get sign before writing to c */
262 x.sign = x.used == 0 ? MP_ZPOS : a->sign;
263
264 if (c != NULL) {
265 mp_clamp (&q);
266 mp_exch (&q, c);
267 c->sign = neg;
268 }
269
270 if (d != NULL) {
271 mp_div_2d (&x, norm, &x, NULL);
272 mp_exch (&x, d);
273 }
274
275 res = MP_OKAY;
276
277 LBL_Y:mp_clear (&y);
278 LBL_X:mp_clear (&x);
279 LBL_T2:mp_clear (&t2);
280 LBL_T1:mp_clear (&t1);
281 LBL_Q:mp_clear (&q);
282 return res;
283 }
284
285 #endif
286
287 #endif
288
289 /* $Source$ */
290 /* $Revision$ */
291 /* $Date$ */
+0
-68
libtom-src/bn_mp_div_2.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_2_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 /* b = a/2 */
18 int mp_div_2(mp_int * a, mp_int * b)
19 {
20 int x, res, oldused;
21
22 /* copy */
23 if (b->alloc < a->used) {
24 if ((res = mp_grow (b, a->used)) != MP_OKAY) {
25 return res;
26 }
27 }
28
29 oldused = b->used;
30 b->used = a->used;
31 {
32 register mp_digit r, rr, *tmpa, *tmpb;
33
34 /* source alias */
35 tmpa = a->dp + b->used - 1;
36
37 /* dest alias */
38 tmpb = b->dp + b->used - 1;
39
40 /* carry */
41 r = 0;
42 for (x = b->used - 1; x >= 0; x--) {
43 /* get the carry for the next iteration */
44 rr = *tmpa & 1;
45
46 /* shift the current digit, add in carry and store */
47 *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
48
49 /* forward carry to next iteration */
50 r = rr;
51 }
52
53 /* zero excess digits */
54 tmpb = b->dp + b->used;
55 for (x = b->used; x < oldused; x++) {
56 *tmpb++ = 0;
57 }
58 }
59 b->sign = a->sign;
60 mp_clamp (b);
61 return MP_OKAY;
62 }
63 #endif
64
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
+0
-97
libtom-src/bn_mp_div_2d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_2D_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 /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
18 int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
19 {
20 mp_digit D, r, rr;
21 int x, res;
22 mp_int t;
23
24
25 /* if the shift count is <= 0 then we do no work */
26 if (b <= 0) {
27 res = mp_copy (a, c);
28 if (d != NULL) {
29 mp_zero (d);
30 }
31 return res;
32 }
33
34 if ((res = mp_init (&t)) != MP_OKAY) {
35 return res;
36 }
37
38 /* get the remainder */
39 if (d != NULL) {
40 if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
41 mp_clear (&t);
42 return res;
43 }
44 }
45
46 /* copy */
47 if ((res = mp_copy (a, c)) != MP_OKAY) {
48 mp_clear (&t);
49 return res;
50 }
51
52 /* shift by as many digits in the bit count */
53 if (b >= (int)DIGIT_BIT) {
54 mp_rshd (c, b / DIGIT_BIT);
55 }
56
57 /* shift any bit count < DIGIT_BIT */
58 D = (mp_digit) (b % DIGIT_BIT);
59 if (D != 0) {
60 register mp_digit *tmpc, mask, shift;
61
62 /* mask */
63 mask = (((mp_digit)1) << D) - 1;
64
65 /* shift for lsb */
66 shift = DIGIT_BIT - D;
67
68 /* alias */
69 tmpc = c->dp + (c->used - 1);
70
71 /* carry */
72 r = 0;
73 for (x = c->used - 1; x >= 0; x--) {
74 /* get the lower bits of this word in a temp */
75 rr = *tmpc & mask;
76
77 /* shift the current word and mix in the carry bits from the previous word */
78 *tmpc = (*tmpc >> D) | (r << shift);
79 --tmpc;
80
81 /* set the carry to the carry bits of the current word found above */
82 r = rr;
83 }
84 }
85 mp_clamp (c);
86 if (d != NULL) {
87 mp_exch (&t, d);
88 }
89 mp_clear (&t);
90 return MP_OKAY;
91 }
92 #endif
93
94 /* $Source$ */
95 /* $Revision$ */
96 /* $Date$ */
+0
-79
libtom-src/bn_mp_div_3.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_3_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 /* divide by three (based on routine from MPI and the GMP manual) */
18 int
19 mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
20 {
21 mp_int q;
22 mp_word w, t;
23 mp_digit b;
24 int res, ix;
25
26 /* b = 2**DIGIT_BIT / 3 */
27 b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
28
29 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
30 return res;
31 }
32
33 q.used = a->used;
34 q.sign = a->sign;
35 w = 0;
36 for (ix = a->used - 1; ix >= 0; ix--) {
37 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
38
39 if (w >= 3) {
40 /* multiply w by [1/3] */
41 t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
42
43 /* now subtract 3 * [w/3] from w, to get the remainder */
44 w -= t+t+t;
45
46 /* fixup the remainder as required since
47 * the optimization is not exact.
48 */
49 while (w >= 3) {
50 t += 1;
51 w -= 3;
52 }
53 } else {
54 t = 0;
55 }
56 q.dp[ix] = (mp_digit)t;
57 }
58
59 /* [optional] store the remainder */
60 if (d != NULL) {
61 *d = (mp_digit)w;
62 }
63
64 /* [optional] store the quotient */
65 if (c != NULL) {
66 mp_clamp(&q);
67 mp_exch(&q, c);
68 }
69 mp_clear(&q);
70
71 return res;
72 }
73
74 #endif
75
76 /* $Source$ */
77 /* $Revision$ */
78 /* $Date$ */
+0
-115
libtom-src/bn_mp_div_d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_D_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 static int s_is_power_of_two(mp_digit b, int *p)
18 {
19 int x;
20
21 /* fast return if no power of two */
22 if ((b==0) || (b & (b-1))) {
23 return 0;
24 }
25
26 for (x = 0; x < DIGIT_BIT; x++) {
27 if (b == (((mp_digit)1)<<x)) {
28 *p = x;
29 return 1;
30 }
31 }
32 return 0;
33 }
34
35 /* single digit division (based on routine from MPI) */
36 int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
37 {
38 mp_int q;
39 mp_word w;
40 mp_digit t;
41 int res, ix;
42
43 /* cannot divide by zero */
44 if (b == 0) {
45 return MP_VAL;
46 }
47
48 /* quick outs */
49 if (b == 1 || mp_iszero(a) == 1) {
50 if (d != NULL) {
51 *d = 0;
52 }
53 if (c != NULL) {
54 return mp_copy(a, c);
55 }
56 return MP_OKAY;
57 }
58
59 /* power of two ? */
60 if (s_is_power_of_two(b, &ix) == 1) {
61 if (d != NULL) {
62 *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
63 }
64 if (c != NULL) {
65 return mp_div_2d(a, ix, c, NULL);
66 }
67 return MP_OKAY;
68 }
69
70 #ifdef BN_MP_DIV_3_C
71 /* three? */
72 if (b == 3) {
73 return mp_div_3(a, c, d);
74 }
75 #endif
76
77 /* no easy answer [c'est la vie]. Just division */
78 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
79 return res;
80 }
81
82 q.used = a->used;
83 q.sign = a->sign;
84 w = 0;
85 for (ix = a->used - 1; ix >= 0; ix--) {
86 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
87
88 if (w >= b) {
89 t = (mp_digit)(w / b);
90 w -= ((mp_word)t) * ((mp_word)b);
91 } else {
92 t = 0;
93 }
94 q.dp[ix] = (mp_digit)t;
95 }
96
97 if (d != NULL) {
98 *d = (mp_digit)w;
99 }
100
101 if (c != NULL) {
102 mp_clamp(&q);
103 mp_exch(&q, c);
104 }
105 mp_clear(&q);
106
107 return res;
108 }
109
110 #endif
111
112 /* $Source$ */
113 /* $Revision$ */
114 /* $Date$ */
+0
-43
libtom-src/bn_mp_dr_is_modulus.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_DR_IS_MODULUS_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 /* determines if a number is a valid DR modulus */
18 int mp_dr_is_modulus(mp_int *a)
19 {
20 int ix;
21
22 /* must be at least two digits */
23 if (a->used < 2) {
24 return 0;
25 }
26
27 /* must be of the form b**k - a [a <= b] so all
28 * but the first digit must be equal to -1 (mod b).
29 */
30 for (ix = 1; ix < a->used; ix++) {
31 if (a->dp[ix] != MP_MASK) {
32 return 0;
33 }
34 }
35 return 1;
36 }
37
38 #endif
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
+0
-94
libtom-src/bn_mp_dr_reduce.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_DR_REDUCE_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 /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
18 *
19 * Based on algorithm from the paper
20 *
21 * "Generating Efficient Primes for Discrete Log Cryptosystems"
22 * Chae Hoon Lim, Pil Joong Lee,
23 * POSTECH Information Research Laboratories
24 *
25 * The modulus must be of a special format [see manual]
26 *
27 * Has been modified to use algorithm 7.10 from the LTM book instead
28 *
29 * Input x must be in the range 0 <= x <= (n-1)**2
30 */
31 int
32 mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
33 {
34 int err, i, m;
35 mp_word r;
36 mp_digit mu, *tmpx1, *tmpx2;
37
38 /* m = digits in modulus */
39 m = n->used;
40
41 /* ensure that "x" has at least 2m digits */
42 if (x->alloc < m + m) {
43 if ((err = mp_grow (x, m + m)) != MP_OKAY) {
44 return err;
45 }
46 }
47
48 /* top of loop, this is where the code resumes if
49 * another reduction pass is required.
50 */
51 top:
52 /* aliases for digits */
53 /* alias for lower half of x */
54 tmpx1 = x->dp;
55
56 /* alias for upper half of x, or x/B**m */
57 tmpx2 = x->dp + m;
58
59 /* set carry to zero */
60 mu = 0;
61
62 /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
63 for (i = 0; i < m; i++) {
64 r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
65 *tmpx1++ = (mp_digit)(r & MP_MASK);
66 mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
67 }
68
69 /* set final carry */
70 *tmpx1++ = mu;
71
72 /* zero words above m */
73 for (i = m + 1; i < x->used; i++) {
74 *tmpx1++ = 0;
75 }
76
77 /* clamp, sub and return */
78 mp_clamp (x);
79
80 /* if x >= n then subtract and reduce again
81 * Each successive "recursion" makes the input smaller and smaller.
82 */
83 if (mp_cmp_mag (x, n) != MP_LT) {
84 s_mp_sub(x, n, x);
85 goto top;
86 }
87 return MP_OKAY;
88 }
89 #endif
90
91 /* $Source$ */
92 /* $Revision$ */
93 /* $Date$ */
+0
-32
libtom-src/bn_mp_dr_setup.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_DR_SETUP_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 /* determines the setup value */
18 void mp_dr_setup(mp_int *a, mp_digit *d)
19 {
20 /* the casts are required if DIGIT_BIT is one less than
21 * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
22 */
23 *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
24 ((mp_word)a->dp[0]));
25 }
26
27 #endif
28
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
+0
-34
libtom-src/bn_mp_exch.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_EXCH_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 /* swap the elements of two integers, for cases where you can't simply swap the
18 * mp_int pointers around
19 */
20 void
21 mp_exch (mp_int * a, mp_int * b)
22 {
23 mp_int t;
24
25 t = *a;
26 *a = *b;
27 *b = t;
28 }
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
+0
-57
libtom-src/bn_mp_expt_d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_EXPT_D_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 (mp_int * a, mp_digit b, mp_int * c)
19 {
20 int res;
21 mp_int g;
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 #endif
53
54 /* $Source$ */
55 /* $Revision$ */
56 /* $Date$ */
+0
-112
libtom-src/bn_mp_exptmod.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_EXPTMOD_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
18 /* this is a shell function that calls either the normal or Montgomery
19 * exptmod functions. Originally the call to the montgomery code was
20 * embedded in the normal function but that wasted alot of stack space
21 * for nothing (since 99% of the time the Montgomery code would be called)
22 */
23 int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
24 {
25 int dr;
26
27 /* modulus P must be positive */
28 if (P->sign == MP_NEG) {
29 return MP_VAL;
30 }
31
32 /* if exponent X is negative we have to recurse */
33 if (X->sign == MP_NEG) {
34 #ifdef BN_MP_INVMOD_C
35 mp_int tmpG, tmpX;
36 int err;
37
38 /* first compute 1/G mod P */
39 if ((err = mp_init(&tmpG)) != MP_OKAY) {
40 return err;
41 }
42 if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
43 mp_clear(&tmpG);
44 return err;
45 }
46
47 /* now get |X| */
48 if ((err = mp_init(&tmpX)) != MP_OKAY) {
49 mp_clear(&tmpG);
50 return err;
51 }
52 if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
53 mp_clear_multi(&tmpG, &tmpX, NULL);
54 return err;
55 }
56
57 /* and now compute (1/G)**|X| instead of G**X [X < 0] */
58 err = mp_exptmod(&tmpG, &tmpX, P, Y);
59 mp_clear_multi(&tmpG, &tmpX, NULL);
60 return err;
61 #else
62 /* no invmod */
63 return MP_VAL;
64 #endif
65 }
66
67 /* modified diminished radix reduction */
68 #if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
69 if (mp_reduce_is_2k_l(P) == MP_YES) {
70 return s_mp_exptmod(G, X, P, Y, 1);
71 }
72 #endif
73
74 #ifdef BN_MP_DR_IS_MODULUS_C
75 /* is it a DR modulus? */
76 dr = mp_dr_is_modulus(P);
77 #else
78 /* default to no */
79 dr = 0;
80 #endif
81
82 #ifdef BN_MP_REDUCE_IS_2K_C
83 /* if not, is it a unrestricted DR modulus? */
84 if (dr == 0) {
85 dr = mp_reduce_is_2k(P) << 1;
86 }
87 #endif
88
89 /* if the modulus is odd or dr != 0 use the montgomery method */
90 #ifdef BN_MP_EXPTMOD_FAST_C
91 if (mp_isodd (P) == 1 || dr != 0) {
92 return mp_exptmod_fast (G, X, P, Y, dr);
93 } else {
94 #endif
95 #ifdef BN_S_MP_EXPTMOD_C
96 /* otherwise use the generic Barrett reduction technique */
97 return s_mp_exptmod (G, X, P, Y, 0);
98 #else
99 /* no exptmod for evens */
100 return MP_VAL;
101 #endif
102 #ifdef BN_MP_EXPTMOD_FAST_C
103 }
104 #endif
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
+0
-321
libtom-src/bn_mp_exptmod_fast.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_EXPTMOD_FAST_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 /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
18 *
19 * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
20 * The value of k changes based on the size of the exponent.
21 *
22 * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
23 */
24
25 #ifdef MP_LOW_MEM
26 #define TAB_SIZE 32
27 #else
28 #define TAB_SIZE 256
29 #endif
30
31 int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
32 {
33 mp_int M[TAB_SIZE], res;
34 mp_digit buf, mp;
35 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
36
37 /* use a pointer to the reduction algorithm. This allows us to use
38 * one of many reduction algorithms without modding the guts of
39 * the code with if statements everywhere.
40 */
41 int (*redux)(mp_int*,mp_int*,mp_digit);
42
43 /* find window size */
44 x = mp_count_bits (X);
45 if (x <= 7) {
46 winsize = 2;
47 } else if (x <= 36) {
48 winsize = 3;
49 } else if (x <= 140) {
50 winsize = 4;
51 } else if (x <= 450) {
52 winsize = 5;
53 } else if (x <= 1303) {
54 winsize = 6;
55 } else if (x <= 3529) {
56 winsize = 7;
57 } else {
58 winsize = 8;
59 }
60
61 #ifdef MP_LOW_MEM
62 if (winsize > 5) {
63 winsize = 5;
64 }
65 #endif
66
67 /* init M array */
68 /* init first cell */
69 if ((err = mp_init(&M[1])) != MP_OKAY) {
70 return err;
71 }
72
73 /* now init the second half of the array */
74 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
75 if ((err = mp_init(&M[x])) != MP_OKAY) {
76 for (y = 1<<(winsize-1); y < x; y++) {
77 mp_clear (&M[y]);
78 }
79 mp_clear(&M[1]);
80 return err;
81 }
82 }
83
84 /* determine and setup reduction code */
85 if (redmode == 0) {
86 #ifdef BN_MP_MONTGOMERY_SETUP_C
87 /* now setup montgomery */
88 if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
89 goto LBL_M;
90 }
91 #else
92 err = MP_VAL;
93 goto LBL_M;
94 #endif
95
96 /* automatically pick the comba one if available (saves quite a few calls/ifs) */
97 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
98 if (((P->used * 2 + 1) < MP_WARRAY) &&
99 P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
100 redux = fast_mp_montgomery_reduce;
101 } else
102 #endif
103 {
104 #ifdef BN_MP_MONTGOMERY_REDUCE_C
105 /* use slower baseline Montgomery method */
106 redux = mp_montgomery_reduce;
107 #else
108 err = MP_VAL;
109 goto LBL_M;
110 #endif
111 }
112 } else if (redmode == 1) {
113 #if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
114 /* setup DR reduction for moduli of the form B**k - b */
115 mp_dr_setup(P, &mp);
116 redux = mp_dr_reduce;
117 #else
118 err = MP_VAL;
119 goto LBL_M;
120 #endif
121 } else {
122 #if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
123 /* setup DR reduction for moduli of the form 2**k - b */
124 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
125 goto LBL_M;
126 }
127 redux = mp_reduce_2k;
128 #else
129 err = MP_VAL;
130 goto LBL_M;
131 #endif
132 }
133
134 /* setup result */
135 if ((err = mp_init (&res)) != MP_OKAY) {
136 goto LBL_M;
137 }
138
139 /* create M table
140 *
141
142 *
143 * The first half of the table is not computed though accept for M[0] and M[1]
144 */
145
146 if (redmode == 0) {
147 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
148 /* now we need R mod m */
149 if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
150 goto LBL_RES;
151 }
152 #else
153 err = MP_VAL;
154 goto LBL_RES;
155 #endif
156
157 /* now set M[1] to G * R mod m */
158 if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
159 goto LBL_RES;
160 }
161 } else {
162 mp_set(&res, 1);
163 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
164 goto LBL_RES;
165 }
166 }
167
168 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
169 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
170 goto LBL_RES;
171 }
172
173 for (x = 0; x < (winsize - 1); x++) {
174 if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
175 goto LBL_RES;
176 }
177 if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
178 goto LBL_RES;
179 }
180 }
181
182 /* create upper table */
183 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
184 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
185 goto LBL_RES;
186 }
187 if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
188 goto LBL_RES;
189 }
190 }
191
192 /* set initial mode and bit cnt */
193 mode = 0;
194 bitcnt = 1;
195 buf = 0;
196 digidx = X->used - 1;
197 bitcpy = 0;
198 bitbuf = 0;
199
200 for (;;) {
201 /* grab next digit as required */
202 if (--bitcnt == 0) {
203 /* if digidx == -1 we are out of digits so break */
204 if (digidx == -1) {
205 break;
206 }
207 /* read next digit and reset bitcnt */
208 buf = X->dp[digidx--];
209 bitcnt = (int)DIGIT_BIT;
210 }
211
212 /* grab the next msb from the exponent */
213 y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
214 buf <<= (mp_digit)1;
215
216 /* if the bit is zero and mode == 0 then we ignore it
217 * These represent the leading zero bits before the first 1 bit
218 * in the exponent. Technically this opt is not required but it
219 * does lower the # of trivial squaring/reductions used
220 */
221 if (mode == 0 && y == 0) {
222 continue;
223 }
224
225 /* if the bit is zero and mode == 1 then we square */
226 if (mode == 1 && y == 0) {
227 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
228 goto LBL_RES;
229 }
230 if ((err = redux (&res, P, mp)) != MP_OKAY) {
231 goto LBL_RES;
232 }
233 continue;
234 }
235
236 /* else we add it to the window */
237 bitbuf |= (y << (winsize - ++bitcpy));
238 mode = 2;
239
240 if (bitcpy == winsize) {
241 /* ok window is filled so square as required and multiply */
242 /* square first */
243 for (x = 0; x < winsize; x++) {
244 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
245 goto LBL_RES;
246 }
247 if ((err = redux (&res, P, mp)) != MP_OKAY) {
248 goto LBL_RES;
249 }
250 }
251
252 /* then multiply */
253 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
254 goto LBL_RES;
255 }
256 if ((err = redux (&res, P, mp)) != MP_OKAY) {
257 goto LBL_RES;
258 }
259
260 /* empty window and reset */
261 bitcpy = 0;
262 bitbuf = 0;
263 mode = 1;
264 }
265 }
266
267 /* if bits remain then square/multiply */
268 if (mode == 2 && bitcpy > 0) {
269 /* square then multiply if the bit is set */
270 for (x = 0; x < bitcpy; x++) {
271 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
272 goto LBL_RES;
273 }
274 if ((err = redux (&res, P, mp)) != MP_OKAY) {
275 goto LBL_RES;
276 }
277
278 /* get next bit of the window */
279 bitbuf <<= 1;
280 if ((bitbuf & (1 << winsize)) != 0) {
281 /* then multiply */
282 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
283 goto LBL_RES;
284 }
285 if ((err = redux (&res, P, mp)) != MP_OKAY) {
286 goto LBL_RES;
287 }
288 }
289 }
290 }
291
292 if (redmode == 0) {
293 /* fixup result if Montgomery reduction is used
294 * recall that any value in a Montgomery system is
295 * actually multiplied by R mod n. So we have
296 * to reduce one more time to cancel out the factor
297 * of R.
298 */
299 if ((err = redux(&res, P, mp)) != MP_OKAY) {
300 goto LBL_RES;
301 }
302 }
303
304 /* swap res with Y */
305 mp_exch (&res, Y);
306 err = MP_OKAY;
307 LBL_RES:mp_clear (&res);
308 LBL_M:
309 mp_clear(&M[1]);
310 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
311 mp_clear (&M[x]);
312 }
313 return err;
314 }
315 #endif
316
317
318 /* $Source$ */
319 /* $Revision$ */
320 /* $Date$ */
+0
-82
libtom-src/bn_mp_exteuclid.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_EXTEUCLID_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 /* Extended euclidean algorithm of (a, b) produces
18 a*u1 + b*u2 = u3
19 */
20 int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
21 {
22 mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
23 int err;
24
25 if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
26 return err;
27 }
28
29 /* initialize, (u1,u2,u3) = (1,0,a) */
30 mp_set(&u1, 1);
31 if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
32
33 /* initialize, (v1,v2,v3) = (0,1,b) */
34 mp_set(&v2, 1);
35 if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
36
37 /* loop while v3 != 0 */
38 while (mp_iszero(&v3) == MP_NO) {
39 /* q = u3/v3 */
40 if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
41
42 /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
43 if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
44 if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
45 if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
46 if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
47 if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
48 if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
49
50 /* (u1,u2,u3) = (v1,v2,v3) */
51 if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
52 if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
53 if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
54
55 /* (v1,v2,v3) = (t1,t2,t3) */
56 if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
57 if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
58 if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
59 }
60
61 /* make sure U3 >= 0 */
62 if (u3.sign == MP_NEG) {
63 mp_neg(&u1, &u1);
64 mp_neg(&u2, &u2);
65 mp_neg(&u3, &u3);
66 }
67
68 /* copy result out */
69 if (U1 != NULL) { mp_exch(U1, &u1); }
70 if (U2 != NULL) { mp_exch(U2, &u2); }
71 if (U3 != NULL) { mp_exch(U3, &u3); }
72
73 err = MP_OKAY;
74 _ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
75 return err;
76 }
77 #endif
78
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
+0
-67
libtom-src/bn_mp_fread.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_FREAD_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 /* read a bigint from a file stream in ASCII */
18 int mp_fread(mp_int *a, int radix, FILE *stream)
19 {
20 int err, ch, neg, y;
21
22 /* clear a */
23 mp_zero(a);
24
25 /* if first digit is - then set negative */
26 ch = fgetc(stream);
27 if (ch == '-') {
28 neg = MP_NEG;
29 ch = fgetc(stream);
30 } else {
31 neg = MP_ZPOS;
32 }
33
34 for (;;) {
35 /* find y in the radix map */
36 for (y = 0; y < radix; y++) {
37 if (mp_s_rmap[y] == ch) {
38 break;
39 }
40 }
41 if (y == radix) {
42 break;
43 }
44
45 /* shift up and add */
46 if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
47 return err;
48 }
49 if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
50 return err;
51 }
52
53 ch = fgetc(stream);
54 }
55 if (mp_cmp_d(a, 0) != MP_EQ) {
56 a->sign = neg;
57 }
58
59 return MP_OKAY;
60 }
61
62 #endif
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
+0
-52
libtom-src/bn_mp_fwrite.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_FWRITE_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 int mp_fwrite(mp_int *a, int radix, FILE *stream)
18 {
19 char *buf;
20 int err, len, x;
21
22 if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
23 return err;
24 }
25
26 buf = OPT_CAST(char) XMALLOC (len);
27 if (buf == NULL) {
28 return MP_MEM;
29 }
30
31 if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
32 XFREE (buf);
33 return err;
34 }
35
36 for (x = 0; x < len; x++) {
37 if (fputc(buf[x], stream) == EOF) {
38 XFREE (buf);
39 return MP_VAL;
40 }
41 }
42
43 XFREE (buf);
44 return MP_OKAY;
45 }
46
47 #endif
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
+0
-105
libtom-src/bn_mp_gcd.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_GCD_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 /* Greatest Common Divisor using the binary method */
18 int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
19 {
20 mp_int u, v;
21 int k, u_lsb, v_lsb, res;
22
23 /* either zero than gcd is the largest */
24 if (mp_iszero (a) == MP_YES) {
25 return mp_abs (b, c);
26 }
27 if (mp_iszero (b) == MP_YES) {
28 return mp_abs (a, c);
29 }
30
31 /* get copies of a and b we can modify */
32 if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
33 return res;
34 }
35
36 if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
37 goto LBL_U;
38 }
39
40 /* must be positive for the remainder of the algorithm */
41 u.sign = v.sign = MP_ZPOS;
42
43 /* B1. Find the common power of two for u and v */
44 u_lsb = mp_cnt_lsb(&u);
45 v_lsb = mp_cnt_lsb(&v);
46 k = MIN(u_lsb, v_lsb);
47
48 if (k > 0) {
49 /* divide the power of two out */
50 if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
51 goto LBL_V;
52 }
53
54 if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
55 goto LBL_V;
56 }
57 }
58
59 /* divide any remaining factors of two out */
60 if (u_lsb != k) {
61 if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
62 goto LBL_V;
63 }
64 }
65
66 if (v_lsb != k) {
67 if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
68 goto LBL_V;
69 }
70 }
71
72 while (mp_iszero(&v) == 0) {
73 /* make sure v is the largest */
74 if (mp_cmp_mag(&u, &v) == MP_GT) {
75 /* swap u and v to make sure v is >= u */
76 mp_exch(&u, &v);
77 }
78
79 /* subtract smallest from largest */
80 if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
81 goto LBL_V;
82 }
83
84 /* Divide out all factors of two */
85 if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
86 goto LBL_V;
87 }
88 }
89
90 /* multiply by 2**k which we divided out at the beginning */
91 if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
92 goto LBL_V;
93 }
94 c->sign = MP_ZPOS;
95 res = MP_OKAY;
96 LBL_V:mp_clear (&u);
97 LBL_U:mp_clear (&v);
98 return res;
99 }
100 #endif
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
+0
-45
libtom-src/bn_mp_get_int.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_GET_INT_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 32-bits of an mp_int */
18 unsigned long mp_get_int(mp_int * a)
19 {
20 int i;
21 ulong64 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 while (--i >= 0) {
34 res = (res << DIGIT_BIT) | DIGIT(a,i);
35 }
36
37 /* force result to 32-bits always so it is consistent on non 32-bit platforms */
38 return (unsigned long)(res & 0xFFFFFFFFUL);
39 }
40 #endif
41
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
+0
-57
libtom-src/bn_mp_grow.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_GROW_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 /* grow as required */
18 int mp_grow (mp_int * a, int size)
19 {
20 int i;
21 mp_digit *tmp;
22
23 /* if the alloc size is smaller alloc more ram */
24 if (a->alloc < size) {
25 /* ensure there are always at least MP_PREC digits extra on top */
26 size += (MP_PREC * 2) - (size % MP_PREC);
27
28 /* reallocate the array a->dp
29 *
30 * We store the return in a temporary variable
31 * in case the operation failed we don't want
32 * to overwrite the dp member of a.
33 */
34 tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
35 if (tmp == NULL) {
36 /* reallocation failed but "a" is still valid [can be freed] */
37 return MP_MEM;
38 }
39
40 /* reallocation succeeded so set a->dp */
41 a->dp = tmp;
42
43 /* zero excess digits */
44 i = a->alloc;
45 a->alloc = size;
46 for (; i < a->alloc; i++) {
47 a->dp[i] = 0;
48 }
49 }
50 return MP_OKAY;
51 }
52 #endif
53
54 /* $Source$ */
55 /* $Revision$ */
56 /* $Date$ */
+0
-46
libtom-src/bn_mp_init.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_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 /* init a new mp_int */
18 int mp_init (mp_int * a)
19 {
20 int i;
21
22 /* allocate memory required and clear it */
23 a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
24 if (a->dp == NULL) {
25 return MP_MEM;
26 }
27
28 /* set the digits to zero */
29 for (i = 0; i < MP_PREC; i++) {
30 a->dp[i] = 0;
31 }
32
33 /* set the used to zero, allocated digits to the default precision
34 * and sign to positive */
35 a->used = 0;
36 a->alloc = MP_PREC;
37 a->sign = MP_ZPOS;
38
39 return MP_OKAY;
40 }
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
+0
-32
libtom-src/bn_mp_init_copy.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_COPY_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 /* creates "a" then copies b into it */
18 int mp_init_copy (mp_int * a, mp_int * b)
19 {
20 int res;
21
22 if ((res = mp_init (a)) != MP_OKAY) {
23 return res;
24 }
25 return mp_copy (b, a);
26 }
27 #endif
28
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
+0
-59
libtom-src/bn_mp_init_multi.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_MULTI_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 #include <stdarg.h>
17
18 int mp_init_multi(mp_int *mp, ...)
19 {
20 mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
21 int n = 0; /* Number of ok inits */
22 mp_int* cur_arg = mp;
23 va_list args;
24
25 va_start(args, mp); /* init args to next argument from caller */
26 while (cur_arg != NULL) {
27 if (mp_init(cur_arg) != MP_OKAY) {
28 /* Oops - error! Back-track and mp_clear what we already
29 succeeded in init-ing, then return error.
30 */
31 va_list clean_args;
32
33 /* end the current list */
34 va_end(args);
35
36 /* now start cleaning up */
37 cur_arg = mp;
38 va_start(clean_args, mp);
39 while (n--) {
40 mp_clear(cur_arg);
41 cur_arg = va_arg(clean_args, mp_int*);
42 }
43 va_end(clean_args);
44 res = MP_MEM;
45 break;
46 }
47 n++;
48 cur_arg = va_arg(args, mp_int*);
49 }
50 va_end(args);
51 return res; /* Assumed ok, if error flagged above. */
52 }
53
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
+0
-32
libtom-src/bn_mp_init_set.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_SET_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 /* initialize and set a digit */
18 int mp_init_set (mp_int * a, mp_digit b)
19 {
20 int err;
21 if ((err = mp_init(a)) != MP_OKAY) {
22 return err;
23 }
24 mp_set(a, b);
25 return err;
26 }
27 #endif
28
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
+0
-31
libtom-src/bn_mp_init_set_int.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_SET_INT_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 /* initialize and set a digit */
18 int mp_init_set_int (mp_int * a, unsigned long b)
19 {
20 int err;
21 if ((err = mp_init(a)) != MP_OKAY) {
22 return err;
23 }
24 return mp_set_int(a, b);
25 }
26 #endif
27
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
+0
-48
libtom-src/bn_mp_init_size.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_SIZE_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 /* init an mp_init for a given size */
18 int mp_init_size (mp_int * a, int size)
19 {
20 int x;
21
22 /* pad size so there are always extra digits */
23 size += (MP_PREC * 2) - (size % MP_PREC);
24
25 /* alloc mem */
26 a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
27 if (a->dp == NULL) {
28 return MP_MEM;
29 }
30
31 /* set the members */
32 a->used = 0;
33 a->alloc = size;
34 a->sign = MP_ZPOS;
35
36 /* zero the digits */
37 for (x = 0; x < size; x++) {
38 a->dp[x] = 0;
39 }
40
41 return MP_OKAY;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
+0
-43
libtom-src/bn_mp_invmod.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_INVMOD_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 /* hac 14.61, pp608 */
18 int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
19 {
20 /* b cannot be negative */
21 if (b->sign == MP_NEG || mp_iszero(b) == 1) {
22 return MP_VAL;
23 }
24
25 #ifdef BN_FAST_MP_INVMOD_C
26 /* if the modulus is odd we can use a faster routine instead */
27 if (mp_isodd (b) == 1) {
28 return fast_mp_invmod (a, b, c);
29 }
30 #endif
31
32 #ifdef BN_MP_INVMOD_SLOW_C
33 return mp_invmod_slow(a, b, c);
34 #endif
35
36 return MP_VAL;
37 }
38 #endif
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
+0
-175
libtom-src/bn_mp_invmod_slow.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_INVMOD_SLOW_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 /* hac 14.61, pp608 */
18 int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
19 {
20 mp_int x, y, u, v, A, B, C, D;
21 int res;
22
23 /* b cannot be negative */
24 if (b->sign == MP_NEG || mp_iszero(b) == 1) {
25 return MP_VAL;
26 }
27
28 /* init temps */
29 if ((res = mp_init_multi(&x, &y, &u, &v,
30 &A, &B, &C, &D, NULL)) != MP_OKAY) {
31 return res;
32 }
33
34 /* x = a, y = b */
35 if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
36 goto LBL_ERR;
37 }
38 if ((res = mp_copy (b, &y)) != MP_OKAY) {
39 goto LBL_ERR;
40 }
41
42 /* 2. [modified] if x,y are both even then return an error! */
43 if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
44 res = MP_VAL;
45 goto LBL_ERR;
46 }
47
48 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
49 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
50 goto LBL_ERR;
51 }
52 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 mp_set (&A, 1);
56 mp_set (&D, 1);
57
58 top:
59 /* 4. while u is even do */
60 while (mp_iseven (&u) == 1) {
61 /* 4.1 u = u/2 */
62 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
63 goto LBL_ERR;
64 }
65 /* 4.2 if A or B is odd then */
66 if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
67 /* A = (A+y)/2, B = (B-x)/2 */
68 if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
69 goto LBL_ERR;
70 }
71 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
72 goto LBL_ERR;
73 }
74 }
75 /* A = A/2, B = B/2 */
76 if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
77 goto LBL_ERR;
78 }
79 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
80 goto LBL_ERR;
81 }
82 }
83
84 /* 5. while v is even do */
85 while (mp_iseven (&v) == 1) {
86 /* 5.1 v = v/2 */
87 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
88 goto LBL_ERR;
89 }
90 /* 5.2 if C or D is odd then */
91 if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
92 /* C = (C+y)/2, D = (D-x)/2 */
93 if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
94 goto LBL_ERR;
95 }
96 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
97 goto LBL_ERR;
98 }
99 }
100 /* C = C/2, D = D/2 */
101 if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
102 goto LBL_ERR;
103 }
104 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
105 goto LBL_ERR;
106 }
107 }
108
109 /* 6. if u >= v then */
110 if (mp_cmp (&u, &v) != MP_LT) {
111 /* u = u - v, A = A - C, B = B - D */
112 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
113 goto LBL_ERR;
114 }
115
116 if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
117 goto LBL_ERR;
118 }
119
120 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
121 goto LBL_ERR;
122 }
123 } else {
124 /* v - v - u, C = C - A, D = D - B */
125 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
126 goto LBL_ERR;
127 }
128
129 if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
130 goto LBL_ERR;
131 }
132
133 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
134 goto LBL_ERR;
135 }
136 }
137
138 /* if not zero goto step 4 */
139 if (mp_iszero (&u) == 0)
140 goto top;
141
142 /* now a = C, b = D, gcd == g*v */
143
144 /* if v != 1 then there is no inverse */
145 if (mp_cmp_d (&v, 1) != MP_EQ) {
146 res = MP_VAL;
147 goto LBL_ERR;
148 }
149
150 /* if its too low */
151 while (mp_cmp_d(&C, 0) == MP_LT) {
152 if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
153 goto LBL_ERR;
154 }
155 }
156
157 /* too big */
158 while (mp_cmp_mag(&C, b) != MP_LT) {
159 if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
160 goto LBL_ERR;
161 }
162 }
163
164 /* C is now the inverse */
165 mp_exch (&C, c);
166 res = MP_OKAY;
167 LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
168 return res;
169 }
170 #endif
171
172 /* $Source$ */
173 /* $Revision$ */
174 /* $Date$ */
+0
-109
libtom-src/bn_mp_is_square.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_IS_SQUARE_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 /* Check if remainders are possible squares - fast exclude non-squares */
18 static const char rem_128[128] = {
19 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
20 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
21 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
22 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
23 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
24 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
25 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
26 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
27 };
28
29 static const char rem_105[105] = {
30 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
31 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
32 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
33 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
34 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
35 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
36 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
37 };
38
39 /* Store non-zero to ret if arg is square, and zero if not */
40 int mp_is_square(mp_int *arg,int *ret)
41 {
42 int res;
43 mp_digit c;
44 mp_int t;
45 unsigned long r;
46
47 /* Default to Non-square :) */
48 *ret = MP_NO;
49
50 if (arg->sign == MP_NEG) {
51 return MP_VAL;
52 }
53
54 /* digits used? (TSD) */
55 if (arg->used == 0) {
56 return MP_OKAY;
57 }
58
59 /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
60 if (rem_128[127 & DIGIT(arg,0)] == 1) {
61 return MP_OKAY;
62 }
63
64 /* Next check mod 105 (3*5*7) */
65 if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
66 return res;
67 }
68 if (rem_105[c] == 1) {
69 return MP_OKAY;
70 }
71
72
73 if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
74 return res;
75 }
76 if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
77 goto ERR;
78 }
79 r = mp_get_int(&t);
80 /* Check for other prime modules, note it's not an ERROR but we must
81 * free "t" so the easiest way is to goto ERR. We know that res
82 * is already equal to MP_OKAY from the mp_mod call
83 */
84 if ( (1L<<(r%11)) & 0x5C4L ) goto ERR;
85 if ( (1L<<(r%13)) & 0x9E4L ) goto ERR;
86 if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR;
87 if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR;
88 if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR;
89 if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR;
90 if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR;
91
92 /* Final check - is sqr(sqrt(arg)) == arg ? */
93 if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
94 goto ERR;
95 }
96 if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
97 goto ERR;
98 }
99
100 *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
101 ERR:mp_clear(&t);
102 return res;
103 }
104 #endif
105
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
+0
-105
libtom-src/bn_mp_jacobi.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_JACOBI_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 /* computes the jacobi c = (a | n) (or Legendre if n is prime)
18 * HAC pp. 73 Algorithm 2.149
19 */
20 int mp_jacobi (mp_int * a, mp_int * p, int *c)
21 {
22 mp_int a1, p1;
23 int k, s, r, res;
24 mp_digit residue;
25
26 /* if p <= 0 return MP_VAL */
27 if (mp_cmp_d(p, 0) != MP_GT) {
28 return MP_VAL;
29 }
30
31 /* step 1. if a == 0, return 0 */
32 if (mp_iszero (a) == 1) {
33 *c = 0;
34 return MP_OKAY;
35 }
36
37 /* step 2. if a == 1, return 1 */
38 if (mp_cmp_d (a, 1) == MP_EQ) {
39 *c = 1;
40 return MP_OKAY;
41 }
42
43 /* default */
44 s = 0;
45
46 /* step 3. write a = a1 * 2**k */
47 if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
48 return res;
49 }
50
51 if ((res = mp_init (&p1)) != MP_OKAY) {
52 goto LBL_A1;
53 }
54
55 /* divide out larger power of two */
56 k = mp_cnt_lsb(&a1);
57 if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
58 goto LBL_P1;
59 }
60
61 /* step 4. if e is even set s=1 */
62 if ((k & 1) == 0) {
63 s = 1;
64 } else {
65 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
66 residue = p->dp[0] & 7;
67
68 if (residue == 1 || residue == 7) {
69 s = 1;
70 } else if (residue == 3 || residue == 5) {
71 s = -1;
72 }
73 }
74
75 /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
76 if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
77 s = -s;
78 }
79
80 /* if a1 == 1 we're done */
81 if (mp_cmp_d (&a1, 1) == MP_EQ) {
82 *c = s;
83 } else {
84 /* n1 = n mod a1 */
85 if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) {
86 goto LBL_P1;
87 }
88 if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
89 goto LBL_P1;
90 }
91 *c = s * r;
92 }
93
94 /* done */
95 res = MP_OKAY;
96 LBL_P1:mp_clear (&p1);
97 LBL_A1:mp_clear (&a1);
98 return res;
99 }
100 #endif
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
+0
-167
libtom-src/bn_mp_karatsuba_mul.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_KARATSUBA_MUL_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 /* c = |a| * |b| using Karatsuba Multiplication using
18 * three half size multiplications
19 *
20 * Let B represent the radix [e.g. 2**DIGIT_BIT] and
21 * let n represent half of the number of digits in
22 * the min(a,b)
23 *
24 * a = a1 * B**n + a0
25 * b = b1 * B**n + b0
26 *
27 * Then, a * b =>
28 a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
29 *
30 * Note that a1b1 and a0b0 are used twice and only need to be
31 * computed once. So in total three half size (half # of
32 * digit) multiplications are performed, a0b0, a1b1 and
33 * (a1+b1)(a0+b0)
34 *
35 * Note that a multiplication of half the digits requires
36 * 1/4th the number of single precision multiplications so in
37 * total after one call 25% of the single precision multiplications
38 * are saved. Note also that the call to mp_mul can end up back
39 * in this function if the a0, a1, b0, or b1 are above the threshold.
40 * This is known as divide-and-conquer and leads to the famous
41 * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
42 * the standard O(N**2) that the baseline/comba methods use.
43 * Generally though the overhead of this method doesn't pay off
44 * until a certain size (N ~ 80) is reached.
45 */
46 int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
47 {
48 mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
49 int B, err;
50
51 /* default the return code to an error */
52 err = MP_MEM;
53
54 /* min # of digits */
55 B = MIN (a->used, b->used);
56
57 /* now divide in two */
58 B = B >> 1;
59
60 /* init copy all the temps */
61 if (mp_init_size (&x0, B) != MP_OKAY)
62 goto ERR;
63 if (mp_init_size (&x1, a->used - B) != MP_OKAY)
64 goto X0;
65 if (mp_init_size (&y0, B) != MP_OKAY)
66 goto X1;
67 if (mp_init_size (&y1, b->used - B) != MP_OKAY)
68 goto Y0;
69
70 /* init temps */
71 if (mp_init_size (&t1, B * 2) != MP_OKAY)
72 goto Y1;
73 if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
74 goto T1;
75 if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
76 goto X0Y0;
77
78 /* now shift the digits */
79 x0.used = y0.used = B;
80 x1.used = a->used - B;
81 y1.used = b->used - B;
82
83 {
84 register int x;
85 register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
86
87 /* we copy the digits directly instead of using higher level functions
88 * since we also need to shift the digits
89 */
90 tmpa = a->dp;
91 tmpb = b->dp;
92
93 tmpx = x0.dp;
94 tmpy = y0.dp;
95 for (x = 0; x < B; x++) {
96 *tmpx++ = *tmpa++;
97 *tmpy++ = *tmpb++;
98 }
99
100 tmpx = x1.dp;
101 for (x = B; x < a->used; x++) {
102 *tmpx++ = *tmpa++;
103 }
104
105 tmpy = y1.dp;
106 for (x = B; x < b->used; x++) {
107 *tmpy++ = *tmpb++;
108 }
109 }
110
111 /* only need to clamp the lower words since by definition the
112 * upper words x1/y1 must have a known number of digits
113 */
114 mp_clamp (&x0);
115 mp_clamp (&y0);
116
117 /* now calc the products x0y0 and x1y1 */
118 /* after this x0 is no longer required, free temp [x0==t2]! */
119 if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)
120 goto X1Y1; /* x0y0 = x0*y0 */
121 if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
122 goto X1Y1; /* x1y1 = x1*y1 */
123
124 /* now calc x1+x0 and y1+y0 */
125 if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
126 goto X1Y1; /* t1 = x1 - x0 */
127 if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
128 goto X1Y1; /* t2 = y1 - y0 */
129 if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
130 goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */
131
132 /* add x0y0 */
133 if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
134 goto X1Y1; /* t2 = x0y0 + x1y1 */
135 if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
136 goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
137
138 /* shift by B */
139 if (mp_lshd (&t1, B) != MP_OKAY)
140 goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
141 if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
142 goto X1Y1; /* x1y1 = x1y1 << 2*B */
143
144 if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
145 goto X1Y1; /* t1 = x0y0 + t1 */
146 if (mp_add (&t1, &x1y1, c) != MP_OKAY)
147 goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
148
149 /* Algorithm succeeded set the return code to MP_OKAY */
150 err = MP_OKAY;
151
152 X1Y1:mp_clear (&x1y1);
153 X0Y0:mp_clear (&x0y0);
154 T1:mp_clear (&t1);
155 Y1:mp_clear (&y1);
156 Y0:mp_clear (&y0);
157 X1:mp_clear (&x1);
158 X0:mp_clear (&x0);
159 ERR:
160 return err;
161 }
162 #endif
163
164 /* $Source$ */
165 /* $Revision$ */
166 /* $Date$ */
+0
-121
libtom-src/bn_mp_karatsuba_sqr.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_KARATSUBA_SQR_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 /* Karatsuba squaring, computes b = a*a using three
18 * half size squarings
19 *
20 * See comments of karatsuba_mul for details. It
21 * is essentially the same algorithm but merely
22 * tuned to perform recursive squarings.
23 */
24 int mp_karatsuba_sqr (mp_int * a, mp_int * b)
25 {
26 mp_int x0, x1, t1, t2, x0x0, x1x1;
27 int B, err;
28
29 err = MP_MEM;
30
31 /* min # of digits */
32 B = a->used;
33
34 /* now divide in two */
35 B = B >> 1;
36
37 /* init copy all the temps */
38 if (mp_init_size (&x0, B) != MP_OKAY)
39 goto ERR;
40 if (mp_init_size (&x1, a->used - B) != MP_OKAY)
41 goto X0;
42
43 /* init temps */
44 if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
45 goto X1;
46 if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
47 goto T1;
48 if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
49 goto T2;
50 if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
51 goto X0X0;
52
53 {
54 register int x;
55 register mp_digit *dst, *src;
56
57 src = a->dp;
58
59 /* now shift the digits */
60 dst = x0.dp;
61 for (x = 0; x < B; x++) {
62 *dst++ = *src++;
63 }
64
65 dst = x1.dp;
66 for (x = B; x < a->used; x++) {
67 *dst++ = *src++;
68 }
69 }
70
71 x0.used = B;
72 x1.used = a->used - B;
73
74 mp_clamp (&x0);
75
76 /* now calc the products x0*x0 and x1*x1 */
77 if (mp_sqr (&x0, &x0x0) != MP_OKAY)
78 goto X1X1; /* x0x0 = x0*x0 */
79 if (mp_sqr (&x1, &x1x1) != MP_OKAY)
80 goto X1X1; /* x1x1 = x1*x1 */
81
82 /* now calc (x1+x0)**2 */
83 if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
84 goto X1X1; /* t1 = x1 - x0 */
85 if (mp_sqr (&t1, &t1) != MP_OKAY)
86 goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
87
88 /* add x0y0 */
89 if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
90 goto X1X1; /* t2 = x0x0 + x1x1 */
91 if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
92 goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
93
94 /* shift by B */
95 if (mp_lshd (&t1, B) != MP_OKAY)
96 goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
97 if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
98 goto X1X1; /* x1x1 = x1x1 << 2*B */
99
100 if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
101 goto X1X1; /* t1 = x0x0 + t1 */
102 if (mp_add (&t1, &x1x1, b) != MP_OKAY)
103 goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
104
105 err = MP_OKAY;
106
107 X1X1:mp_clear (&x1x1);
108 X0X0:mp_clear (&x0x0);
109 T2:mp_clear (&t2);
110 T1:mp_clear (&t1);
111 X1:mp_clear (&x1);
112 X0:mp_clear (&x0);
113 ERR:
114 return err;
115 }
116 #endif
117
118 /* $Source$ */
119 /* $Revision$ */
120 /* $Date$ */
+0
-60
libtom-src/bn_mp_lcm.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_LCM_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 /* computes least common multiple as |a*b|/(a, b) */
18 int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
19 {
20 int res;
21 mp_int t1, t2;
22
23
24 if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
25 return res;
26 }
27
28 /* t1 = get the GCD of the two inputs */
29 if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
30 goto LBL_T;
31 }
32
33 /* divide the smallest by the GCD */
34 if (mp_cmp_mag(a, b) == MP_LT) {
35 /* store quotient in t2 such that t2 * b is the LCM */
36 if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
37 goto LBL_T;
38 }
39 res = mp_mul(b, &t2, c);
40 } else {
41 /* store quotient in t2 such that t2 * a is the LCM */
42 if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
43 goto LBL_T;
44 }
45 res = mp_mul(a, &t2, c);
46 }
47
48 /* fix the sign to positive */
49 c->sign = MP_ZPOS;
50
51 LBL_T:
52 mp_clear_multi (&t1, &t2, NULL);
53 return res;
54 }
55 #endif
56
57 /* $Source$ */
58 /* $Revision$ */
59 /* $Date$ */
+0
-67
libtom-src/bn_mp_lshd.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_LSHD_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 /* shift left a certain amount of digits */
18 int mp_lshd (mp_int * a, int b)
19 {
20 int x, res;
21
22 /* if its less than zero return */
23 if (b <= 0) {
24 return MP_OKAY;
25 }
26
27 /* grow to fit the new digits */
28 if (a->alloc < a->used + b) {
29 if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
30 return res;
31 }
32 }
33
34 {
35 register mp_digit *top, *bottom;
36
37 /* increment the used by the shift amount then copy upwards */
38 a->used += b;
39
40 /* top */
41 top = a->dp + a->used - 1;
42
43 /* base */
44 bottom = a->dp + a->used - 1 - b;
45
46 /* much like mp_rshd this is implemented using a sliding window
47 * except the window goes the otherway around. Copying from
48 * the bottom to the top. see bn_mp_rshd.c for more info.
49 */
50 for (x = a->used - 1; x >= b; x--) {
51 *top-- = *bottom--;
52 }
53
54 /* zero the lower digits */
55 top = a->dp;
56 for (x = 0; x < b; x++) {
57 *top++ = 0;
58 }
59 }
60 return MP_OKAY;
61 }
62 #endif
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
+0
-48
libtom-src/bn_mp_mod.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MOD_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 /* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */
18 int
19 mp_mod (mp_int * a, mp_int * b, mp_int * c)
20 {
21 mp_int t;
22 int res;
23
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
27
28 if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
32
33 if (mp_iszero(&t) || t.sign == b->sign) {
34 res = MP_OKAY;
35 mp_exch (&t, c);
36 } else {
37 res = mp_add (b, &t, c);
38 }
39
40 mp_clear (&t);
41 return res;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
+0
-55
libtom-src/bn_mp_mod_2d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MOD_2D_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 /* calc a value mod 2**b */
18 int
19 mp_mod_2d (mp_int * a, int b, mp_int * c)
20 {
21 int x, res;
22
23 /* if b is <= 0 then zero the int */
24 if (b <= 0) {
25 mp_zero (c);
26 return MP_OKAY;
27 }
28
29 /* if the modulus is larger than the value than return */
30 if (b >= (int) (a->used * DIGIT_BIT)) {
31 res = mp_copy (a, c);
32 return res;
33 }
34
35 /* copy */
36 if ((res = mp_copy (a, c)) != MP_OKAY) {
37 return res;
38 }
39
40 /* zero digits above the last digit of the modulus */
41 for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
42 c->dp[x] = 0;
43 }
44 /* clear the digit that is not completely outside/inside the modulus */
45 c->dp[b / DIGIT_BIT] &=
46 (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
47 mp_clamp (c);
48 return MP_OKAY;
49 }
50 #endif
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
+0
-27
libtom-src/bn_mp_mod_d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MOD_D_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 int
18 mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
19 {
20 return mp_div_d(a, b, NULL, c);
21 }
22 #endif
23
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
+0
-59
libtom-src/bn_mp_montgomery_calc_normalization.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_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 /*
18 * shifts with subtractions when the result is greater than b.
19 *
20 * The method is slightly modified to shift B unconditionally upto just under
21 * the leading bit of b. This saves alot of multiple precision shifting.
22 */
23 int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
24 {
25 int x, bits, res;
26
27 /* how many bits of last digit does b use */
28 bits = mp_count_bits (b) % DIGIT_BIT;
29
30 if (b->used > 1) {
31 if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
32 return res;
33 }
34 } else {
35 mp_set(a, 1);
36 bits = 1;
37 }
38
39
40 /* now compute C = A * B mod b */
41 for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
42 if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
43 return res;
44 }
45 if (mp_cmp_mag (a, b) != MP_LT) {
46 if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
47 return res;
48 }
49 }
50 }
51
52 return MP_OKAY;
53 }
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
+0
-118
libtom-src/bn_mp_montgomery_reduce.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MONTGOMERY_REDUCE_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 /* computes xR**-1 == x (mod N) via Montgomery Reduction */
18 int
19 mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
20 {
21 int ix, res, digs;
22 mp_digit mu;
23
24 /* can the fast reduction [comba] method be used?
25 *
26 * Note that unlike in mul you're safely allowed *less*
27 * than the available columns [255 per default] since carries
28 * are fixed up in the inner loop.
29 */
30 digs = n->used * 2 + 1;
31 if ((digs < MP_WARRAY) &&
32 n->used <
33 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
34 return fast_mp_montgomery_reduce (x, n, rho);
35 }
36
37 /* grow the input as required */
38 if (x->alloc < digs) {
39 if ((res = mp_grow (x, digs)) != MP_OKAY) {
40 return res;
41 }
42 }
43 x->used = digs;
44
45 for (ix = 0; ix < n->used; ix++) {
46 /* mu = ai * rho mod b
47 *
48 * The value of rho must be precalculated via
49 * montgomery_setup() such that
50 * it equals -1/n0 mod b this allows the
51 * following inner loop to reduce the
52 * input one digit at a time
53 */
54 mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
55
56 /* a = a + mu * m * b**i */
57 {
58 register int iy;
59 register mp_digit *tmpn, *tmpx, u;
60 register mp_word r;
61
62 /* alias for digits of the modulus */
63 tmpn = n->dp;
64
65 /* alias for the digits of x [the input] */
66 tmpx = x->dp + ix;
67
68 /* set the carry to zero */
69 u = 0;
70
71 /* Multiply and add in place */
72 for (iy = 0; iy < n->used; iy++) {
73 /* compute product and sum */
74 r = ((mp_word)mu) * ((mp_word)*tmpn++) +
75 ((mp_word) u) + ((mp_word) * tmpx);
76
77 /* get carry */
78 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
79
80 /* fix digit */
81 *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
82 }
83 /* At this point the ix'th digit of x should be zero */
84
85
86 /* propagate carries upwards as required*/
87 while (u) {
88 *tmpx += u;
89 u = *tmpx >> DIGIT_BIT;
90 *tmpx++ &= MP_MASK;
91 }
92 }
93 }
94
95 /* at this point the n.used'th least
96 * significant digits of x are all zero
97 * which means we can shift x to the
98 * right by n.used digits and the
99 * residue is unchanged.
100 */
101
102 /* x = x/b**n.used */
103 mp_clamp(x);
104 mp_rshd (x, n->used);
105
106 /* if x >= n then x = x - n */
107 if (mp_cmp_mag (x, n) != MP_LT) {
108 return s_mp_sub (x, n, x);
109 }
110
111 return MP_OKAY;
112 }
113 #endif
114
115 /* $Source$ */
116 /* $Revision$ */
117 /* $Date$ */
+0
-59
libtom-src/bn_mp_montgomery_setup.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MONTGOMERY_SETUP_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 /* setups the montgomery reduction stuff */
18 int
19 mp_montgomery_setup (mp_int * n, mp_digit * rho)
20 {
21 mp_digit x, b;
22
23 /* fast inversion mod 2**k
24 *
25 * Based on the fact that
26 *
27 * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
28 * => 2*X*A - X*X*A*A = 1
29 * => 2*(1) - (1) = 1
30 */
31 b = n->dp[0];
32
33 if ((b & 1) == 0) {
34 return MP_VAL;
35 }
36
37 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
38 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
39 #if !defined(MP_8BIT)
40 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
41 #endif
42 #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
43 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
44 #endif
45 #ifdef MP_64BIT
46 x *= 2 - b * x; /* here x*a==1 mod 2**64 */
47 #endif
48
49 /* rho = -1/m mod b */
50 *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
51
52 return MP_OKAY;
53 }
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
+0
-66
libtom-src/bn_mp_mul.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MUL_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 /* high level multiplication (handles sign) */
18 int mp_mul (mp_int * a, mp_int * b, mp_int * c)
19 {
20 int res, neg;
21 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
22
23 /* use Toom-Cook? */
24 #ifdef BN_MP_TOOM_MUL_C
25 if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
26 res = mp_toom_mul(a, b, c);
27 } else
28 #endif
29 #ifdef BN_MP_KARATSUBA_MUL_C
30 /* use Karatsuba? */
31 if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
32 res = mp_karatsuba_mul (a, b, c);
33 } else
34 #endif
35 {
36 /* can we use the fast multiplier?
37 *
38 * The fast multiplier can be used if the output will
39 * have less than MP_WARRAY digits and the number of
40 * digits won't affect carry propagation
41 */
42 int digs = a->used + b->used + 1;
43
44 #ifdef BN_FAST_S_MP_MUL_DIGS_C
45 if ((digs < MP_WARRAY) &&
46 MIN(a->used, b->used) <=
47 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
48 res = fast_s_mp_mul_digs (a, b, c, digs);
49 } else
50 #endif
51 #ifdef BN_S_MP_MUL_DIGS_C
52 res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
53 #else
54 res = MP_VAL;
55 #endif
56
57 }
58 c->sign = (c->used > 0) ? neg : MP_ZPOS;
59 return res;
60 }
61 #endif
62
63 /* $Source$ */
64 /* $Revision$ */
65 /* $Date$ */
+0
-82
libtom-src/bn_mp_mul_2.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MUL_2_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 /* b = a*2 */
18 int mp_mul_2(mp_int * a, mp_int * b)
19 {
20 int x, res, oldused;
21
22 /* grow to accomodate result */
23 if (b->alloc < a->used + 1) {
24 if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
25 return res;
26 }
27 }
28
29 oldused = b->used;
30 b->used = a->used;
31
32 {
33 register mp_digit r, rr, *tmpa, *tmpb;
34
35 /* alias for source */
36 tmpa = a->dp;
37
38 /* alias for dest */
39 tmpb = b->dp;
40
41 /* carry */
42 r = 0;
43 for (x = 0; x < a->used; x++) {
44
45 /* get what will be the *next* carry bit from the
46 * MSB of the current digit
47 */
48 rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
49
50 /* now shift up this digit, add in the carry [from the previous] */
51 *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
52
53 /* copy the carry that would be from the source
54 * digit into the next iteration
55 */
56 r = rr;
57 }
58
59 /* new leading digit? */
60 if (r != 0) {
61 /* add a MSB which is always 1 at this point */
62 *tmpb = 1;
63 ++(b->used);
64 }
65
66 /* now zero any excess digits on the destination
67 * that we didn't write to
68 */
69 tmpb = b->dp + b->used;
70 for (x = b->used; x < oldused; x++) {
71 *tmpb++ = 0;
72 }
73 }
74 b->sign = a->sign;
75 return MP_OKAY;
76 }
77 #endif
78
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
+0
-85
libtom-src/bn_mp_mul_2d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MUL_2D_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 /* shift left by a certain bit count */
18 int mp_mul_2d (mp_int * a, int b, mp_int * c)
19 {
20 mp_digit d;
21 int res;
22
23 /* copy */
24 if (a != c) {
25 if ((res = mp_copy (a, c)) != MP_OKAY) {
26 return res;
27 }
28 }
29
30 if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
31 if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
32 return res;
33 }
34 }
35
36 /* shift by as many digits in the bit count */
37 if (b >= (int)DIGIT_BIT) {
38 if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
39 return res;
40 }
41 }
42
43 /* shift any bit count < DIGIT_BIT */
44 d = (mp_digit) (b % DIGIT_BIT);
45 if (d != 0) {
46 register mp_digit *tmpc, shift, mask, r, rr;
47 register int x;
48
49 /* bitmask for carries */
50 mask = (((mp_digit)1) << d) - 1;
51
52 /* shift for msbs */
53 shift = DIGIT_BIT - d;
54
55 /* alias */
56 tmpc = c->dp;
57
58 /* carry */
59 r = 0;
60 for (x = 0; x < c->used; x++) {
61 /* get the higher bits of the current word */
62 rr = (*tmpc >> shift) & mask;
63
64 /* shift the current word and OR in the carry */
65 *tmpc = ((*tmpc << d) | r) & MP_MASK;
66 ++tmpc;
67
68 /* set the carry to the carry bits of the current word */
69 r = rr;
70 }
71
72 /* set final carry */
73 if (r != 0) {
74 c->dp[(c->used)++] = r;
75 }
76 }
77 mp_clamp (c);
78 return MP_OKAY;
79 }
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
+0
-79
libtom-src/bn_mp_mul_d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MUL_D_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 /* multiply by a digit */
18 int
19 mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
20 {
21 mp_digit u, *tmpa, *tmpc;
22 mp_word r;
23 int ix, res, olduse;
24
25 /* make sure c is big enough to hold a*b */
26 if (c->alloc < a->used + 1) {
27 if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
28 return res;
29 }
30 }
31
32 /* get the original destinations used count */
33 olduse = c->used;
34
35 /* set the sign */
36 c->sign = a->sign;
37
38 /* alias for a->dp [source] */
39 tmpa = a->dp;
40
41 /* alias for c->dp [dest] */
42 tmpc = c->dp;
43
44 /* zero carry */
45 u = 0;
46
47 /* compute columns */
48 for (ix = 0; ix < a->used; ix++) {
49 /* compute product and carry sum for this term */
50 r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
51
52 /* mask off higher bits to get a single digit */
53 *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
54
55 /* send carry into next iteration */
56 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
57 }
58
59 /* store final carry [if any] and increment ix offset */
60 *tmpc++ = u;
61 ++ix;
62
63 /* now zero digits above the top */
64 while (ix++ < olduse) {
65 *tmpc++ = 0;
66 }
67
68 /* set used count */
69 c->used = a->used + 1;
70 mp_clamp(c);
71
72 return MP_OKAY;
73 }
74 #endif
75
76 /* $Source$ */
77 /* $Revision$ */
78 /* $Date$ */
+0
-40
libtom-src/bn_mp_mulmod.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_MULMOD_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 /* d = a * b (mod c) */
18 int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
19 {
20 int res;
21 mp_int t;
22
23 if ((res = mp_init (&t)) != MP_OKAY) {
24 return res;
25 }
26
27 if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
28 mp_clear (&t);
29 return res;
30 }
31 res = mp_mod (&t, c, d);
32 mp_clear (&t);
33 return res;
34 }
35 #endif
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
+0
-132
libtom-src/bn_mp_n_root.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_N_ROOT_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 (mp_int * a, mp_digit b, mp_int * c)
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 (&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 #endif
128
129 /* $Source$ */
130 /* $Revision$ */
131 /* $Date$ */
+0
-40
libtom-src/bn_mp_neg.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_NEG_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 /* b = -a */
18 int mp_neg (mp_int * a, mp_int * b)
19 {
20 int res;
21 if (a != b) {
22 if ((res = mp_copy (a, b)) != MP_OKAY) {
23 return res;
24 }
25 }
26
27 if (mp_iszero(b) != MP_YES) {
28 b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
29 } else {
30 b->sign = MP_ZPOS;
31 }
32
33 return MP_OKAY;
34 }
35 #endif
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
+0
-50
libtom-src/bn_mp_or.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_OR_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 /* OR two ints together */
18 int mp_or (mp_int * a, mp_int * b, mp_int * c)
19 {
20 int res, ix, px;
21 mp_int t, *x;
22
23 if (a->used > b->used) {
24 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
25 return res;
26 }
27 px = b->used;
28 x = b;
29 } else {
30 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
31 return res;
32 }
33 px = a->used;
34 x = a;
35 }
36
37 for (ix = 0; ix < px; ix++) {
38 t.dp[ix] |= x->dp[ix];
39 }
40 mp_clamp (&t);
41 mp_exch (c, &t);
42 mp_clear (&t);
43 return MP_OKAY;
44 }
45 #endif
46
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
+0
-62
libtom-src/bn_mp_prime_fermat.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_FERMAT_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 /* performs one Fermat test.
18 *
19 * If "a" were prime then b**a == b (mod a) since the order of
20 * the multiplicative sub-group would be phi(a) = a-1. That means
21 * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
22 *
23 * Sets result to 1 if the congruence holds, or zero otherwise.
24 */
25 int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
26 {
27 mp_int t;
28 int err;
29
30 /* default to composite */
31 *result = MP_NO;
32
33 /* ensure b > 1 */
34 if (mp_cmp_d(b, 1) != MP_GT) {
35 return MP_VAL;
36 }
37
38 /* init t */
39 if ((err = mp_init (&t)) != MP_OKAY) {
40 return err;
41 }
42
43 /* compute t = b**a mod a */
44 if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
45 goto LBL_T;
46 }
47
48 /* is it equal to b? */
49 if (mp_cmp (&t, b) == MP_EQ) {
50 *result = MP_YES;
51 }
52
53 err = MP_OKAY;
54 LBL_T:mp_clear (&t);
55 return err;
56 }
57 #endif
58
59 /* $Source$ */
60 /* $Revision$ */
61 /* $Date$ */
+0
-50
libtom-src/bn_mp_prime_is_divisible.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_IS_DIVISIBLE_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 /* determines if an integers is divisible by one
18 * of the first PRIME_SIZE primes or not
19 *
20 * sets result to 0 if not, 1 if yes
21 */
22 int mp_prime_is_divisible (mp_int * a, int *result)
23 {
24 int err, ix;
25 mp_digit res;
26
27 /* default to not */
28 *result = MP_NO;
29
30 for (ix = 0; ix < PRIME_SIZE; ix++) {
31 /* what is a mod LBL_prime_tab[ix] */
32 if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
33 return err;
34 }
35
36 /* is the residue zero? */
37 if (res == 0) {
38 *result = MP_YES;
39 return MP_OKAY;
40 }
41 }
42
43 return MP_OKAY;
44 }
45 #endif
46
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
+0
-83
libtom-src/bn_mp_prime_is_prime.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_IS_PRIME_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 /* performs a variable number of rounds of Miller-Rabin
18 *
19 * Probability of error after t rounds is no more than
20
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)
25 {
26 mp_int b;
27 int ix, err, res;
28
29 /* default to no */
30 *result = MP_NO;
31
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) {
52 return MP_OKAY;
53 }
54
55 /* now perform the miller-rabin rounds */
56 if ((err = mp_init (&b)) != MP_OKAY) {
57 return err;
58 }
59
60 for (ix = 0; ix < t; ix++) {
61 /* set the prime */
62 mp_set (&b, ltm_prime_tab[ix]);
63
64 if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
65 goto LBL_B;
66 }
67
68 if (res == MP_NO) {
69 goto LBL_B;
70 }
71 }
72
73 /* passed the test */
74 *result = MP_YES;
75 LBL_B:mp_clear (&b);
76 return err;
77 }
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
+0
-103
libtom-src/bn_mp_prime_miller_rabin.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_MILLER_RABIN_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 /* Miller-Rabin test of "a" to the base of "b" as described in
18 * HAC pp. 139 Algorithm 4.24
19 *
20 * Sets result to 0 if definitely composite or 1 if probably prime.
21 * Randomly the chance of error is no more than 1/4 and often
22 * very much lower.
23 */
24 int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
25 {
26 mp_int n1, y, r;
27 int s, j, err;
28
29 /* default */
30 *result = MP_NO;
31
32 /* ensure b > 1 */
33 if (mp_cmp_d(b, 1) != MP_GT) {
34 return MP_VAL;
35 }
36
37 /* get n1 = a - 1 */
38 if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
39 return err;
40 }
41 if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
42 goto LBL_N1;
43 }
44
45 /* set 2**s * r = n1 */
46 if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
47 goto LBL_N1;
48 }
49
50 /* count the number of least significant bits
51 * which are zero
52 */
53 s = mp_cnt_lsb(&r);
54
55 /* now divide n - 1 by 2**s */
56 if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
57 goto LBL_R;
58 }
59
60 /* compute y = b**r mod a */
61 if ((err = mp_init (&y)) != MP_OKAY) {
62 goto LBL_R;
63 }
64 if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
65 goto LBL_Y;
66 }
67
68 /* if y != 1 and y != n1 do */
69 if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
70 j = 1;
71 /* while j <= s-1 and y != n1 */
72 while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
73 if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
74 goto LBL_Y;
75 }
76
77 /* if y == 1 then composite */
78 if (mp_cmp_d (&y, 1) == MP_EQ) {
79 goto LBL_Y;
80 }
81
82 ++j;
83 }
84
85 /* if y != n1 then composite */
86 if (mp_cmp (&y, &n1) != MP_EQ) {
87 goto LBL_Y;
88 }
89 }
90
91 /* probably prime now */
92 *result = MP_YES;
93 LBL_Y:mp_clear (&y);
94 LBL_R:mp_clear (&r);
95 LBL_N1:mp_clear (&n1);
96 return err;
97 }
98 #endif
99
100 /* $Source$ */
101 /* $Revision$ */
102 /* $Date$ */
+0
-170
libtom-src/bn_mp_prime_next_prime.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_NEXT_PRIME_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 /* finds the next prime after the number "a" using "t" trials
18 * of Miller-Rabin.
19 *
20 * bbs_style = 1 means the prime must be congruent to 3 mod 4
21 */
22 int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
23 {
24 int err, res, x, y;
25 mp_digit res_tab[PRIME_SIZE], step, kstep;
26 mp_int b;
27
28 /* ensure t is valid */
29 if (t <= 0 || t > PRIME_SIZE) {
30 return MP_VAL;
31 }
32
33 /* force positive */
34 a->sign = MP_ZPOS;
35
36 /* simple algo if a is less than the largest prime in the table */
37 if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
38 /* find which prime it is bigger than */
39 for (x = PRIME_SIZE - 2; x >= 0; x--) {
40 if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
41 if (bbs_style == 1) {
42 /* ok we found a prime smaller or
43 * equal [so the next is larger]
44 *
45 * however, the prime must be
46 * congruent to 3 mod 4
47 */
48 if ((ltm_prime_tab[x + 1] & 3) != 3) {
49 /* scan upwards for a prime congruent to 3 mod 4 */
50 for (y = x + 1; y < PRIME_SIZE; y++) {
51 if ((ltm_prime_tab[y] & 3) == 3) {
52 mp_set(a, ltm_prime_tab[y]);
53 return MP_OKAY;
54 }
55 }
56 }
57 } else {
58 mp_set(a, ltm_prime_tab[x + 1]);
59 return MP_OKAY;
60 }
61 }
62 }
63 /* at this point a maybe 1 */
64 if (mp_cmp_d(a, 1) == MP_EQ) {
65 mp_set(a, 2);
66 return MP_OKAY;
67 }
68 /* fall through to the sieve */
69 }
70
71 /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
72 if (bbs_style == 1) {
73 kstep = 4;
74 } else {
75 kstep = 2;
76 }
77
78 /* at this point we will use a combination of a sieve and Miller-Rabin */
79
80 if (bbs_style == 1) {
81 /* if a mod 4 != 3 subtract the correct value to make it so */
82 if ((a->dp[0] & 3) != 3) {
83 if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
84 }
85 } else {
86 if (mp_iseven(a) == 1) {
87 /* force odd */
88 if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
89 return err;
90 }
91 }
92 }
93
94 /* generate the restable */
95 for (x = 1; x < PRIME_SIZE; x++) {
96 if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) {
97 return err;
98 }
99 }
100
101 /* init temp used for Miller-Rabin Testing */
102 if ((err = mp_init(&b)) != MP_OKAY) {
103 return err;
104 }
105
106 for (;;) {
107 /* skip to the next non-trivially divisible candidate */
108 step = 0;
109 do {
110 /* y == 1 if any residue was zero [e.g. cannot be prime] */
111 y = 0;
112
113 /* increase step to next candidate */
114 step += kstep;
115
116 /* compute the new residue without using division */
117 for (x = 1; x < PRIME_SIZE; x++) {
118 /* add the step to each residue */
119 res_tab[x] += kstep;
120
121 /* subtract the modulus [instead of using division] */
122 if (res_tab[x] >= ltm_prime_tab[x]) {
123 res_tab[x] -= ltm_prime_tab[x];
124 }
125
126 /* set flag if zero */
127 if (res_tab[x] == 0) {
128 y = 1;
129 }
130 }
131 } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep));
132
133 /* add the step */
134 if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
135 goto LBL_ERR;
136 }
137
138 /* if didn't pass sieve and step == MAX then skip test */
139 if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
140 continue;
141 }
142
143 /* is this prime? */
144 for (x = 0; x < t; x++) {
145 mp_set(&b, ltm_prime_tab[x]);
146 if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
147 goto LBL_ERR;
148 }
149 if (res == MP_NO) {
150 break;
151 }
152 }
153
154 if (res == MP_YES) {
155 break;
156 }
157 }
158
159 err = MP_OKAY;
160 LBL_ERR:
161 mp_clear(&b);
162 return err;
163 }
164
165 #endif
166
167 /* $Source$ */
168 /* $Revision$ */
169 /* $Date$ */
+0
-52
libtom-src/bn_mp_prime_rabin_miller_trials.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_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
18 static const struct {
19 int k, t;
20 } sizes[] = {
21 { 128, 28 },
22 { 256, 16 },
23 { 384, 10 },
24 { 512, 7 },
25 { 640, 6 },
26 { 768, 5 },
27 { 896, 4 },
28 { 1024, 4 }
29 };
30
31 /* returns # of RM trials required for a given bit size */
32 int mp_prime_rabin_miller_trials(int size)
33 {
34 int x;
35
36 for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
37 if (sizes[x].k == size) {
38 return sizes[x].t;
39 } else if (sizes[x].k > size) {
40 return (x == 0) ? sizes[0].t : sizes[x - 1].t;
41 }
42 }
43 return sizes[x-1].t + 1;
44 }
45
46
47 #endif
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
+0
-124
libtom-src/bn_mp_prime_random_ex.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_RANDOM_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 /* makes a truly random prime of a given size (bits),
18 *
19 * Flags are as follows:
20 *
21 * LTM_PRIME_BBS - make prime congruent to 3 mod 4
22 * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
23 * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
24 *
25 * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
26 * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
27 * so it can be NULL
28 *
29 */
30
31 /* This is possibly the mother of all prime generation functions, muahahahahaha! */
32 int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat)
33 {
34 unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
35 int res, err, bsize, maskOR_msb_offset;
36
37 /* sanity check the input */
38 if (size <= 1 || t <= 0) {
39 return MP_VAL;
40 }
41
42 /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */
43 if (flags & LTM_PRIME_SAFE) {
44 flags |= LTM_PRIME_BBS;
45 }
46
47 /* calc the byte size */
48 bsize = (size>>3) + ((size&7)?1:0);
49
50 /* we need a buffer of bsize bytes */
51 tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
52 if (tmp == NULL) {
53 return MP_MEM;
54 }
55
56 /* calc the maskAND value for the MSbyte*/
57 maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7)));
58
59 /* calc the maskOR_msb */
60 maskOR_msb = 0;
61 maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
62 if (flags & LTM_PRIME_2MSB_ON) {
63 maskOR_msb |= 0x80 >> ((9 - size) & 7);
64 }
65
66 /* get the maskOR_lsb */
67 maskOR_lsb = 1;
68 if (flags & LTM_PRIME_BBS) {
69 maskOR_lsb |= 3;
70 }
71
72 do {
73 /* read the bytes */
74 if (cb(tmp, bsize, dat) != bsize) {
75 err = MP_VAL;
76 goto error;
77 }
78
79 /* work over the MSbyte */
80 tmp[0] &= maskAND;
81 tmp[0] |= 1 << ((size - 1) & 7);
82
83 /* mix in the maskORs */
84 tmp[maskOR_msb_offset] |= maskOR_msb;
85 tmp[bsize-1] |= maskOR_lsb;
86
87 /* read it in */
88 if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; }
89
90 /* is it prime? */
91 if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
92 if (res == MP_NO) {
93 continue;
94 }
95
96 if (flags & LTM_PRIME_SAFE) {
97 /* see if (a-1)/2 is prime */
98 if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; }
99 if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; }
100
101 /* is it prime? */
102 if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
103 }
104 } while (res == MP_NO);
105
106 if (flags & LTM_PRIME_SAFE) {
107 /* restore a to the original value */
108 if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; }
109 if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; }
110 }
111
112 err = MP_OKAY;
113 error:
114 XFREE(tmp);
115 return err;
116 }
117
118
119 #endif
120
121 /* $Source$ */
122 /* $Revision$ */
123 /* $Date$ */
+0
-78
libtom-src/bn_mp_radix_size.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_RADIX_SIZE_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 /* returns size of ASCII reprensentation */
18 int mp_radix_size (mp_int * a, int radix, int *size)
19 {
20 int res, digs;
21 mp_int t;
22 mp_digit d;
23
24 *size = 0;
25
26 /* make sure the radix is in range */
27 if (radix < 2 || radix > 64) {
28 return MP_VAL;
29 }
30
31 if (mp_iszero(a) == MP_YES) {
32 *size = 2;
33 return MP_OKAY;
34 }
35
36 /* special case for binary */
37 if (radix == 2) {
38 *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
39 return MP_OKAY;
40 }
41
42 /* digs is the digit count */
43 digs = 0;
44
45 /* if it's negative add one for the sign */
46 if (a->sign == MP_NEG) {
47 ++digs;
48 }
49
50 /* init a copy of the input */
51 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
52 return res;
53 }
54
55 /* force temp to positive */
56 t.sign = MP_ZPOS;
57
58 /* fetch out all of the digits */
59 while (mp_iszero (&t) == MP_NO) {
60 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
61 mp_clear (&t);
62 return res;
63 }
64 ++digs;
65 }
66 mp_clear (&t);
67
68 /* return digs + 1, the 1 is for the NULL byte that would be required. */
69 *size = digs + 1;
70 return MP_OKAY;
71 }
72
73 #endif
74
75 /* $Source$ */
76 /* $Revision$ */
77 /* $Date$ */
+0
-24
libtom-src/bn_mp_radix_smap.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_RADIX_SMAP_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 /* chars used in radix conversions */
18 const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
19 #endif
20
21 /* $Source$ */
22 /* $Revision$ */
23 /* $Date$ */
+0
-55
libtom-src/bn_mp_rand.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_RAND_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 /* makes a pseudo-random int of a given size */
18 int
19 mp_rand (mp_int * a, int digits)
20 {
21 int res;
22 mp_digit d;
23
24 mp_zero (a);
25 if (digits <= 0) {
26 return MP_OKAY;
27 }
28
29 /* first place a random non-zero digit */
30 do {
31 d = ((mp_digit) abs (rand ())) & MP_MASK;
32 } while (d == 0);
33
34 if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
35 return res;
36 }
37
38 while (--digits > 0) {
39 if ((res = mp_lshd (a, 1)) != MP_OKAY) {
40 return res;
41 }
42
43 if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) {
44 return res;
45 }
46 }
47
48 return MP_OKAY;
49 }
50 #endif
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
+0
-85
libtom-src/bn_mp_read_radix.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_READ_RADIX_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 /* read a string [ASCII] in a given radix */
18 int mp_read_radix (mp_int * a, const char *str, int radix)
19 {
20 int y, res, neg;
21 char ch;
22
23 /* zero the digit bignum */
24 mp_zero(a);
25
26 /* make sure the radix is ok */
27 if (radix < 2 || radix > 64) {
28 return MP_VAL;
29 }
30
31 /* if the leading digit is a
32 * minus set the sign to negative.
33 */
34 if (*str == '-') {
35 ++str;
36 neg = MP_NEG;
37 } else {
38 neg = MP_ZPOS;
39 }
40
41 /* set the integer to the default of zero */
42 mp_zero (a);
43
44 /* process each digit of the string */
45 while (*str) {
46 /* if the radix <= 36 the conversion is case insensitive
47 * this allows numbers like 1AB and 1ab to represent the same value
48 * [e.g. in hex]
49 */
50 ch = (char) ((radix <= 36) ? toupper ((int)*str) : *str);
51 for (y = 0; y < 64; y++) {
52 if (ch == mp_s_rmap[y]) {
53 break;
54 }
55 }
56
57 /* if the char was found in the map
58 * and is less than the given radix add it
59 * to the number, otherwise exit the loop.
60 */
61 if (y < radix) {
62 if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
63 return res;
64 }
65 if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
66 return res;
67 }
68 } else {
69 break;
70 }
71 ++str;
72 }
73
74 /* set the sign only if a != 0 */
75 if (mp_iszero(a) != 1) {
76 a->sign = neg;
77 }
78 return MP_OKAY;
79 }
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
+0
-41
libtom-src/bn_mp_read_signed_bin.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_READ_SIGNED_BIN_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 /* read signed bin, big endian, first byte is 0==positive or 1==negative */
18 int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c)
19 {
20 int res;
21
22 /* read magnitude */
23 if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
24 return res;
25 }
26
27 /* first byte is 0 for positive, non-zero for negative */
28 if (b[0] == 0) {
29 a->sign = MP_ZPOS;
30 } else {
31 a->sign = MP_NEG;
32 }
33
34 return MP_OKAY;
35 }
36 #endif
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
+0
-55
libtom-src/bn_mp_read_unsigned_bin.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_READ_UNSIGNED_BIN_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 /* reads a unsigned char array, assumes the msb is stored first [big endian] */
18 int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
19 {
20 int res;
21
22 /* make sure there are at least two digits */
23 if (a->alloc < 2) {
24 if ((res = mp_grow(a, 2)) != MP_OKAY) {
25 return res;
26 }
27 }
28
29 /* zero the int */
30 mp_zero (a);
31
32 /* read the bytes in */
33 while (c-- > 0) {
34 if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
35 return res;
36 }
37
38 #ifndef MP_8BIT
39 a->dp[0] |= *b++;
40 a->used += 1;
41 #else
42 a->dp[0] = (*b & MP_MASK);
43 a->dp[1] |= ((*b++ >> 7U) & 1);
44 a->used += 2;
45 #endif
46 }
47 mp_clamp (a);
48 return MP_OKAY;
49 }
50 #endif
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
+0
-100
libtom-src/bn_mp_reduce.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_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 /* reduces x mod m, assumes 0 < x < m**2, mu is
18 * precomputed via mp_reduce_setup.
19 * From HAC pp.604 Algorithm 14.42
20 */
21 int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
22 {
23 mp_int q;
24 int res, um = m->used;
25
26 /* q = x */
27 if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
28 return res;
29 }
30
31 /* q1 = x / b**(k-1) */
32 mp_rshd (&q, um - 1);
33
34 /* according to HAC this optimization is ok */
35 if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
36 if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
37 goto CLEANUP;
38 }
39 } else {
40 #ifdef BN_S_MP_MUL_HIGH_DIGS_C
41 if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
42 goto CLEANUP;
43 }
44 #elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
45 if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
46 goto CLEANUP;
47 }
48 #else
49 {
50 res = MP_VAL;
51 goto CLEANUP;
52 }
53 #endif
54 }
55
56 /* q3 = q2 / b**(k+1) */
57 mp_rshd (&q, um + 1);
58
59 /* x = x mod b**(k+1), quick (no division) */
60 if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
61 goto CLEANUP;
62 }
63
64 /* q = q * m mod b**(k+1), quick (no division) */
65 if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
66 goto CLEANUP;
67 }
68
69 /* x = x - q */
70 if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
71 goto CLEANUP;
72 }
73
74 /* If x < 0, add b**(k+1) to it */
75 if (mp_cmp_d (x, 0) == MP_LT) {
76 mp_set (&q, 1);
77 if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
78 goto CLEANUP;
79 if ((res = mp_add (x, &q, x)) != MP_OKAY)
80 goto CLEANUP;
81 }
82
83 /* Back off if it's too big */
84 while (mp_cmp (x, m) != MP_LT) {
85 if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
86 goto CLEANUP;
87 }
88 }
89
90 CLEANUP:
91 mp_clear (&q);
92
93 return res;
94 }
95 #endif
96
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
+0
-61
libtom-src/bn_mp_reduce_2k.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_2K_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 /* reduces a modulo n where n is of the form 2**p - d */
18 int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
19 {
20 mp_int q;
21 int p, res;
22
23 if ((res = mp_init(&q)) != MP_OKAY) {
24 return res;
25 }
26
27 p = mp_count_bits(n);
28 top:
29 /* q = a/2**p, a = a mod 2**p */
30 if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
31 goto ERR;
32 }
33
34 if (d != 1) {
35 /* q = q * d */
36 if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
37 goto ERR;
38 }
39 }
40
41 /* a = a + q */
42 if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
43 goto ERR;
44 }
45
46 if (mp_cmp_mag(a, n) != MP_LT) {
47 s_mp_sub(a, n, a);
48 goto top;
49 }
50
51 ERR:
52 mp_clear(&q);
53 return res;
54 }
55
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
+0
-62
libtom-src/bn_mp_reduce_2k_l.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_2K_L_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 /* reduces a modulo n where n is of the form 2**p - d
18 This differs from reduce_2k since "d" can be larger
19 than a single digit.
20 */
21 int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
22 {
23 mp_int q;
24 int p, res;
25
26 if ((res = mp_init(&q)) != MP_OKAY) {
27 return res;
28 }
29
30 p = mp_count_bits(n);
31 top:
32 /* q = a/2**p, a = a mod 2**p */
33 if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
34 goto ERR;
35 }
36
37 /* q = q * d */
38 if ((res = mp_mul(&q, d, &q)) != MP_OKAY) {
39 goto ERR;
40 }
41
42 /* a = a + q */
43 if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
44 goto ERR;
45 }
46
47 if (mp_cmp_mag(a, n) != MP_LT) {
48 s_mp_sub(a, n, a);
49 goto top;
50 }
51
52 ERR:
53 mp_clear(&q);
54 return res;
55 }
56
57 #endif
58
59 /* $Source$ */
60 /* $Revision$ */
61 /* $Date$ */
+0
-47
libtom-src/bn_mp_reduce_2k_setup.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_2K_SETUP_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 /* determines the setup value */
18 int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
19 {
20 int res, p;
21 mp_int tmp;
22
23 if ((res = mp_init(&tmp)) != MP_OKAY) {
24 return res;
25 }
26
27 p = mp_count_bits(a);
28 if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
29 mp_clear(&tmp);
30 return res;
31 }
32
33 if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
34 mp_clear(&tmp);
35 return res;
36 }
37
38 *d = tmp.dp[0];
39 mp_clear(&tmp);
40 return MP_OKAY;
41 }
42 #endif
43
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
+0
-44
libtom-src/bn_mp_reduce_2k_setup_l.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_2K_SETUP_L_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 /* determines the setup value */
18 int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
19 {
20 int res;
21 mp_int tmp;
22
23 if ((res = mp_init(&tmp)) != MP_OKAY) {
24 return res;
25 }
26
27 if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
28 goto ERR;
29 }
30
31 if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
32 goto ERR;
33 }
34
35 ERR:
36 mp_clear(&tmp);
37 return res;
38 }
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-52
libtom-src/bn_mp_reduce_is_2k.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_IS_2K_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 /* determines if mp_reduce_2k can be used */
18 int mp_reduce_is_2k(mp_int *a)
19 {
20 int ix, iy, iw;
21 mp_digit iz;
22
23 if (a->used == 0) {
24 return MP_NO;
25 } else if (a->used == 1) {
26 return MP_YES;
27 } else if (a->used > 1) {
28 iy = mp_count_bits(a);
29 iz = 1;
30 iw = 1;
31
32 /* Test every bit from the second digit up, must be 1 */
33 for (ix = DIGIT_BIT; ix < iy; ix++) {
34 if ((a->dp[iw] & iz) == 0) {
35 return MP_NO;
36 }
37 iz <<= 1;
38 if (iz > (mp_digit)MP_MASK) {
39 ++iw;
40 iz = 1;
41 }
42 }
43 }
44 return MP_YES;
45 }
46
47 #endif
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
+0
-44
libtom-src/bn_mp_reduce_is_2k_l.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_IS_2K_L_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 /* determines if reduce_2k_l can be used */
18 int mp_reduce_is_2k_l(mp_int *a)
19 {
20 int ix, iy;
21
22 if (a->used == 0) {
23 return MP_NO;
24 } else if (a->used == 1) {
25 return MP_YES;
26 } else if (a->used > 1) {
27 /* if more than half of the digits are -1 we're sold */
28 for (iy = ix = 0; ix < a->used; ix++) {
29 if (a->dp[ix] == MP_MASK) {
30 ++iy;
31 }
32 }
33 return (iy >= (a->used/2)) ? MP_YES : MP_NO;
34
35 }
36 return MP_NO;
37 }
38
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-34
libtom-src/bn_mp_reduce_setup.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_SETUP_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 /* pre-calculate the value required for Barrett reduction
18 * For a given modulus "b" it calulates the value required in "a"
19 */
20 int mp_reduce_setup (mp_int * a, mp_int * b)
21 {
22 int res;
23
24 if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
25 return res;
26 }
27 return mp_div (a, b, a, NULL);
28 }
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
+0
-72
libtom-src/bn_mp_rshd.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_RSHD_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 /* shift right a certain amount of digits */
18 void mp_rshd (mp_int * a, int b)
19 {
20 int x;
21
22 /* if b <= 0 then ignore it */
23 if (b <= 0) {
24 return;
25 }
26
27 /* if b > used then simply zero it and return */
28 if (a->used <= b) {
29 mp_zero (a);
30 return;
31 }
32
33 {
34 register mp_digit *bottom, *top;
35
36 /* shift the digits down */
37
38 /* bottom */
39 bottom = a->dp;
40
41 /* top [offset into digits] */
42 top = a->dp + b;
43
44 /* this is implemented as a sliding window where
45 * the window is b-digits long and digits from
46 * the top of the window are copied to the bottom
47 *
48 * e.g.
49
50 b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
51 /\ | ---->
52 \-------------------/ ---->
53 */
54 for (x = 0; x < (a->used - b); x++) {
55 *bottom++ = *top++;
56 }
57
58 /* zero the top digits */
59 for (; x < a->used; x++) {
60 *bottom++ = 0;
61 }
62 }
63
64 /* remove excess digits */
65 a->used -= b;
66 }
67 #endif
68
69 /* $Source$ */
70 /* $Revision$ */
71 /* $Date$ */
+0
-29
libtom-src/bn_mp_set.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SET_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 to a digit */
18 void mp_set (mp_int * a, mp_digit b)
19 {
20 mp_zero (a);
21 a->dp[0] = b & MP_MASK;
22 a->used = (a->dp[0] != 0) ? 1 : 0;
23 }
24 #endif
25
26 /* $Source$ */
27 /* $Revision$ */
28 /* $Date$ */
+0
-48
libtom-src/bn_mp_set_int.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SET_INT_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 32-bit const */
18 int mp_set_int (mp_int * a, unsigned long b)
19 {
20 int x, res;
21
22 mp_zero (a);
23
24 /* set four bits at a time */
25 for (x = 0; x < 8; x++) {
26 /* shift the number up four bits */
27 if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
28 return res;
29 }
30
31 /* OR in the top four bits of the source */
32 a->dp[0] |= (b >> 28) & 15;
33
34 /* shift the source up to the next four bits */
35 b <<= 4;
36
37 /* ensure that digits are not clamped off */
38 a->used += 1;
39 }
40 mp_clamp (a);
41 return MP_OKAY;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
+0
-40
libtom-src/bn_mp_shrink.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SHRINK_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 /* shrink a bignum */
18 int mp_shrink (mp_int * a)
19 {
20 mp_digit *tmp;
21 int used = 1;
22
23 if(a->used > 0)
24 used = a->used;
25
26 if (a->alloc != used) {
27 if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) {
28 return MP_MEM;
29 }
30 a->dp = tmp;
31 a->alloc = used;
32 }
33 return MP_OKAY;
34 }
35 #endif
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
+0
-27
libtom-src/bn_mp_signed_bin_size.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SIGNED_BIN_SIZE_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 size for an signed equivalent */
18 int mp_signed_bin_size (mp_int * a)
19 {
20 return 1 + mp_unsigned_bin_size (a);
21 }
22 #endif
23
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
+0
-58
libtom-src/bn_mp_sqr.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SQR_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 /* computes b = a*a */
18 int
19 mp_sqr (mp_int * a, mp_int * b)
20 {
21 int res;
22
23 #ifdef BN_MP_TOOM_SQR_C
24 /* use Toom-Cook? */
25 if (a->used >= TOOM_SQR_CUTOFF) {
26 res = mp_toom_sqr(a, b);
27 /* Karatsuba? */
28 } else
29 #endif
30 #ifdef BN_MP_KARATSUBA_SQR_C
31 if (a->used >= KARATSUBA_SQR_CUTOFF) {
32 res = mp_karatsuba_sqr (a, b);
33 } else
34 #endif
35 {
36 #ifdef BN_FAST_S_MP_SQR_C
37 /* can we use the fast comba multiplier? */
38 if ((a->used * 2 + 1) < MP_WARRAY &&
39 a->used <
40 (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
41 res = fast_s_mp_sqr (a, b);
42 } else
43 #endif
44 #ifdef BN_S_MP_SQR_C
45 res = s_mp_sqr (a, b);
46 #else
47 res = MP_VAL;
48 #endif
49 }
50 b->sign = MP_ZPOS;
51 return res;
52 }
53 #endif
54
55 /* $Source$ */
56 /* $Revision$ */
57 /* $Date$ */
+0
-41
libtom-src/bn_mp_sqrmod.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SQRMOD_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 /* c = a * a (mod b) */
18 int
19 mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int res;
22 mp_int t;
23
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
27
28 if ((res = mp_sqr (a, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
32 res = mp_mod (&t, b, c);
33 mp_clear (&t);
34 return res;
35 }
36 #endif
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
+0
-81
libtom-src/bn_mp_sqrt.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SQRT_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 /* this function is less generic than mp_n_root, simpler and faster */
18 int mp_sqrt(mp_int *arg, mp_int *ret)
19 {
20 int res;
21 mp_int t1,t2;
22
23 /* must be positive */
24 if (arg->sign == MP_NEG) {
25 return MP_VAL;
26 }
27
28 /* easy out */
29 if (mp_iszero(arg) == MP_YES) {
30 mp_zero(ret);
31 return MP_OKAY;
32 }
33
34 if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
35 return res;
36 }
37
38 if ((res = mp_init(&t2)) != MP_OKAY) {
39 goto E2;
40 }
41
42 /* First approx. (not very bad for large arg) */
43 mp_rshd (&t1,t1.used/2);
44
45 /* t1 > 0 */
46 if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
47 goto E1;
48 }
49 if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
50 goto E1;
51 }
52 if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
53 goto E1;
54 }
55 /* And now t1 > sqrt(arg) */
56 do {
57 if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
58 goto E1;
59 }
60 if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
61 goto E1;
62 }
63 if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
64 goto E1;
65 }
66 /* t1 >= sqrt(arg) >= t2 at this point */
67 } while (mp_cmp_mag(&t1,&t2) == MP_GT);
68
69 mp_exch(&t1,ret);
70
71 E1: mp_clear(&t2);
72 E2: mp_clear(&t1);
73 return res;
74 }
75
76 #endif
77
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
+0
-59
libtom-src/bn_mp_sub.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SUB_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 /* high level subtraction (handles signs) */
18 int
19 mp_sub (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int sa, sb, res;
22
23 sa = a->sign;
24 sb = b->sign;
25
26 if (sa != sb) {
27 /* subtract a negative from a positive, OR */
28 /* subtract a positive from a negative. */
29 /* In either case, ADD their magnitudes, */
30 /* and use the sign of the first number. */
31 c->sign = sa;
32 res = s_mp_add (a, b, c);
33 } else {
34 /* subtract a positive from a positive, OR */
35 /* subtract a negative from a negative. */
36 /* First, take the difference between their */
37 /* magnitudes, then... */
38 if (mp_cmp_mag (a, b) != MP_LT) {
39 /* Copy the sign from the first */
40 c->sign = sa;
41 /* The first has a larger or equal magnitude */
42 res = s_mp_sub (a, b, c);
43 } else {
44 /* The result has the *opposite* sign from */
45 /* the first number. */
46 c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
47 /* The second has a larger magnitude */
48 res = s_mp_sub (b, a, c);
49 }
50 }
51 return res;
52 }
53
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
+0
-93
libtom-src/bn_mp_sub_d.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SUB_D_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 /* single digit subtraction */
18 int
19 mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
20 {
21 mp_digit *tmpa, *tmpc, mu;
22 int res, ix, oldused;
23
24 /* grow c as required */
25 if (c->alloc < a->used + 1) {
26 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27 return res;
28 }
29 }
30
31 /* if a is negative just do an unsigned
32 * addition [with fudged signs]
33 */
34 if (a->sign == MP_NEG) {
35 a->sign = MP_ZPOS;
36 res = mp_add_d(a, b, c);
37 a->sign = c->sign = MP_NEG;
38
39 /* clamp */
40 mp_clamp(c);
41
42 return res;
43 }
44
45 /* setup regs */
46 oldused = c->used;
47 tmpa = a->dp;
48 tmpc = c->dp;
49
50 /* if a <= b simply fix the single digit */
51 if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
52 if (a->used == 1) {
53 *tmpc++ = b - *tmpa;
54 } else {
55 *tmpc++ = b;
56 }
57 ix = 1;
58
59 /* negative/1digit */
60 c->sign = MP_NEG;
61 c->used = 1;
62 } else {
63 /* positive/size */
64 c->sign = MP_ZPOS;
65 c->used = a->used;
66
67 /* subtract first digit */
68 *tmpc = *tmpa++ - b;
69 mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
70 *tmpc++ &= MP_MASK;
71
72 /* handle rest of the digits */
73 for (ix = 1; ix < a->used; ix++) {
74 *tmpc = *tmpa++ - mu;
75 mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
76 *tmpc++ &= MP_MASK;
77 }
78 }
79
80 /* zero excess digits */
81 while (ix++ < oldused) {
82 *tmpc++ = 0;
83 }
84 mp_clamp(c);
85 return MP_OKAY;
86 }
87
88 #endif
89
90 /* $Source$ */
91 /* $Revision$ */
92 /* $Date$ */
+0
-42
libtom-src/bn_mp_submod.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_SUBMOD_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 /* d = a - b (mod c) */
18 int
19 mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
20 {
21 int res;
22 mp_int t;
23
24
25 if ((res = mp_init (&t)) != MP_OKAY) {
26 return res;
27 }
28
29 if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
30 mp_clear (&t);
31 return res;
32 }
33 res = mp_mod (&t, c, d);
34 mp_clear (&t);
35 return res;
36 }
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
+0
-33
libtom-src/bn_mp_to_signed_bin.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_TO_SIGNED_BIN_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 /* store in signed [big endian] format */
18 int mp_to_signed_bin (mp_int * a, unsigned char *b)
19 {
20 int res;
21
22 if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
23 return res;
24 }
25 b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1);
26 return MP_OKAY;
27 }
28 #endif
29
30 /* $Source$ */
31 /* $Revision$ */
32 /* $Date$ */
+0
-31
libtom-src/bn_mp_to_signed_bin_n.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_TO_SIGNED_BIN_N_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 /* store in signed [big endian] format */
18 int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
19 {
20 if (*outlen < (unsigned long)mp_signed_bin_size(a)) {
21 return MP_VAL;
22 }
23 *outlen = mp_signed_bin_size(a);
24 return mp_to_signed_bin(a, b);
25 }
26 #endif
27
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
+0
-48
libtom-src/bn_mp_to_unsigned_bin.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_TO_UNSIGNED_BIN_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 /* store in unsigned [big endian] format */
18 int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
19 {
20 int x, res;
21 mp_int t;
22
23 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
24 return res;
25 }
26
27 x = 0;
28 while (mp_iszero (&t) == 0) {
29 #ifndef MP_8BIT
30 b[x++] = (unsigned char) (t.dp[0] & 255);
31 #else
32 b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
33 #endif
34 if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
35 mp_clear (&t);
36 return res;
37 }
38 }
39 bn_reverse (b, x);
40 mp_clear (&t);
41 return MP_OKAY;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
+0
-31
libtom-src/bn_mp_to_unsigned_bin_n.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_TO_UNSIGNED_BIN_N_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 /* store in unsigned [big endian] format */
18 int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
19 {
20 if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
21 return MP_VAL;
22 }
23 *outlen = mp_unsigned_bin_size(a);
24 return mp_to_unsigned_bin(a, b);
25 }
26 #endif
27
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
+0
-284
libtom-src/bn_mp_toom_mul.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_TOOM_MUL_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 /* multiplication using the Toom-Cook 3-way algorithm
18 *
19 * Much more complicated than Karatsuba but has a lower
20 * asymptotic running time of O(N**1.464). This algorithm is
21 * only particularly useful on VERY large inputs
22 * (we're talking 1000s of digits here...).
23 */
24 int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
25 {
26 mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
27 int res, B;
28
29 /* init temps */
30 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
31 &a0, &a1, &a2, &b0, &b1,
32 &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
33 return res;
34 }
35
36 /* B */
37 B = MIN(a->used, b->used) / 3;
38
39 /* a = a2 * B**2 + a1 * B + a0 */
40 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
41 goto ERR;
42 }
43
44 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
45 goto ERR;
46 }
47 mp_rshd(&a1, B);
48 mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
49
50 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
51 goto ERR;
52 }
53 mp_rshd(&a2, B*2);
54
55 /* b = b2 * B**2 + b1 * B + b0 */
56 if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
57 goto ERR;
58 }
59
60 if ((res = mp_copy(b, &b1)) != MP_OKAY) {
61 goto ERR;
62 }
63 mp_rshd(&b1, B);
64 mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
65
66 if ((res = mp_copy(b, &b2)) != MP_OKAY) {
67 goto ERR;
68 }
69 mp_rshd(&b2, B*2);
70
71 /* w0 = a0*b0 */
72 if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
73 goto ERR;
74 }
75
76 /* w4 = a2 * b2 */
77 if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
78 goto ERR;
79 }
80
81 /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
82 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
83 goto ERR;
84 }
85 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
86 goto ERR;
87 }
88 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
89 goto ERR;
90 }
91 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
92 goto ERR;
93 }
94
95 if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
96 goto ERR;
97 }
98 if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
99 goto ERR;
100 }
101 if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
102 goto ERR;
103 }
104 if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
105 goto ERR;
106 }
107
108 if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
109 goto ERR;
110 }
111
112 /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
113 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
114 goto ERR;
115 }
116 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
117 goto ERR;
118 }
119 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
120 goto ERR;
121 }
122 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
123 goto ERR;
124 }
125
126 if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
127 goto ERR;
128 }
129 if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
130 goto ERR;
131 }
132 if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
133 goto ERR;
134 }
135 if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
136 goto ERR;
137 }
138
139 if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
140 goto ERR;
141 }
142
143
144 /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
145 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
146 goto ERR;
147 }
148 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
149 goto ERR;
150 }
151 if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
152 goto ERR;
153 }
154 if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
155 goto ERR;
156 }
157 if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
158 goto ERR;
159 }
160
161 /* now solve the matrix
162
163 0 0 0 0 1
164 1 2 4 8 16
165 1 1 1 1 1
166 16 8 4 2 1
167 1 0 0 0 0
168
169 using 12 subtractions, 4 shifts,
170 2 small divisions and 1 small multiplication
171 */
172
173 /* r1 - r4 */
174 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
175 goto ERR;
176 }
177 /* r3 - r0 */
178 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
179 goto ERR;
180 }
181 /* r1/2 */
182 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
183 goto ERR;
184 }
185 /* r3/2 */
186 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
187 goto ERR;
188 }
189 /* r2 - r0 - r4 */
190 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
191 goto ERR;
192 }
193 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
194 goto ERR;
195 }
196 /* r1 - r2 */
197 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
198 goto ERR;
199 }
200 /* r3 - r2 */
201 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
202 goto ERR;
203 }
204 /* r1 - 8r0 */
205 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
206 goto ERR;
207 }
208 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
209 goto ERR;
210 }
211 /* r3 - 8r4 */
212 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
213 goto ERR;
214 }
215 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
216 goto ERR;
217 }
218 /* 3r2 - r1 - r3 */
219 if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
220 goto ERR;
221 }
222 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
223 goto ERR;
224 }
225 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
226 goto ERR;
227 }
228 /* r1 - r2 */
229 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
230 goto ERR;
231 }
232 /* r3 - r2 */
233 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
234 goto ERR;
235 }
236 /* r1/3 */
237 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
238 goto ERR;
239 }
240 /* r3/3 */
241 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
242 goto ERR;
243 }
244
245 /* at this point shift W[n] by B*n */
246 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
247 goto ERR;
248 }
249 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
250 goto ERR;
251 }
252 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
253 goto ERR;
254 }
255 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
256 goto ERR;
257 }
258
259 if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
260 goto ERR;
261 }
262 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
263 goto ERR;
264 }
265 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
266 goto ERR;
267 }
268 if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
269 goto ERR;
270 }
271
272 ERR:
273 mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
274 &a0, &a1, &a2, &b0, &b1,
275 &b2, &tmp1, &tmp2, NULL);
276 return res;
277 }
278
279 #endif
280
281 /* $Source$ */
282 /* $Revision$ */
283 /* $Date$ */
+0
-226
libtom-src/bn_mp_toom_sqr.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_TOOM_SQR_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 /* squaring using Toom-Cook 3-way algorithm */
18 int
19 mp_toom_sqr(mp_int *a, mp_int *b)
20 {
21 mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
22 int res, B;
23
24 /* init temps */
25 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
26 return res;
27 }
28
29 /* B */
30 B = a->used / 3;
31
32 /* a = a2 * B**2 + a1 * B + a0 */
33 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
34 goto ERR;
35 }
36
37 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
38 goto ERR;
39 }
40 mp_rshd(&a1, B);
41 mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
42
43 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
44 goto ERR;
45 }
46 mp_rshd(&a2, B*2);
47
48 /* w0 = a0*a0 */
49 if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
50 goto ERR;
51 }
52
53 /* w4 = a2 * a2 */
54 if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
55 goto ERR;
56 }
57
58 /* w1 = (a2 + 2(a1 + 2a0))**2 */
59 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
60 goto ERR;
61 }
62 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
63 goto ERR;
64 }
65 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
66 goto ERR;
67 }
68 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
69 goto ERR;
70 }
71
72 if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
73 goto ERR;
74 }
75
76 /* w3 = (a0 + 2(a1 + 2a2))**2 */
77 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
78 goto ERR;
79 }
80 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
81 goto ERR;
82 }
83 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
84 goto ERR;
85 }
86 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
87 goto ERR;
88 }
89
90 if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
91 goto ERR;
92 }
93
94
95 /* w2 = (a2 + a1 + a0)**2 */
96 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
97 goto ERR;
98 }
99 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
100 goto ERR;
101 }
102 if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
103 goto ERR;
104 }
105
106 /* now solve the matrix
107
108 0 0 0 0 1
109 1 2 4 8 16
110 1 1 1 1 1
111 16 8 4 2 1
112 1 0 0 0 0
113
114 using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
115 */
116
117 /* r1 - r4 */
118 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
119 goto ERR;
120 }
121 /* r3 - r0 */
122 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
123 goto ERR;
124 }
125 /* r1/2 */
126 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
127 goto ERR;
128 }
129 /* r3/2 */
130 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
131 goto ERR;
132 }
133 /* r2 - r0 - r4 */
134 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
135 goto ERR;
136 }
137 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
138 goto ERR;
139 }
140 /* r1 - r2 */
141 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
142 goto ERR;
143 }
144 /* r3 - r2 */
145 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
146 goto ERR;
147 }
148 /* r1 - 8r0 */
149 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
150 goto ERR;
151 }
152 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
153 goto ERR;
154 }
155 /* r3 - 8r4 */
156 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
157 goto ERR;
158 }
159 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
160 goto ERR;
161 }
162 /* 3r2 - r1 - r3 */
163 if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
164 goto ERR;
165 }
166 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
167 goto ERR;
168 }
169 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
170 goto ERR;
171 }
172 /* r1 - r2 */
173 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
174 goto ERR;
175 }
176 /* r3 - r2 */
177 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
178 goto ERR;
179 }
180 /* r1/3 */
181 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
182 goto ERR;
183 }
184 /* r3/3 */
185 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
186 goto ERR;
187 }
188
189 /* at this point shift W[n] by B*n */
190 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
191 goto ERR;
192 }
193 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
194 goto ERR;
195 }
196 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
197 goto ERR;
198 }
199 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
200 goto ERR;
201 }
202
203 if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
204 goto ERR;
205 }
206 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
207 goto ERR;
208 }
209 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
210 goto ERR;
211 }
212 if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
213 goto ERR;
214 }
215
216 ERR:
217 mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
218 return res;
219 }
220
221 #endif
222
223 /* $Source$ */
224 /* $Revision$ */
225 /* $Date$ */
+0
-75
libtom-src/bn_mp_toradix.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_TORADIX_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 /* stores a bignum as a ASCII string in a given radix (2..64) */
18 int mp_toradix (mp_int * a, char *str, int radix)
19 {
20 int res, digs;
21 mp_int t;
22 mp_digit d;
23 char *_s = str;
24
25 /* check range of the radix */
26 if (radix < 2 || radix > 64) {
27 return MP_VAL;
28 }
29
30 /* quick out if its zero */
31 if (mp_iszero(a) == 1) {
32 *str++ = '0';
33 *str = '\0';
34 return MP_OKAY;
35 }
36
37 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
38 return res;
39 }
40
41 /* if it is negative output a - */
42 if (t.sign == MP_NEG) {
43 ++_s;
44 *str++ = '-';
45 t.sign = MP_ZPOS;
46 }
47
48 digs = 0;
49 while (mp_iszero (&t) == 0) {
50 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
51 mp_clear (&t);
52 return res;
53 }
54 *str++ = mp_s_rmap[d];
55 ++digs;
56 }
57
58 /* reverse the digits of the string. In this case _s points
59 * to the first digit [exluding the sign] of the number]
60 */
61 bn_reverse ((unsigned char *)_s, digs);
62
63 /* append a NULL so the string is properly terminated */
64 *str = '\0';
65
66 mp_clear (&t);
67 return MP_OKAY;
68 }
69
70 #endif
71
72 /* $Source$ */
73 /* $Revision$ */
74 /* $Date$ */
+0
-88
libtom-src/bn_mp_toradix_n.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_TORADIX_N_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 /* stores a bignum as a ASCII string in a given radix (2..64)
18 *
19 * Stores upto maxlen-1 chars and always a NULL byte
20 */
21 int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
22 {
23 int res, digs;
24 mp_int t;
25 mp_digit d;
26 char *_s = str;
27
28 /* check range of the maxlen, radix */
29 if (maxlen < 2 || radix < 2 || radix > 64) {
30 return MP_VAL;
31 }
32
33 /* quick out if its zero */
34 if (mp_iszero(a) == MP_YES) {
35 *str++ = '0';
36 *str = '\0';
37 return MP_OKAY;
38 }
39
40 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
41 return res;
42 }
43
44 /* if it is negative output a - */
45 if (t.sign == MP_NEG) {
46 /* we have to reverse our digits later... but not the - sign!! */
47 ++_s;
48
49 /* store the flag and mark the number as positive */
50 *str++ = '-';
51 t.sign = MP_ZPOS;
52
53 /* subtract a char */
54 --maxlen;
55 }
56
57 digs = 0;
58 while (mp_iszero (&t) == 0) {
59 if (--maxlen < 1) {
60 /* no more room */
61 break;
62 }
63 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
64 mp_clear (&t);
65 return res;
66 }
67 *str++ = mp_s_rmap[d];
68 ++digs;
69 }
70
71 /* reverse the digits of the string. In this case _s points
72 * to the first digit [exluding the sign] of the number
73 */
74 bn_reverse ((unsigned char *)_s, digs);
75
76 /* append a NULL so the string is properly terminated */
77 *str = '\0';
78
79 mp_clear (&t);
80 return MP_OKAY;
81 }
82
83 #endif
84
85 /* $Source$ */
86 /* $Revision$ */
87 /* $Date$ */
+0
-28
libtom-src/bn_mp_unsigned_bin_size.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_UNSIGNED_BIN_SIZE_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 size for an unsigned equivalent */
18 int mp_unsigned_bin_size (mp_int * a)
19 {
20 int size = mp_count_bits (a);
21 return (size / 8 + ((size & 7) != 0 ? 1 : 0));
22 }
23 #endif
24
25 /* $Source$ */
26 /* $Revision$ */
27 /* $Date$ */
+0
-51
libtom-src/bn_mp_xor.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_XOR_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 /* XOR two ints together */
18 int
19 mp_xor (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int res, ix, px;
22 mp_int t, *x;
23
24 if (a->used > b->used) {
25 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
37
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] ^= x->dp[ix];
40 }
41 mp_clamp (&t);
42 mp_exch (c, &t);
43 mp_clear (&t);
44 return MP_OKAY;
45 }
46 #endif
47
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
+0
-36
libtom-src/bn_mp_zero.c less more
0 #include <tommath.h>
1 #ifdef BN_MP_ZERO_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 to zero */
18 void mp_zero (mp_int * a)
19 {
20 int n;
21 mp_digit *tmp;
22
23 a->sign = MP_ZPOS;
24 a->used = 0;
25
26 tmp = a->dp;
27 for (n = 0; n < a->alloc; n++) {
28 *tmp++ = 0;
29 }
30 }
31 #endif
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
+0
-61
libtom-src/bn_prime_tab.c less more
0 #include <tommath.h>
1 #ifdef BN_PRIME_TAB_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 const mp_digit ltm_prime_tab[] = {
17 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
18 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
19 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
20 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
21 #ifndef MP_8BIT
22 0x0083,
23 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
24 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
25 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
26 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
27
28 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
29 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
30 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
31 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
32 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
33 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
34 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
35 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
36
37 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
38 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
39 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
40 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
41 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
42 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
43 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
44 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
45
46 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
47 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
48 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
49 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
50 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
51 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
52 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
53 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
54 #endif
55 };
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
+0
-39
libtom-src/bn_reverse.c less more
0 #include <tommath.h>
1 #ifdef BN_REVERSE_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 /* reverse an array, used for radix code */
18 void
19 bn_reverse (unsigned char *s, int len)
20 {
21 int ix, iy;
22 unsigned char t;
23
24 ix = 0;
25 iy = len - 1;
26 while (ix < iy) {
27 t = s[ix];
28 s[ix] = s[iy];
29 s[iy] = t;
30 ++ix;
31 --iy;
32 }
33 }
34 #endif
35
36 /* $Source$ */
37 /* $Revision$ */
38 /* $Date$ */
+0
-109
libtom-src/bn_s_mp_add.c less more
0 #include <tommath.h>
1 #ifdef BN_S_MP_ADD_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 /* low level addition, based on HAC pp.594, Algorithm 14.7 */
18 int
19 s_mp_add (mp_int * a, mp_int * b, mp_int * c)
20 {
21 mp_int *x;
22 int olduse, res, min, max;
23
24 /* find sizes, we let |a| <= |b| which means we have to sort
25 * them. "x" will point to the input with the most digits
26 */
27 if (a->used > b->used) {
28 min = b->used;
29 max = a->used;
30 x = a;
31 } else {
32 min = a->used;
33 max = b->used;
34 x = b;
35 }
36
37 /* init result */
38 if (c->alloc < max + 1) {
39 if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
40 return res;
41 }
42 }
43
44 /* get old used digit count and set new one */
45 olduse = c->used;
46 c->used = max + 1;
47
48 {
49 register mp_digit u, *tmpa, *tmpb, *tmpc;
50 register int i;
51
52 /* alias for digit pointers */
53
54 /* first input */
55 tmpa = a->dp;
56
57 /* second input */
58 tmpb = b->dp;
59
60 /* destination */
61 tmpc = c->dp;
62
63 /* zero the carry */
64 u = 0;
65 for (i = 0; i < min; i++) {
66 /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
67 *tmpc = *tmpa++ + *tmpb++ + u;
68
69 /* U = carry bit of T[i] */
70 u = *tmpc >> ((mp_digit)DIGIT_BIT);
71
72 /* take away carry bit from T[i] */
73 *tmpc++ &= MP_MASK;
74 }
75
76 /* now copy higher words if any, that is in A+B
77 * if A or B has more digits add those in
78 */
79 if (min != max) {
80 for (; i < max; i++) {
81 /* T[i] = X[i] + U */
82 *tmpc = x->dp[i] + u;
83
84 /* U = carry bit of T[i] */
85 u = *tmpc >> ((mp_digit)DIGIT_BIT);
86
87 /* take away carry bit from T[i] */
88 *tmpc++ &= MP_MASK;
89 }
90 }
91
92 /* add carry */
93 *tmpc++ = u;
94
95 /* clear digits above oldused */
96 for (i = c->used; i < olduse; i++) {
97 *tmpc++ = 0;
98 }
99 }
100
101 mp_clamp (c);
102 return MP_OKAY;
103 }
104 #endif
105
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
+0
-252
libtom-src/bn_s_mp_exptmod.c less more
0 #include <tommath.h>
1 #ifdef BN_S_MP_EXPTMOD_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 #ifdef MP_LOW_MEM
17 #define TAB_SIZE 32
18 #else
19 #define TAB_SIZE 256
20 #endif
21
22 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
23 {
24 mp_int M[TAB_SIZE], res, mu;
25 mp_digit buf;
26 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
27 int (*redux)(mp_int*,mp_int*,mp_int*);
28
29 /* find window size */
30 x = mp_count_bits (X);
31 if (x <= 7) {
32 winsize = 2;
33 } else if (x <= 36) {
34 winsize = 3;
35 } else if (x <= 140) {
36 winsize = 4;
37 } else if (x <= 450) {
38 winsize = 5;
39 } else if (x <= 1303) {
40 winsize = 6;
41 } else if (x <= 3529) {
42 winsize = 7;
43 } else {
44 winsize = 8;
45 }
46
47 #ifdef MP_LOW_MEM
48 if (winsize > 5) {
49 winsize = 5;
50 }
51 #endif
52
53 /* init M array */
54 /* init first cell */
55 if ((err = mp_init(&M[1])) != MP_OKAY) {
56 return err;
57 }
58
59 /* now init the second half of the array */
60 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
61 if ((err = mp_init(&M[x])) != MP_OKAY) {
62 for (y = 1<<(winsize-1); y < x; y++) {
63 mp_clear (&M[y]);
64 }
65 mp_clear(&M[1]);
66 return err;
67 }
68 }
69
70 /* create mu, used for Barrett reduction */
71 if ((err = mp_init (&mu)) != MP_OKAY) {
72 goto LBL_M;
73 }
74
75 if (redmode == 0) {
76 if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
77 goto LBL_MU;
78 }
79 redux = mp_reduce;
80 } else {
81 if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
82 goto LBL_MU;
83 }
84 redux = mp_reduce_2k_l;
85 }
86
87 /* create M table
88 *
89 * The M table contains powers of the base,
90 * e.g. M[x] = G**x mod P
91 *
92 * The first half of the table is not
93 * computed though accept for M[0] and M[1]
94 */
95 if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
96 goto LBL_MU;
97 }
98
99 /* compute the value at M[1<<(winsize-1)] by squaring
100 * M[1] (winsize-1) times
101 */
102 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
103 goto LBL_MU;
104 }
105
106 for (x = 0; x < (winsize - 1); x++) {
107 /* square it */
108 if ((err = mp_sqr (&M[1 << (winsize - 1)],
109 &M[1 << (winsize - 1)])) != MP_OKAY) {
110 goto LBL_MU;
111 }
112
113 /* reduce modulo P */
114 if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
115 goto LBL_MU;
116 }
117 }
118
119 /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
120 * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
121 */
122 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
123 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
124 goto LBL_MU;
125 }
126 if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
127 goto LBL_MU;
128 }
129 }
130
131 /* setup result */
132 if ((err = mp_init (&res)) != MP_OKAY) {
133 goto LBL_MU;
134 }
135 mp_set (&res, 1);
136
137 /* set initial mode and bit cnt */
138 mode = 0;
139 bitcnt = 1;
140 buf = 0;
141 digidx = X->used - 1;
142 bitcpy = 0;
143 bitbuf = 0;
144
145 for (;;) {
146 /* grab next digit as required */
147 if (--bitcnt == 0) {
148 /* if digidx == -1 we are out of digits */
149 if (digidx == -1) {
150 break;
151 }
152 /* read next digit and reset the bitcnt */
153 buf = X->dp[digidx--];
154 bitcnt = (int) DIGIT_BIT;
155 }
156
157 /* grab the next msb from the exponent */
158 y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
159 buf <<= (mp_digit)1;
160
161 /* if the bit is zero and mode == 0 then we ignore it
162 * These represent the leading zero bits before the first 1 bit
163 * in the exponent. Technically this opt is not required but it
164 * does lower the # of trivial squaring/reductions used
165 */
166 if (mode == 0 && y == 0) {
167 continue;
168 }
169
170 /* if the bit is zero and mode == 1 then we square */
171 if (mode == 1 && y == 0) {
172 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
173 goto LBL_RES;
174 }
175 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
176 goto LBL_RES;
177 }
178 continue;
179 }
180
181 /* else we add it to the window */
182 bitbuf |= (y << (winsize - ++bitcpy));
183 mode = 2;
184
185 if (bitcpy == winsize) {
186 /* ok window is filled so square as required and multiply */
187 /* square first */
188 for (x = 0; x < winsize; x++) {
189 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
190 goto LBL_RES;
191 }
192 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
193 goto LBL_RES;
194 }
195 }
196
197 /* then multiply */
198 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
199 goto LBL_RES;
200 }
201 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
202 goto LBL_RES;
203 }
204
205 /* empty window and reset */
206 bitcpy = 0;
207 bitbuf = 0;
208 mode = 1;
209 }
210 }
211
212 /* if bits remain then square/multiply */
213 if (mode == 2 && bitcpy > 0) {
214 /* square then multiply if the bit is set */
215 for (x = 0; x < bitcpy; x++) {
216 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
217 goto LBL_RES;
218 }
219 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
220 goto LBL_RES;
221 }
222
223 bitbuf <<= 1;
224 if ((bitbuf & (1 << winsize)) != 0) {
225 /* then multiply */
226 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
227 goto LBL_RES;
228 }
229 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
230 goto LBL_RES;
231 }
232 }
233 }
234 }
235
236 mp_exch (&res, Y);
237 err = MP_OKAY;
238 LBL_RES:mp_clear (&res);
239 LBL_MU:mp_clear (&mu);
240 LBL_M:
241 mp_clear(&M[1]);
242 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
243 mp_clear (&M[x]);
244 }
245 return err;
246 }
247 #endif
248
249 /* $Source$ */
250 /* $Revision$ */
251 /* $Date$ */
+0
-90
libtom-src/bn_s_mp_mul_digs.c less more
0 #include <tommath.h>
1 #ifdef BN_S_MP_MUL_DIGS_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 /* multiplies |a| * |b| and only computes upto digs digits of result
18 * HAC pp. 595, Algorithm 14.12 Modified so you can control how
19 * many digits of output are created.
20 */
21 int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
22 {
23 mp_int t;
24 int res, pa, pb, ix, iy;
25 mp_digit u;
26 mp_word r;
27 mp_digit tmpx, *tmpt, *tmpy;
28
29 /* can we use the fast multiplier? */
30 if (((digs) < MP_WARRAY) &&
31 MIN (a->used, b->used) <
32 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
33 return fast_s_mp_mul_digs (a, b, c, digs);
34 }
35
36 if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
37 return res;
38 }
39 t.used = digs;
40
41 /* compute the digits of the product directly */
42 pa = a->used;
43 for (ix = 0; ix < pa; ix++) {
44 /* set the carry to zero */
45 u = 0;
46
47 /* limit ourselves to making digs digits of output */
48 pb = MIN (b->used, digs - ix);
49
50 /* setup some aliases */
51 /* copy of the digit from a used within the nested loop */
52 tmpx = a->dp[ix];
53
54 /* an alias for the destination shifted ix places */
55 tmpt = t.dp + ix;
56
57 /* an alias for the digits of b */
58 tmpy = b->dp;
59
60 /* compute the columns of the output and propagate the carry */
61 for (iy = 0; iy < pb; iy++) {
62 /* compute the column as a mp_word */
63 r = ((mp_word)*tmpt) +
64 ((mp_word)tmpx) * ((mp_word)*tmpy++) +
65 ((mp_word) u);
66
67 /* the new column is the lower part of the result */
68 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
69
70 /* get the carry word from the result */
71 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
72 }
73 /* set carry if it is placed below digs */
74 if (ix + iy < digs) {
75 *tmpt = u;
76 }
77 }
78
79 mp_clamp (&t);
80 mp_exch (&t, c);
81
82 mp_clear (&t);
83 return MP_OKAY;
84 }
85 #endif
86
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
+0
-81
libtom-src/bn_s_mp_mul_high_digs.c less more
0 #include <tommath.h>
1 #ifdef BN_S_MP_MUL_HIGH_DIGS_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 /* multiplies |a| * |b| and does not compute the lower digs digits
18 * [meant to get the higher part of the product]
19 */
20 int
21 s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
22 {
23 mp_int t;
24 int res, pa, pb, ix, iy;
25 mp_digit u;
26 mp_word r;
27 mp_digit tmpx, *tmpt, *tmpy;
28
29 /* can we use the fast multiplier? */
30 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
31 if (((a->used + b->used + 1) < MP_WARRAY)
32 && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
33 return fast_s_mp_mul_high_digs (a, b, c, digs);
34 }
35 #endif
36
37 if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
38 return res;
39 }
40 t.used = a->used + b->used + 1;
41
42 pa = a->used;
43 pb = b->used;
44 for (ix = 0; ix < pa; ix++) {
45 /* clear the carry */
46 u = 0;
47
48 /* left hand side of A[ix] * B[iy] */
49 tmpx = a->dp[ix];
50
51 /* alias to the address of where the digits will be stored */
52 tmpt = &(t.dp[digs]);
53
54 /* alias for where to read the right hand side from */
55 tmpy = b->dp + (digs - ix);
56
57 for (iy = digs - ix; iy < pb; iy++) {
58 /* calculate the double precision result */
59 r = ((mp_word)*tmpt) +
60 ((mp_word)tmpx) * ((mp_word)*tmpy++) +
61 ((mp_word) u);
62
63 /* get the lower part */
64 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
65
66 /* carry the carry */
67 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
68 }
69 *tmpt = u;
70 }
71 mp_clamp (&t);
72 mp_exch (&t, c);
73 mp_clear (&t);
74 return MP_OKAY;
75 }
76 #endif
77
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
+0
-84
libtom-src/bn_s_mp_sqr.c less more
0 #include <tommath.h>
1 #ifdef BN_S_MP_SQR_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 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
18 int s_mp_sqr (mp_int * a, mp_int * b)
19 {
20 mp_int t;
21 int res, ix, iy, pa;
22 mp_word r;
23 mp_digit u, tmpx, *tmpt;
24
25 pa = a->used;
26 if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
27 return res;
28 }
29
30 /* default used is maximum possible size */
31 t.used = 2*pa + 1;
32
33 for (ix = 0; ix < pa; ix++) {
34 /* first calculate the digit at 2*ix */
35 /* calculate double precision result */
36 r = ((mp_word) t.dp[2*ix]) +
37 ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
38
39 /* store lower part in result */
40 t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
41
42 /* get the carry */
43 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
44
45 /* left hand side of A[ix] * A[iy] */
46 tmpx = a->dp[ix];
47
48 /* alias for where to store the results */
49 tmpt = t.dp + (2*ix + 1);
50
51 for (iy = ix + 1; iy < pa; iy++) {
52 /* first calculate the product */
53 r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
54
55 /* now calculate the double precision result, note we use
56 * addition instead of *2 since it's easier to optimize
57 */
58 r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
59
60 /* store lower part */
61 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
62
63 /* get carry */
64 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
65 }
66 /* propagate upwards */
67 while (u != ((mp_digit) 0)) {
68 r = ((mp_word) *tmpt) + ((mp_word) u);
69 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
70 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
71 }
72 }
73
74 mp_clamp (&t);
75 mp_exch (&t, b);
76 mp_clear (&t);
77 return MP_OKAY;
78 }
79 #endif
80
81 /* $Source$ */
82 /* $Revision$ */
83 /* $Date$ */
+0
-89
libtom-src/bn_s_mp_sub.c less more
0 #include <tommath.h>
1 #ifdef BN_S_MP_SUB_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 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
18 int
19 s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int olduse, res, min, max;
22
23 /* find sizes */
24 min = b->used;
25 max = a->used;
26
27 /* init result */
28 if (c->alloc < max) {
29 if ((res = mp_grow (c, max)) != MP_OKAY) {
30 return res;
31 }
32 }
33 olduse = c->used;
34 c->used = max;
35
36 {
37 register mp_digit u, *tmpa, *tmpb, *tmpc;
38 register int i;
39
40 /* alias for digit pointers */
41 tmpa = a->dp;
42 tmpb = b->dp;
43 tmpc = c->dp;
44
45 /* set carry to zero */
46 u = 0;
47 for (i = 0; i < min; i++) {
48 /* T[i] = A[i] - B[i] - U */
49 *tmpc = *tmpa++ - *tmpb++ - u;
50
51 /* U = carry bit of T[i]
52 * Note this saves performing an AND operation since
53 * if a carry does occur it will propagate all the way to the
54 * MSB. As a result a single shift is enough to get the carry
55 */
56 u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
57
58 /* Clear carry from T[i] */
59 *tmpc++ &= MP_MASK;
60 }
61
62 /* now copy higher words if any, e.g. if A has more digits than B */
63 for (; i < max; i++) {
64 /* T[i] = A[i] - U */
65 *tmpc = *tmpa++ - u;
66
67 /* U = carry bit of T[i] */
68 u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
69
70 /* Clear carry from T[i] */
71 *tmpc++ &= MP_MASK;
72 }
73
74 /* clear digits above used (since we may not have grown result above) */
75 for (i = c->used; i < olduse; i++) {
76 *tmpc++ = 0;
77 }
78 }
79
80 mp_clamp (c);
81 return MP_OKAY;
82 }
83
84 #endif
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
+0
-36
libtom-src/bncore.c less more
0 #include <tommath.h>
1 #ifdef BNCORE_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 /* Known optimal configurations
18
19 CPU /Compiler /MUL CUTOFF/SQR CUTOFF
20 -------------------------------------------------------------
21 Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-)
22 AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35
23
24 */
25
26 int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */
27 KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */
28
29 TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
30 TOOM_SQR_CUTOFF = 400;
31 #endif
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
+0
-760
libtom-src/ciphers/aes/aes.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* AES implementation by Tom St Denis
12 *
13 * Derived from the Public Domain source code by
14
15 ---
16 * rijndael-alg-fst.c
17 *
18 * @version 3.0 (December 2000)
19 *
20 * Optimised ANSI C code for the Rijndael cipher (now AES)
21 *
22 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
23 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
24 * @author Paulo Barreto <paulo.barreto@terra.com.br>
25 ---
26 */
27 /**
28 @file aes.c
29 Implementation of AES
30 */
31
32 #include "tomcrypt.h"
33
34 #ifdef LTC_RIJNDAEL
35
36 #ifndef ENCRYPT_ONLY
37
38 #define SETUP rijndael_setup
39 #define ECB_ENC rijndael_ecb_encrypt
40 #define ECB_DEC rijndael_ecb_decrypt
41 #define ECB_DONE rijndael_done
42 #define ECB_TEST rijndael_test
43 #define ECB_KS rijndael_keysize
44
45 const struct ltc_cipher_descriptor rijndael_desc =
46 {
47 "rijndael",
48 6,
49 16, 32, 16, 10,
50 SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
51 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
52 };
53
54 const struct ltc_cipher_descriptor aes_desc =
55 {
56 "aes",
57 6,
58 16, 32, 16, 10,
59 SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
60 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
61 };
62
63 #else
64
65 #define SETUP rijndael_enc_setup
66 #define ECB_ENC rijndael_enc_ecb_encrypt
67 #define ECB_KS rijndael_enc_keysize
68 #define ECB_DONE rijndael_enc_done
69
70 const struct ltc_cipher_descriptor rijndael_enc_desc =
71 {
72 "rijndael",
73 6,
74 16, 32, 16, 10,
75 SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
76 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
77 };
78
79 const struct ltc_cipher_descriptor aes_enc_desc =
80 {
81 "aes",
82 6,
83 16, 32, 16, 10,
84 SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
85 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
86 };
87
88 #endif
89
90 #include "aes_tab.c.inc"
91
92 static ulong32 setup_mix(ulong32 temp)
93 {
94 return (Te4_3[byte(temp, 2)]) ^
95 (Te4_2[byte(temp, 1)]) ^
96 (Te4_1[byte(temp, 0)]) ^
97 (Te4_0[byte(temp, 3)]);
98 }
99
100 #ifndef ENCRYPT_ONLY
101 #ifdef LTC_SMALL_CODE
102 static ulong32 setup_mix2(ulong32 temp)
103 {
104 return Td0(255 & Te4[byte(temp, 3)]) ^
105 Td1(255 & Te4[byte(temp, 2)]) ^
106 Td2(255 & Te4[byte(temp, 1)]) ^
107 Td3(255 & Te4[byte(temp, 0)]);
108 }
109 #endif
110 #endif
111
112 /**
113 Initialize the AES (Rijndael) block cipher
114 @param key The symmetric key you wish to pass
115 @param keylen The key length in bytes
116 @param num_rounds The number of rounds desired (0 for default)
117 @param skey The key in as scheduled by this function.
118 @return CRYPT_OK if successful
119 */
120 int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
121 {
122 int i, j;
123 ulong32 temp, *rk;
124 #ifndef ENCRYPT_ONLY
125 ulong32 *rrk;
126 #endif
127 LTC_ARGCHK(key != NULL);
128 LTC_ARGCHK(skey != NULL);
129
130 if (keylen != 16 && keylen != 24 && keylen != 32) {
131 return CRYPT_INVALID_KEYSIZE;
132 }
133
134 if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) {
135 return CRYPT_INVALID_ROUNDS;
136 }
137
138 skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
139
140 /* setup the forward key */
141 i = 0;
142 rk = skey->rijndael.eK;
143 LOAD32H(rk[0], key );
144 LOAD32H(rk[1], key + 4);
145 LOAD32H(rk[2], key + 8);
146 LOAD32H(rk[3], key + 12);
147 if (keylen == 16) {
148 j = 44;
149 for (;;) {
150 temp = rk[3];
151 rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
152 rk[5] = rk[1] ^ rk[4];
153 rk[6] = rk[2] ^ rk[5];
154 rk[7] = rk[3] ^ rk[6];
155 if (++i == 10) {
156 break;
157 }
158 rk += 4;
159 }
160 } else if (keylen == 24) {
161 j = 52;
162 LOAD32H(rk[4], key + 16);
163 LOAD32H(rk[5], key + 20);
164 for (;;) {
165 #ifdef _MSC_VER
166 temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
167 #else
168 temp = rk[5];
169 #endif
170 rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
171 rk[ 7] = rk[ 1] ^ rk[ 6];
172 rk[ 8] = rk[ 2] ^ rk[ 7];
173 rk[ 9] = rk[ 3] ^ rk[ 8];
174 if (++i == 8) {
175 break;
176 }
177 rk[10] = rk[ 4] ^ rk[ 9];
178 rk[11] = rk[ 5] ^ rk[10];
179 rk += 6;
180 }
181 } else if (keylen == 32) {
182 j = 60;
183 LOAD32H(rk[4], key + 16);
184 LOAD32H(rk[5], key + 20);
185 LOAD32H(rk[6], key + 24);
186 LOAD32H(rk[7], key + 28);
187 for (;;) {
188 #ifdef _MSC_VER
189 temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
190 #else
191 temp = rk[7];
192 #endif
193 rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
194 rk[ 9] = rk[ 1] ^ rk[ 8];
195 rk[10] = rk[ 2] ^ rk[ 9];
196 rk[11] = rk[ 3] ^ rk[10];
197 if (++i == 7) {
198 break;
199 }
200 temp = rk[11];
201 rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8));
202 rk[13] = rk[ 5] ^ rk[12];
203 rk[14] = rk[ 6] ^ rk[13];
204 rk[15] = rk[ 7] ^ rk[14];
205 rk += 8;
206 }
207 } else {
208 /* this can't happen */
209 return CRYPT_ERROR;
210 }
211
212 #ifndef ENCRYPT_ONLY
213 /* setup the inverse key now */
214 rk = skey->rijndael.dK;
215 rrk = skey->rijndael.eK + j - 4;
216
217 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
218 /* copy first */
219 *rk++ = *rrk++;
220 *rk++ = *rrk++;
221 *rk++ = *rrk++;
222 *rk = *rrk;
223 rk -= 3; rrk -= 3;
224
225 for (i = 1; i < skey->rijndael.Nr; i++) {
226 rrk -= 4;
227 rk += 4;
228 #ifdef LTC_SMALL_CODE
229 temp = rrk[0];
230 rk[0] = setup_mix2(temp);
231 temp = rrk[1];
232 rk[1] = setup_mix2(temp);
233 temp = rrk[2];
234 rk[2] = setup_mix2(temp);
235 temp = rrk[3];
236 rk[3] = setup_mix2(temp);
237 #else
238 temp = rrk[0];
239 rk[0] =
240 Tks0[byte(temp, 3)] ^
241 Tks1[byte(temp, 2)] ^
242 Tks2[byte(temp, 1)] ^
243 Tks3[byte(temp, 0)];
244 temp = rrk[1];
245 rk[1] =
246 Tks0[byte(temp, 3)] ^
247 Tks1[byte(temp, 2)] ^
248 Tks2[byte(temp, 1)] ^
249 Tks3[byte(temp, 0)];
250 temp = rrk[2];
251 rk[2] =
252 Tks0[byte(temp, 3)] ^
253 Tks1[byte(temp, 2)] ^
254 Tks2[byte(temp, 1)] ^
255 Tks3[byte(temp, 0)];
256 temp = rrk[3];
257 rk[3] =
258 Tks0[byte(temp, 3)] ^
259 Tks1[byte(temp, 2)] ^
260 Tks2[byte(temp, 1)] ^
261 Tks3[byte(temp, 0)];
262 #endif
263
264 }
265
266 /* copy last */
267 rrk -= 4;
268 rk += 4;
269 *rk++ = *rrk++;
270 *rk++ = *rrk++;
271 *rk++ = *rrk++;
272 *rk = *rrk;
273 #endif /* ENCRYPT_ONLY */
274
275 return CRYPT_OK;
276 }
277
278 /**
279 Encrypts a block of text with AES
280 @param pt The input plaintext (16 bytes)
281 @param ct The output ciphertext (16 bytes)
282 @param skey The key as scheduled
283 @return CRYPT_OK if successful
284 */
285 #ifdef LTC_CLEAN_STACK
286 static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
287 #else
288 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
289 #endif
290 {
291 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
292 int Nr, r;
293
294 LTC_ARGCHK(pt != NULL);
295 LTC_ARGCHK(ct != NULL);
296 LTC_ARGCHK(skey != NULL);
297
298 Nr = skey->rijndael.Nr;
299 rk = skey->rijndael.eK;
300
301 /*
302 * map byte array block to cipher state
303 * and add initial round key:
304 */
305 LOAD32H(s0, pt ); s0 ^= rk[0];
306 LOAD32H(s1, pt + 4); s1 ^= rk[1];
307 LOAD32H(s2, pt + 8); s2 ^= rk[2];
308 LOAD32H(s3, pt + 12); s3 ^= rk[3];
309
310 #ifdef LTC_SMALL_CODE
311
312 for (r = 0; ; r++) {
313 rk += 4;
314 t0 =
315 Te0(byte(s0, 3)) ^
316 Te1(byte(s1, 2)) ^
317 Te2(byte(s2, 1)) ^
318 Te3(byte(s3, 0)) ^
319 rk[0];
320 t1 =
321 Te0(byte(s1, 3)) ^
322 Te1(byte(s2, 2)) ^
323 Te2(byte(s3, 1)) ^
324 Te3(byte(s0, 0)) ^
325 rk[1];
326 t2 =
327 Te0(byte(s2, 3)) ^
328 Te1(byte(s3, 2)) ^
329 Te2(byte(s0, 1)) ^
330 Te3(byte(s1, 0)) ^
331 rk[2];
332 t3 =
333 Te0(byte(s3, 3)) ^
334 Te1(byte(s0, 2)) ^
335 Te2(byte(s1, 1)) ^
336 Te3(byte(s2, 0)) ^
337 rk[3];
338 if (r == Nr-2) {
339 break;
340 }
341 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
342 }
343 rk += 4;
344
345 #else
346
347 /*
348 * Nr - 1 full rounds:
349 */
350 r = Nr >> 1;
351 for (;;) {
352 t0 =
353 Te0(byte(s0, 3)) ^
354 Te1(byte(s1, 2)) ^
355 Te2(byte(s2, 1)) ^
356 Te3(byte(s3, 0)) ^
357 rk[4];
358 t1 =
359 Te0(byte(s1, 3)) ^
360 Te1(byte(s2, 2)) ^
361 Te2(byte(s3, 1)) ^
362 Te3(byte(s0, 0)) ^
363 rk[5];
364 t2 =
365 Te0(byte(s2, 3)) ^
366 Te1(byte(s3, 2)) ^
367 Te2(byte(s0, 1)) ^
368 Te3(byte(s1, 0)) ^
369 rk[6];
370 t3 =
371 Te0(byte(s3, 3)) ^
372 Te1(byte(s0, 2)) ^
373 Te2(byte(s1, 1)) ^
374 Te3(byte(s2, 0)) ^
375 rk[7];
376
377 rk += 8;
378 if (--r == 0) {
379 break;
380 }
381
382 s0 =
383 Te0(byte(t0, 3)) ^
384 Te1(byte(t1, 2)) ^
385 Te2(byte(t2, 1)) ^
386 Te3(byte(t3, 0)) ^
387 rk[0];
388 s1 =
389 Te0(byte(t1, 3)) ^
390 Te1(byte(t2, 2)) ^
391 Te2(byte(t3, 1)) ^
392 Te3(byte(t0, 0)) ^
393 rk[1];
394 s2 =
395 Te0(byte(t2, 3)) ^
396 Te1(byte(t3, 2)) ^
397 Te2(byte(t0, 1)) ^
398 Te3(byte(t1, 0)) ^
399 rk[2];
400 s3 =
401 Te0(byte(t3, 3)) ^
402 Te1(byte(t0, 2)) ^
403 Te2(byte(t1, 1)) ^
404 Te3(byte(t2, 0)) ^
405 rk[3];
406 }
407
408 #endif
409
410 /*
411 * apply last round and
412 * map cipher state to byte array block:
413 */
414 s0 =
415 (Te4_3[byte(t0, 3)]) ^
416 (Te4_2[byte(t1, 2)]) ^
417 (Te4_1[byte(t2, 1)]) ^
418 (Te4_0[byte(t3, 0)]) ^
419 rk[0];
420 STORE32H(s0, ct);
421 s1 =
422 (Te4_3[byte(t1, 3)]) ^
423 (Te4_2[byte(t2, 2)]) ^
424 (Te4_1[byte(t3, 1)]) ^
425 (Te4_0[byte(t0, 0)]) ^
426 rk[1];
427 STORE32H(s1, ct+4);
428 s2 =
429 (Te4_3[byte(t2, 3)]) ^
430 (Te4_2[byte(t3, 2)]) ^
431 (Te4_1[byte(t0, 1)]) ^
432 (Te4_0[byte(t1, 0)]) ^
433 rk[2];
434 STORE32H(s2, ct+8);
435 s3 =
436 (Te4_3[byte(t3, 3)]) ^
437 (Te4_2[byte(t0, 2)]) ^
438 (Te4_1[byte(t1, 1)]) ^
439 (Te4_0[byte(t2, 0)]) ^
440 rk[3];
441 STORE32H(s3, ct+12);
442
443 return CRYPT_OK;
444 }
445
446 #ifdef LTC_CLEAN_STACK
447 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
448 {
449 int err = _rijndael_ecb_encrypt(pt, ct, skey);
450 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
451 return err;
452 }
453 #endif
454
455 #ifndef ENCRYPT_ONLY
456
457 /**
458 Decrypts a block of text with AES
459 @param ct The input ciphertext (16 bytes)
460 @param pt The output plaintext (16 bytes)
461 @param skey The key as scheduled
462 @return CRYPT_OK if successful
463 */
464 #ifdef LTC_CLEAN_STACK
465 static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
466 #else
467 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
468 #endif
469 {
470 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
471 int Nr, r;
472
473 LTC_ARGCHK(pt != NULL);
474 LTC_ARGCHK(ct != NULL);
475 LTC_ARGCHK(skey != NULL);
476
477 Nr = skey->rijndael.Nr;
478 rk = skey->rijndael.dK;
479
480 /*
481 * map byte array block to cipher state
482 * and add initial round key:
483 */
484 LOAD32H(s0, ct ); s0 ^= rk[0];
485 LOAD32H(s1, ct + 4); s1 ^= rk[1];
486 LOAD32H(s2, ct + 8); s2 ^= rk[2];
487 LOAD32H(s3, ct + 12); s3 ^= rk[3];
488
489 #ifdef LTC_SMALL_CODE
490 for (r = 0; ; r++) {
491 rk += 4;
492 t0 =
493 Td0(byte(s0, 3)) ^
494 Td1(byte(s3, 2)) ^
495 Td2(byte(s2, 1)) ^
496 Td3(byte(s1, 0)) ^
497 rk[0];
498 t1 =
499 Td0(byte(s1, 3)) ^
500 Td1(byte(s0, 2)) ^
501 Td2(byte(s3, 1)) ^
502 Td3(byte(s2, 0)) ^
503 rk[1];
504 t2 =
505 Td0(byte(s2, 3)) ^
506 Td1(byte(s1, 2)) ^
507 Td2(byte(s0, 1)) ^
508 Td3(byte(s3, 0)) ^
509 rk[2];
510 t3 =
511 Td0(byte(s3, 3)) ^
512 Td1(byte(s2, 2)) ^
513 Td2(byte(s1, 1)) ^
514 Td3(byte(s0, 0)) ^
515 rk[3];
516 if (r == Nr-2) {
517 break;
518 }
519 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
520 }
521 rk += 4;
522
523 #else
524
525 /*
526 * Nr - 1 full rounds:
527 */
528 r = Nr >> 1;
529 for (;;) {
530
531 t0 =
532 Td0(byte(s0, 3)) ^
533 Td1(byte(s3, 2)) ^
534 Td2(byte(s2, 1)) ^
535 Td3(byte(s1, 0)) ^
536 rk[4];
537 t1 =
538 Td0(byte(s1, 3)) ^
539 Td1(byte(s0, 2)) ^
540 Td2(byte(s3, 1)) ^
541 Td3(byte(s2, 0)) ^
542 rk[5];
543 t2 =
544 Td0(byte(s2, 3)) ^
545 Td1(byte(s1, 2)) ^
546 Td2(byte(s0, 1)) ^
547 Td3(byte(s3, 0)) ^
548 rk[6];
549 t3 =
550 Td0(byte(s3, 3)) ^
551 Td1(byte(s2, 2)) ^
552 Td2(byte(s1, 1)) ^
553 Td3(byte(s0, 0)) ^
554 rk[7];
555
556 rk += 8;
557 if (--r == 0) {
558 break;
559 }
560
561
562 s0 =
563 Td0(byte(t0, 3)) ^
564 Td1(byte(t3, 2)) ^
565 Td2(byte(t2, 1)) ^
566 Td3(byte(t1, 0)) ^
567 rk[0];
568 s1 =
569 Td0(byte(t1, 3)) ^
570 Td1(byte(t0, 2)) ^
571 Td2(byte(t3, 1)) ^
572 Td3(byte(t2, 0)) ^
573 rk[1];
574 s2 =
575 Td0(byte(t2, 3)) ^
576 Td1(byte(t1, 2)) ^
577 Td2(byte(t0, 1)) ^
578 Td3(byte(t3, 0)) ^
579 rk[2];
580 s3 =
581 Td0(byte(t3, 3)) ^
582 Td1(byte(t2, 2)) ^
583 Td2(byte(t1, 1)) ^
584 Td3(byte(t0, 0)) ^
585 rk[3];
586 }
587 #endif
588
589 /*
590 * apply last round and
591 * map cipher state to byte array block:
592 */
593 s0 =
594 (Td4[byte(t0, 3)] & 0xff000000) ^
595 (Td4[byte(t3, 2)] & 0x00ff0000) ^
596 (Td4[byte(t2, 1)] & 0x0000ff00) ^
597 (Td4[byte(t1, 0)] & 0x000000ff) ^
598 rk[0];
599 STORE32H(s0, pt);
600 s1 =
601 (Td4[byte(t1, 3)] & 0xff000000) ^
602 (Td4[byte(t0, 2)] & 0x00ff0000) ^
603 (Td4[byte(t3, 1)] & 0x0000ff00) ^
604 (Td4[byte(t2, 0)] & 0x000000ff) ^
605 rk[1];
606 STORE32H(s1, pt+4);
607 s2 =
608 (Td4[byte(t2, 3)] & 0xff000000) ^
609 (Td4[byte(t1, 2)] & 0x00ff0000) ^
610 (Td4[byte(t0, 1)] & 0x0000ff00) ^
611 (Td4[byte(t3, 0)] & 0x000000ff) ^
612 rk[2];
613 STORE32H(s2, pt+8);
614 s3 =
615 (Td4[byte(t3, 3)] & 0xff000000) ^
616 (Td4[byte(t2, 2)] & 0x00ff0000) ^
617 (Td4[byte(t1, 1)] & 0x0000ff00) ^
618 (Td4[byte(t0, 0)] & 0x000000ff) ^
619 rk[3];
620 STORE32H(s3, pt+12);
621
622 return CRYPT_OK;
623 }
624
625
626 #ifdef LTC_CLEAN_STACK
627 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
628 {
629 int err = _rijndael_ecb_decrypt(ct, pt, skey);
630 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
631 return err;
632 }
633 #endif
634
635 /**
636 Performs a self-test of the AES block cipher
637 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
638 */
639 int ECB_TEST(void)
640 {
641 #ifndef LTC_TEST
642 return CRYPT_NOP;
643 #else
644 int err;
645 static const struct {
646 int keylen;
647 unsigned char key[32], pt[16], ct[16];
648 } tests[] = {
649 { 16,
650 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
651 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
652 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
653 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
654 { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
655 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
656 }, {
657 24,
658 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
659 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
660 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
661 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
662 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
663 { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
664 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
665 }, {
666 32,
667 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
668 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
669 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
670 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
671 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
672 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
673 { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
674 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
675 }
676 };
677
678 symmetric_key key;
679 unsigned char tmp[2][16];
680 int i, y;
681
682 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
683 zeromem(&key, sizeof(key));
684 if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
685 return err;
686 }
687
688 rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
689 rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
690 if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
691 #if 0
692 printf("\n\nTest %d failed\n", i);
693 if (XMEMCMP(tmp[0], tests[i].ct, 16)) {
694 printf("CT: ");
695 for (i = 0; i < 16; i++) {
696 printf("%02x ", tmp[0][i]);
697 }
698 printf("\n");
699 } else {
700 printf("PT: ");
701 for (i = 0; i < 16; i++) {
702 printf("%02x ", tmp[1][i]);
703 }
704 printf("\n");
705 }
706 #endif
707 return CRYPT_FAIL_TESTVECTOR;
708 }
709
710 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
711 for (y = 0; y < 16; y++) tmp[0][y] = 0;
712 for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
713 for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
714 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
715 }
716 return CRYPT_OK;
717 #endif
718 }
719
720 #endif /* ENCRYPT_ONLY */
721
722
723 /** Terminate the context
724 @param skey The scheduled key
725 */
726 void ECB_DONE(symmetric_key *skey)
727 {
728 }
729
730
731 /**
732 Gets suitable key size
733 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
734 @return CRYPT_OK if the input key size is acceptable.
735 */
736 int ECB_KS(int *keysize)
737 {
738 LTC_ARGCHK(keysize != NULL);
739
740 if (*keysize < 16)
741 return CRYPT_INVALID_KEYSIZE;
742 if (*keysize < 24) {
743 *keysize = 16;
744 return CRYPT_OK;
745 } else if (*keysize < 32) {
746 *keysize = 24;
747 return CRYPT_OK;
748 } else {
749 *keysize = 32;
750 return CRYPT_OK;
751 }
752 }
753
754 #endif
755
756
757 /* $Source$ */
758 /* $Revision$ */
759 /* $Date$ */
+0
-1028
libtom-src/ciphers/aes/aes_tab.c.inc less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /* The precomputed tables for AES */
11 /*
12 Te0[x] = S [x].[02, 01, 01, 03];
13 Te1[x] = S [x].[03, 02, 01, 01];
14 Te2[x] = S [x].[01, 03, 02, 01];
15 Te3[x] = S [x].[01, 01, 03, 02];
16 Te4[x] = S [x].[01, 01, 01, 01];
17
18 Td0[x] = Si[x].[0e, 09, 0d, 0b];
19 Td1[x] = Si[x].[0b, 0e, 09, 0d];
20 Td2[x] = Si[x].[0d, 0b, 0e, 09];
21 Td3[x] = Si[x].[09, 0d, 0b, 0e];
22 Td4[x] = Si[x].[01, 01, 01, 01];
23 */
24
25 /**
26 @file aes_tab.c
27 AES tables
28 */
29 static const ulong32 TE0[256] = {
30 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
31 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
32 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
33 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
34 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL,
35 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
36 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL,
37 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
38 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL,
39 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
40 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL,
41 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
42 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL,
43 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
44 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL,
45 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
46 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL,
47 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
48 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL,
49 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
50 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL,
51 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
52 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL,
53 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
54 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL,
55 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
56 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL,
57 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
58 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL,
59 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
60 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL,
61 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
62 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL,
63 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
64 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL,
65 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
66 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL,
67 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
68 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL,
69 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
70 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL,
71 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
72 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL,
73 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
74 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL,
75 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
76 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL,
77 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
78 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL,
79 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
80 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL,
81 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
82 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL,
83 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
84 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL,
85 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
86 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL,
87 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
88 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL,
89 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
90 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL,
91 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
92 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL,
93 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL,
94 };
95
96 #ifndef PELI_TAB
97 static const ulong32 Te4[256] = {
98 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL,
99 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL,
100 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL,
101 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL,
102 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL,
103 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL,
104 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL,
105 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL,
106 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL,
107 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL,
108 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL,
109 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL,
110 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL,
111 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL,
112 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL,
113 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL,
114 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL,
115 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL,
116 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL,
117 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL,
118 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL,
119 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL,
120 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL,
121 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL,
122 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL,
123 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL,
124 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL,
125 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL,
126 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL,
127 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL,
128 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL,
129 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL,
130 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL,
131 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL,
132 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL,
133 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL,
134 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL,
135 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL,
136 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL,
137 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL,
138 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL,
139 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL,
140 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL,
141 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL,
142 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL,
143 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL,
144 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL,
145 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL,
146 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL,
147 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL,
148 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL,
149 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL,
150 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL,
151 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL,
152 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL,
153 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL,
154 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL,
155 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL,
156 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL,
157 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL,
158 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL,
159 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL,
160 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL,
161 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL,
162 };
163 #endif
164
165 #ifndef ENCRYPT_ONLY
166
167 static const ulong32 TD0[256] = {
168 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
169 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
170 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL,
171 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL,
172 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL,
173 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL,
174 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL,
175 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL,
176 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL,
177 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL,
178 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL,
179 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL,
180 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL,
181 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL,
182 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL,
183 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL,
184 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL,
185 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL,
186 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL,
187 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL,
188 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL,
189 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL,
190 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL,
191 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL,
192 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL,
193 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL,
194 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL,
195 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL,
196 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL,
197 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL,
198 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL,
199 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL,
200 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL,
201 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL,
202 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL,
203 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL,
204 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL,
205 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL,
206 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL,
207 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL,
208 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL,
209 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL,
210 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL,
211 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL,
212 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL,
213 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL,
214 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL,
215 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL,
216 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL,
217 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL,
218 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL,
219 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL,
220 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL,
221 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL,
222 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL,
223 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL,
224 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL,
225 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL,
226 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL,
227 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL,
228 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL,
229 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL,
230 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL,
231 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL,
232 };
233
234 static const ulong32 Td4[256] = {
235 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL,
236 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL,
237 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL,
238 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL,
239 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL,
240 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL,
241 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL,
242 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL,
243 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL,
244 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL,
245 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL,
246 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL,
247 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL,
248 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL,
249 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL,
250 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL,
251 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL,
252 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL,
253 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL,
254 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL,
255 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL,
256 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL,
257 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL,
258 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL,
259 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL,
260 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL,
261 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL,
262 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL,
263 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL,
264 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL,
265 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL,
266 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL,
267 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL,
268 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL,
269 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL,
270 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL,
271 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL,
272 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL,
273 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL,
274 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL,
275 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL,
276 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL,
277 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL,
278 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL,
279 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL,
280 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL,
281 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL,
282 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL,
283 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL,
284 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL,
285 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL,
286 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL,
287 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL,
288 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL,
289 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL,
290 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL,
291 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL,
292 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL,
293 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL,
294 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL,
295 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL,
296 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL,
297 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL,
298 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL,
299 };
300
301 #endif /* ENCRYPT_ONLY */
302
303 #ifdef LTC_SMALL_CODE
304
305 #define Te0(x) TE0[x]
306 #define Te1(x) RORc(TE0[x], 8)
307 #define Te2(x) RORc(TE0[x], 16)
308 #define Te3(x) RORc(TE0[x], 24)
309
310 #define Td0(x) TD0[x]
311 #define Td1(x) RORc(TD0[x], 8)
312 #define Td2(x) RORc(TD0[x], 16)
313 #define Td3(x) RORc(TD0[x], 24)
314
315 #define Te4_0 0x000000FF & Te4
316 #define Te4_1 0x0000FF00 & Te4
317 #define Te4_2 0x00FF0000 & Te4
318 #define Te4_3 0xFF000000 & Te4
319
320 #else
321
322 #define Te0(x) TE0[x]
323 #define Te1(x) TE1[x]
324 #define Te2(x) TE2[x]
325 #define Te3(x) TE3[x]
326
327 #define Td0(x) TD0[x]
328 #define Td1(x) TD1[x]
329 #define Td2(x) TD2[x]
330 #define Td3(x) TD3[x]
331
332 static const ulong32 TE1[256] = {
333 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL,
334 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL,
335 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL,
336 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL,
337 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL,
338 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL,
339 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL,
340 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL,
341 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL,
342 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL,
343 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL,
344 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL,
345 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL,
346 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL,
347 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL,
348 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL,
349 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL,
350 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL,
351 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL,
352 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL,
353 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL,
354 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL,
355 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL,
356 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL,
357 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL,
358 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL,
359 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL,
360 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL,
361 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL,
362 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL,
363 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL,
364 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL,
365 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL,
366 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL,
367 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL,
368 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL,
369 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL,
370 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL,
371 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL,
372 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL,
373 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL,
374 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL,
375 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL,
376 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL,
377 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL,
378 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL,
379 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL,
380 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL,
381 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL,
382 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL,
383 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL,
384 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL,
385 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL,
386 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL,
387 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL,
388 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL,
389 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL,
390 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL,
391 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL,
392 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL,
393 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL,
394 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL,
395 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL,
396 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL,
397 };
398 static const ulong32 TE2[256] = {
399 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL,
400 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL,
401 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL,
402 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL,
403 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL,
404 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL,
405 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL,
406 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL,
407 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL,
408 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL,
409 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL,
410 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL,
411 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL,
412 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL,
413 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL,
414 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL,
415 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL,
416 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL,
417 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL,
418 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL,
419 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL,
420 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL,
421 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL,
422 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL,
423 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL,
424 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL,
425 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL,
426 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL,
427 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL,
428 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL,
429 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL,
430 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL,
431 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL,
432 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL,
433 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL,
434 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL,
435 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL,
436 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL,
437 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL,
438 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL,
439 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL,
440 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL,
441 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL,
442 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL,
443 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL,
444 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL,
445 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL,
446 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL,
447 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL,
448 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL,
449 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL,
450 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL,
451 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL,
452 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL,
453 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL,
454 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL,
455 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL,
456 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL,
457 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL,
458 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL,
459 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL,
460 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL,
461 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL,
462 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL,
463 };
464 static const ulong32 TE3[256] = {
465
466 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL,
467 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL,
468 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL,
469 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL,
470 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL,
471 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL,
472 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL,
473 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL,
474 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL,
475 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL,
476 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL,
477 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL,
478 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL,
479 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL,
480 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL,
481 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL,
482 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL,
483 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL,
484 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL,
485 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL,
486 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL,
487 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL,
488 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL,
489 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL,
490 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL,
491 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL,
492 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL,
493 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL,
494 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL,
495 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL,
496 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL,
497 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL,
498 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL,
499 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL,
500 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL,
501 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL,
502 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL,
503 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL,
504 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL,
505 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL,
506 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL,
507 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL,
508 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL,
509 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL,
510 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL,
511 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL,
512 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL,
513 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL,
514 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL,
515 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL,
516 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL,
517 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL,
518 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL,
519 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL,
520 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL,
521 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL,
522 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL,
523 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL,
524 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL,
525 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL,
526 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL,
527 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL,
528 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL,
529 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL,
530 };
531
532 #ifndef PELI_TAB
533 static const ulong32 Te4_0[] = {
534 0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL, 0x0000006bUL, 0x0000006fUL, 0x000000c5UL,
535 0x00000030UL, 0x00000001UL, 0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL, 0x00000076UL,
536 0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL, 0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL,
537 0x000000adUL, 0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL, 0x00000072UL, 0x000000c0UL,
538 0x000000b7UL, 0x000000fdUL, 0x00000093UL, 0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL,
539 0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL, 0x000000d8UL, 0x00000031UL, 0x00000015UL,
540 0x00000004UL, 0x000000c7UL, 0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL, 0x0000009aUL,
541 0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL, 0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL,
542 0x00000009UL, 0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL, 0x0000005aUL, 0x000000a0UL,
543 0x00000052UL, 0x0000003bUL, 0x000000d6UL, 0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL,
544 0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL, 0x000000fcUL, 0x000000b1UL, 0x0000005bUL,
545 0x0000006aUL, 0x000000cbUL, 0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL, 0x000000cfUL,
546 0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL, 0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL,
547 0x00000045UL, 0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL, 0x0000009fUL, 0x000000a8UL,
548 0x00000051UL, 0x000000a3UL, 0x00000040UL, 0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL,
549 0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL, 0x000000ffUL, 0x000000f3UL, 0x000000d2UL,
550 0x000000cdUL, 0x0000000cUL, 0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL, 0x00000017UL,
551 0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL, 0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL,
552 0x00000060UL, 0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL, 0x00000090UL, 0x00000088UL,
553 0x00000046UL, 0x000000eeUL, 0x000000b8UL, 0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL,
554 0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL, 0x00000006UL, 0x00000024UL, 0x0000005cUL,
555 0x000000c2UL, 0x000000d3UL, 0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL, 0x00000079UL,
556 0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL, 0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL,
557 0x0000006cUL, 0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL, 0x000000aeUL, 0x00000008UL,
558 0x000000baUL, 0x00000078UL, 0x00000025UL, 0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL,
559 0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL, 0x000000bdUL, 0x0000008bUL, 0x0000008aUL,
560 0x00000070UL, 0x0000003eUL, 0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL, 0x0000000eUL,
561 0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL, 0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL,
562 0x000000e1UL, 0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL, 0x0000008eUL, 0x00000094UL,
563 0x0000009bUL, 0x0000001eUL, 0x00000087UL, 0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL,
564 0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL, 0x000000e6UL, 0x00000042UL, 0x00000068UL,
565 0x00000041UL, 0x00000099UL, 0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL, 0x00000016UL
566 };
567
568 static const ulong32 Te4_1[] = {
569 0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL, 0x00006b00UL, 0x00006f00UL, 0x0000c500UL,
570 0x00003000UL, 0x00000100UL, 0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL, 0x00007600UL,
571 0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL, 0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL,
572 0x0000ad00UL, 0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL, 0x00007200UL, 0x0000c000UL,
573 0x0000b700UL, 0x0000fd00UL, 0x00009300UL, 0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL,
574 0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL, 0x0000d800UL, 0x00003100UL, 0x00001500UL,
575 0x00000400UL, 0x0000c700UL, 0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL, 0x00009a00UL,
576 0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL, 0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL,
577 0x00000900UL, 0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL, 0x00005a00UL, 0x0000a000UL,
578 0x00005200UL, 0x00003b00UL, 0x0000d600UL, 0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL,
579 0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL, 0x0000fc00UL, 0x0000b100UL, 0x00005b00UL,
580 0x00006a00UL, 0x0000cb00UL, 0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL, 0x0000cf00UL,
581 0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL, 0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL,
582 0x00004500UL, 0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL, 0x00009f00UL, 0x0000a800UL,
583 0x00005100UL, 0x0000a300UL, 0x00004000UL, 0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL,
584 0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL, 0x0000ff00UL, 0x0000f300UL, 0x0000d200UL,
585 0x0000cd00UL, 0x00000c00UL, 0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL, 0x00001700UL,
586 0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL, 0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL,
587 0x00006000UL, 0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL, 0x00009000UL, 0x00008800UL,
588 0x00004600UL, 0x0000ee00UL, 0x0000b800UL, 0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL,
589 0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL, 0x00000600UL, 0x00002400UL, 0x00005c00UL,
590 0x0000c200UL, 0x0000d300UL, 0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL, 0x00007900UL,
591 0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL, 0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL,
592 0x00006c00UL, 0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL, 0x0000ae00UL, 0x00000800UL,
593 0x0000ba00UL, 0x00007800UL, 0x00002500UL, 0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL,
594 0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL, 0x0000bd00UL, 0x00008b00UL, 0x00008a00UL,
595 0x00007000UL, 0x00003e00UL, 0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL, 0x00000e00UL,
596 0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL, 0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL,
597 0x0000e100UL, 0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL, 0x00008e00UL, 0x00009400UL,
598 0x00009b00UL, 0x00001e00UL, 0x00008700UL, 0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL,
599 0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL, 0x0000e600UL, 0x00004200UL, 0x00006800UL,
600 0x00004100UL, 0x00009900UL, 0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL, 0x00001600UL
601 };
602
603 static const ulong32 Te4_2[] = {
604 0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL, 0x006b0000UL, 0x006f0000UL, 0x00c50000UL,
605 0x00300000UL, 0x00010000UL, 0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL, 0x00760000UL,
606 0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL, 0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL,
607 0x00ad0000UL, 0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL, 0x00720000UL, 0x00c00000UL,
608 0x00b70000UL, 0x00fd0000UL, 0x00930000UL, 0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL,
609 0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL, 0x00d80000UL, 0x00310000UL, 0x00150000UL,
610 0x00040000UL, 0x00c70000UL, 0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL, 0x009a0000UL,
611 0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL, 0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL,
612 0x00090000UL, 0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL, 0x005a0000UL, 0x00a00000UL,
613 0x00520000UL, 0x003b0000UL, 0x00d60000UL, 0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL,
614 0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL, 0x00fc0000UL, 0x00b10000UL, 0x005b0000UL,
615 0x006a0000UL, 0x00cb0000UL, 0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL, 0x00cf0000UL,
616 0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL, 0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL,
617 0x00450000UL, 0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL, 0x009f0000UL, 0x00a80000UL,
618 0x00510000UL, 0x00a30000UL, 0x00400000UL, 0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL,
619 0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL, 0x00ff0000UL, 0x00f30000UL, 0x00d20000UL,
620 0x00cd0000UL, 0x000c0000UL, 0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL, 0x00170000UL,
621 0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL, 0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL,
622 0x00600000UL, 0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL, 0x00900000UL, 0x00880000UL,
623 0x00460000UL, 0x00ee0000UL, 0x00b80000UL, 0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL,
624 0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL, 0x00060000UL, 0x00240000UL, 0x005c0000UL,
625 0x00c20000UL, 0x00d30000UL, 0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL, 0x00790000UL,
626 0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL, 0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL,
627 0x006c0000UL, 0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL, 0x00ae0000UL, 0x00080000UL,
628 0x00ba0000UL, 0x00780000UL, 0x00250000UL, 0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL,
629 0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL, 0x00bd0000UL, 0x008b0000UL, 0x008a0000UL,
630 0x00700000UL, 0x003e0000UL, 0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL, 0x000e0000UL,
631 0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL, 0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL,
632 0x00e10000UL, 0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL, 0x008e0000UL, 0x00940000UL,
633 0x009b0000UL, 0x001e0000UL, 0x00870000UL, 0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL,
634 0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL, 0x00e60000UL, 0x00420000UL, 0x00680000UL,
635 0x00410000UL, 0x00990000UL, 0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL, 0x00160000UL
636 };
637
638 static const ulong32 Te4_3[] = {
639 0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL, 0x6b000000UL, 0x6f000000UL, 0xc5000000UL,
640 0x30000000UL, 0x01000000UL, 0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL, 0x76000000UL,
641 0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL, 0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL,
642 0xad000000UL, 0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL, 0x72000000UL, 0xc0000000UL,
643 0xb7000000UL, 0xfd000000UL, 0x93000000UL, 0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL,
644 0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL, 0xd8000000UL, 0x31000000UL, 0x15000000UL,
645 0x04000000UL, 0xc7000000UL, 0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL, 0x9a000000UL,
646 0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL, 0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL,
647 0x09000000UL, 0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL, 0x5a000000UL, 0xa0000000UL,
648 0x52000000UL, 0x3b000000UL, 0xd6000000UL, 0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL,
649 0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL, 0xfc000000UL, 0xb1000000UL, 0x5b000000UL,
650 0x6a000000UL, 0xcb000000UL, 0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL, 0xcf000000UL,
651 0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL, 0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL,
652 0x45000000UL, 0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL, 0x9f000000UL, 0xa8000000UL,
653 0x51000000UL, 0xa3000000UL, 0x40000000UL, 0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL,
654 0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL, 0xff000000UL, 0xf3000000UL, 0xd2000000UL,
655 0xcd000000UL, 0x0c000000UL, 0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL, 0x17000000UL,
656 0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL, 0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL,
657 0x60000000UL, 0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL, 0x90000000UL, 0x88000000UL,
658 0x46000000UL, 0xee000000UL, 0xb8000000UL, 0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL,
659 0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL, 0x06000000UL, 0x24000000UL, 0x5c000000UL,
660 0xc2000000UL, 0xd3000000UL, 0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL, 0x79000000UL,
661 0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL, 0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL,
662 0x6c000000UL, 0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL, 0xae000000UL, 0x08000000UL,
663 0xba000000UL, 0x78000000UL, 0x25000000UL, 0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL,
664 0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL, 0xbd000000UL, 0x8b000000UL, 0x8a000000UL,
665 0x70000000UL, 0x3e000000UL, 0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL, 0x0e000000UL,
666 0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL, 0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL,
667 0xe1000000UL, 0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL, 0x8e000000UL, 0x94000000UL,
668 0x9b000000UL, 0x1e000000UL, 0x87000000UL, 0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL,
669 0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL, 0xe6000000UL, 0x42000000UL, 0x68000000UL,
670 0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL
671 };
672 #endif /* pelimac */
673
674 #ifndef ENCRYPT_ONLY
675
676 static const ulong32 TD1[256] = {
677 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
678 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
679 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL,
680 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL,
681 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL,
682 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL,
683 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL,
684 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL,
685 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL,
686 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL,
687 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL,
688 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL,
689 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL,
690 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL,
691 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL,
692 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL,
693 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL,
694 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL,
695 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL,
696 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL,
697 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL,
698 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL,
699 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL,
700 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL,
701 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL,
702 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL,
703 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL,
704 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL,
705 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL,
706 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL,
707 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL,
708 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL,
709 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL,
710 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL,
711 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL,
712 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL,
713 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL,
714 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL,
715 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL,
716 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL,
717 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL,
718 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL,
719 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL,
720 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL,
721 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL,
722 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL,
723 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL,
724 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL,
725 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL,
726 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL,
727 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL,
728 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL,
729 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL,
730 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL,
731 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL,
732 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL,
733 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL,
734 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL,
735 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL,
736 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL,
737 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL,
738 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL,
739 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL,
740 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL,
741 };
742 static const ulong32 TD2[256] = {
743 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL,
744 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL,
745 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL,
746 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL,
747 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL,
748 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL,
749 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL,
750 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL,
751 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL,
752 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL,
753 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL,
754 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL,
755 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL,
756 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL,
757 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL,
758 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL,
759 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL,
760 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL,
761 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL,
762 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL,
763 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL,
764 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL,
765 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL,
766 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL,
767 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL,
768 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL,
769 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL,
770 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL,
771 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL,
772 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL,
773 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL,
774 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL,
775 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL,
776 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL,
777 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL,
778 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL,
779 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL,
780 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL,
781 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL,
782 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL,
783 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL,
784 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL,
785 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL,
786 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL,
787 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL,
788 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL,
789 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL,
790 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL,
791 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL,
792 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL,
793 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL,
794 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL,
795 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL,
796 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL,
797 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL,
798 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL,
799 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL,
800 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL,
801 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL,
802 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL,
803 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL,
804 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL,
805 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL,
806 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL,
807 };
808 static const ulong32 TD3[256] = {
809 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL,
810 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL,
811 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL,
812 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL,
813 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL,
814 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL,
815 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL,
816 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL,
817 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL,
818 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL,
819 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL,
820 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL,
821 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL,
822 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL,
823 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL,
824 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL,
825 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL,
826 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL,
827 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL,
828 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL,
829 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL,
830 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL,
831 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL,
832 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL,
833 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL,
834 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL,
835 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL,
836 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL,
837 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL,
838 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL,
839 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL,
840 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL,
841 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL,
842 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL,
843 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL,
844 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL,
845 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL,
846 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL,
847 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL,
848 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL,
849 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL,
850 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL,
851 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL,
852 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL,
853 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL,
854 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL,
855 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL,
856 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL,
857 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL,
858 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL,
859 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL,
860 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL,
861 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL,
862 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL,
863 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL,
864 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL,
865 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL,
866 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL,
867 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL,
868 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL,
869 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL,
870 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL,
871 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL,
872 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL,
873 };
874
875 static const ulong32 Tks0[] = {
876 0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL, 0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL,
877 0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL, 0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL,
878 0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL, 0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL,
879 0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL, 0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL,
880 0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL, 0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL,
881 0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL, 0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL,
882 0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL, 0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL,
883 0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL, 0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL,
884 0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL, 0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL,
885 0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL, 0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL,
886 0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL, 0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL,
887 0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL, 0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL,
888 0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL, 0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL,
889 0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL, 0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL,
890 0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL, 0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL,
891 0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL, 0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL,
892 0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL, 0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL,
893 0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL, 0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL,
894 0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL, 0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL,
895 0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL, 0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL,
896 0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL, 0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL,
897 0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL, 0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL,
898 0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL, 0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL,
899 0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL, 0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL,
900 0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL, 0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL,
901 0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL, 0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL,
902 0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL, 0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL,
903 0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL, 0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL,
904 0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL, 0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL,
905 0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL, 0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL,
906 0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL, 0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL,
907 0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL, 0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL
908 };
909
910 static const ulong32 Tks1[] = {
911 0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL, 0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL,
912 0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL, 0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL,
913 0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL, 0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL,
914 0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL, 0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL,
915 0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL, 0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL,
916 0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL, 0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL,
917 0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL, 0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL,
918 0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL, 0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL,
919 0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL, 0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL,
920 0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL, 0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL,
921 0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL, 0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL,
922 0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL, 0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL,
923 0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL, 0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL,
924 0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL, 0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL,
925 0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL, 0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL,
926 0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL, 0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL,
927 0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL, 0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL,
928 0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL, 0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL,
929 0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL, 0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL,
930 0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL, 0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL,
931 0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL, 0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL,
932 0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL, 0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL,
933 0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL, 0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL,
934 0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL, 0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL,
935 0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL, 0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL,
936 0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL, 0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL,
937 0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL, 0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL,
938 0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL, 0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL,
939 0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL, 0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL,
940 0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL, 0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL,
941 0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL, 0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL,
942 0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL, 0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL
943 };
944
945 static const ulong32 Tks2[] = {
946 0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL, 0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL,
947 0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL, 0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL,
948 0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL, 0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL,
949 0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL, 0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL,
950 0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL, 0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL,
951 0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL, 0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL,
952 0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL, 0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL,
953 0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL, 0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL,
954 0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL, 0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL,
955 0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL, 0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL,
956 0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL, 0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL,
957 0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL, 0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL,
958 0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL, 0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL,
959 0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL, 0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL,
960 0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL, 0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL,
961 0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL, 0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL,
962 0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL, 0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL,
963 0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL, 0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL,
964 0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL, 0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL,
965 0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL, 0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL,
966 0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL, 0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL,
967 0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL, 0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL,
968 0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL, 0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL,
969 0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL, 0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL,
970 0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL, 0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL,
971 0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL, 0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL,
972 0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL, 0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL,
973 0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL, 0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL,
974 0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL, 0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL,
975 0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL, 0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL,
976 0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL, 0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL,
977 0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL, 0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL
978 };
979
980 static const ulong32 Tks3[] = {
981 0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL,
982 0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL,
983 0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL,
984 0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL,
985 0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL,
986 0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL,
987 0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL,
988 0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL,
989 0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL,
990 0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL,
991 0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL,
992 0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL,
993 0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL,
994 0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL,
995 0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL,
996 0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL,
997 0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL,
998 0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL,
999 0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL,
1000 0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL,
1001 0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL,
1002 0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL,
1003 0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL,
1004 0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL,
1005 0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL,
1006 0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL,
1007 0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL,
1008 0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL,
1009 0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL,
1010 0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL,
1011 0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL,
1012 0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL
1013 };
1014
1015 #endif /* ENCRYPT_ONLY */
1016
1017 #endif /* SMALL CODE */
1018
1019 static const ulong32 rcon[] = {
1020 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
1021 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
1022 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1023 };
1024
1025 /* $Source$ */
1026 /* $Revision$ */
1027 /* $Date$ */
+0
-1558
libtom-src/ciphers/anubis.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file anubis.c
13 Anubis implementation derived from public domain source
14 Authors: Paulo S.L.M. Barreto and Vincent Rijmen.
15 */
16
17 #include "tomcrypt.h"
18
19 #ifdef LTC_ANUBIS
20
21 const struct ltc_cipher_descriptor anubis_desc = {
22 "anubis",
23 19,
24 16, 40, 16, 12,
25 &anubis_setup,
26 &anubis_ecb_encrypt,
27 &anubis_ecb_decrypt,
28 &anubis_test,
29 &anubis_done,
30 &anubis_keysize,
31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
32 };
33
34 #define MIN_N 4
35 #define MAX_N 10
36 #define MIN_ROUNDS (8 + MIN_N)
37 #define MAX_ROUNDS (8 + MAX_N)
38 #define MIN_KEYSIZEB (4*MIN_N)
39 #define MAX_KEYSIZEB (4*MAX_N)
40 #define BLOCKSIZE 128
41 #define BLOCKSIZEB (BLOCKSIZE/8)
42
43
44 /*
45 * Though Anubis is endianness-neutral, the encryption tables are listed
46 * in BIG-ENDIAN format, which is adopted throughout this implementation
47 * (but little-endian notation would be equally suitable if consistently
48 * employed).
49 */
50 #if defined(LTC_ANUBIS_TWEAK)
51
52 static const ulong32 T0[256] = {
53 0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U,
54 0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U,
55 0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U,
56 0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U,
57 0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU,
58 0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U,
59 0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U,
60 0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U,
61 0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU,
62 0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U,
63 0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U,
64 0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU,
65 0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U,
66 0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U,
67 0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U,
68 0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U,
69 0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U,
70 0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U,
71 0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U,
72 0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U,
73 0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U,
74 0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U,
75 0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U,
76 0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U,
77 0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU,
78 0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU,
79 0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU,
80 0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U,
81 0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU,
82 0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU,
83 0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U,
84 0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U,
85 0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U,
86 0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U,
87 0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U,
88 0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U,
89 0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU,
90 0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU,
91 0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU,
92 0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU,
93 0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU,
94 0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU,
95 0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU,
96 0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U,
97 0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU,
98 0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U,
99 0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU,
100 0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU,
101 0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U,
102 0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U,
103 0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U,
104 0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU,
105 0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU,
106 0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U,
107 0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U,
108 0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U,
109 0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U,
110 0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU,
111 0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU,
112 0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U,
113 0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU,
114 0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU,
115 0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU,
116 0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U,
117 };
118
119 static const ulong32 T1[256] = {
120 0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU,
121 0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U,
122 0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U,
123 0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU,
124 0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U,
125 0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U,
126 0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU,
127 0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U,
128 0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U,
129 0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U,
130 0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU,
131 0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U,
132 0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U,
133 0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U,
134 0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U,
135 0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU,
136 0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U,
137 0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U,
138 0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU,
139 0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU,
140 0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U,
141 0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U,
142 0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U,
143 0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U,
144 0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U,
145 0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU,
146 0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U,
147 0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U,
148 0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U,
149 0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU,
150 0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U,
151 0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U,
152 0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU,
153 0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U,
154 0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU,
155 0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU,
156 0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU,
157 0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U,
158 0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU,
159 0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU,
160 0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU,
161 0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U,
162 0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U,
163 0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U,
164 0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U,
165 0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U,
166 0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U,
167 0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU,
168 0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U,
169 0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U,
170 0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U,
171 0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U,
172 0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U,
173 0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU,
174 0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U,
175 0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U,
176 0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U,
177 0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U,
178 0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU,
179 0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU,
180 0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U,
181 0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU,
182 0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U,
183 0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U,
184 };
185
186 static const ulong32 T2[256] = {
187 0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U,
188 0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU,
189 0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U,
190 0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U,
191 0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU,
192 0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U,
193 0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU,
194 0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U,
195 0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU,
196 0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU,
197 0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U,
198 0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U,
199 0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U,
200 0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU,
201 0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U,
202 0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U,
203 0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U,
204 0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U,
205 0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU,
206 0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU,
207 0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U,
208 0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU,
209 0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU,
210 0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U,
211 0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU,
212 0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U,
213 0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U,
214 0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU,
215 0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U,
216 0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U,
217 0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU,
218 0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U,
219 0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU,
220 0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U,
221 0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU,
222 0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U,
223 0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U,
224 0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U,
225 0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U,
226 0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U,
227 0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U,
228 0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U,
229 0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U,
230 0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU,
231 0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU,
232 0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU,
233 0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU,
234 0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U,
235 0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U,
236 0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U,
237 0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U,
238 0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU,
239 0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU,
240 0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U,
241 0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U,
242 0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU,
243 0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U,
244 0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU,
245 0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U,
246 0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U,
247 0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU,
248 0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U,
249 0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU,
250 0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U,
251 };
252
253 static const ulong32 T3[256] = {
254 0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U,
255 0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU,
256 0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU,
257 0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU,
258 0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U,
259 0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U,
260 0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U,
261 0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU,
262 0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU,
263 0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU,
264 0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U,
265 0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U,
266 0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U,
267 0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU,
268 0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU,
269 0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU,
270 0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU,
271 0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU,
272 0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U,
273 0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU,
274 0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U,
275 0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U,
276 0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U,
277 0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U,
278 0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U,
279 0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU,
280 0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU,
281 0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U,
282 0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U,
283 0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U,
284 0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U,
285 0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU,
286 0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U,
287 0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU,
288 0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U,
289 0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U,
290 0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU,
291 0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U,
292 0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U,
293 0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU,
294 0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U,
295 0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U,
296 0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU,
297 0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU,
298 0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U,
299 0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU,
300 0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U,
301 0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU,
302 0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U,
303 0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U,
304 0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U,
305 0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U,
306 0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U,
307 0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU,
308 0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU,
309 0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U,
310 0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U,
311 0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U,
312 0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U,
313 0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U,
314 0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU,
315 0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U,
316 0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU,
317 0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U,
318 };
319
320 static const ulong32 T4[256] = {
321 0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U,
322 0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU,
323 0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU,
324 0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU,
325 0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U,
326 0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U,
327 0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U,
328 0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU,
329 0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU,
330 0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU,
331 0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U,
332 0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U,
333 0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U,
334 0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU,
335 0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU,
336 0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU,
337 0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU,
338 0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU,
339 0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U,
340 0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU,
341 0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U,
342 0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U,
343 0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U,
344 0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U,
345 0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U,
346 0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU,
347 0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU,
348 0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U,
349 0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U,
350 0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U,
351 0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U,
352 0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU,
353 0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U,
354 0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU,
355 0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U,
356 0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U,
357 0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU,
358 0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U,
359 0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U,
360 0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU,
361 0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U,
362 0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U,
363 0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU,
364 0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU,
365 0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U,
366 0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU,
367 0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U,
368 0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU,
369 0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U,
370 0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U,
371 0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U,
372 0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U,
373 0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U,
374 0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU,
375 0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU,
376 0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U,
377 0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U,
378 0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U,
379 0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U,
380 0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U,
381 0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU,
382 0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U,
383 0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU,
384 0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U,
385 };
386
387 static const ulong32 T5[256] = {
388 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U,
389 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U,
390 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U,
391 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U,
392 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U,
393 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U,
394 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U,
395 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U,
396 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U,
397 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U,
398 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U,
399 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U,
400 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U,
401 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U,
402 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U,
403 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U,
404 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U,
405 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U,
406 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U,
407 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U,
408 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U,
409 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U,
410 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U,
411 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U,
412 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU,
413 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU,
414 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU,
415 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU,
416 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU,
417 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU,
418 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU,
419 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU,
420 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU,
421 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU,
422 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU,
423 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU,
424 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU,
425 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU,
426 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU,
427 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU,
428 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U,
429 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U,
430 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U,
431 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U,
432 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U,
433 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U,
434 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U,
435 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U,
436 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U,
437 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U,
438 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U,
439 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U,
440 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U,
441 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U,
442 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U,
443 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U,
444 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU,
445 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU,
446 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU,
447 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU,
448 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU,
449 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU,
450 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU,
451 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU,
452 };
453
454 /**
455 * The round constants.
456 */
457 static const ulong32 rc[] = {
458 0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU,
459 0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU,
460 0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U,
461 0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU,
462 0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U,
463 };
464
465
466
467 #else
468
469
470 static const ulong32 T0[256] = {
471 0xa753a6f5U, 0xd3bb6bd0U, 0xe6d1bf6eU, 0x71e2d93bU,
472 0xd0bd67daU, 0xac458acfU, 0x4d9a29b3U, 0x79f2f90bU,
473 0x3a74e89cU, 0xc98f038cU, 0x913f7e41U, 0xfce5d732U,
474 0x1e3c7844U, 0x478e018fU, 0x54a84de5U, 0xbd67cea9U,
475 0x8c050a0fU, 0xa557aef9U, 0x7af4f501U, 0xfbebcb20U,
476 0x63c69157U, 0xb86ddab7U, 0xdda753f4U, 0xd4b577c2U,
477 0xe5d7b364U, 0xb37bf68dU, 0xc59733a4U, 0xbe61c2a3U,
478 0xa94f9ed1U, 0x880d1a17U, 0x0c183028U, 0xa259b2ebU,
479 0x3972e496U, 0xdfa35bf8U, 0x2952a4f6U, 0xdaa94fe6U,
480 0x2b56acfaU, 0xa84d9ad7U, 0xcb8b0b80U, 0x4c982db5U,
481 0x4b9631a7U, 0x224488ccU, 0xaa4992dbU, 0x244890d8U,
482 0x4182199bU, 0x70e0dd3dU, 0xa651a2f3U, 0xf9efc32cU,
483 0x5ab475c1U, 0xe2d9af76U, 0xb07dfa87U, 0x366cd8b4U,
484 0x7dfae913U, 0xe4d5b762U, 0x3366ccaaU, 0xffe3db38U,
485 0x60c09d5dU, 0x204080c0U, 0x08102030U, 0x8b0b161dU,
486 0x5ebc65d9U, 0xab4b96ddU, 0x7ffee11fU, 0x78f0fd0dU,
487 0x7cf8ed15U, 0x2c58b0e8U, 0x57ae41efU, 0xd2b96fd6U,
488 0xdca557f2U, 0x6ddaa973U, 0x7efce519U, 0x0d1a342eU,
489 0x53a651f7U, 0x94356a5fU, 0xc39b2bb0U, 0x2850a0f0U,
490 0x274e9cd2U, 0x060c1814U, 0x5fbe61dfU, 0xad478ec9U,
491 0x67ce814fU, 0x5cb86dd5U, 0x55aa49e3U, 0x48903dadU,
492 0x0e1c3824U, 0x52a455f1U, 0xeac98f46U, 0x42841591U,
493 0x5bb671c7U, 0x5dba69d3U, 0x3060c0a0U, 0x58b07dcdU,
494 0x51a259fbU, 0x59b279cbU, 0x3c78f088U, 0x4e9c25b9U,
495 0x3870e090U, 0x8a09121bU, 0x72e4d531U, 0x14285078U,
496 0xe7d3bb68U, 0xc6913faeU, 0xdea15ffeU, 0x50a05dfdU,
497 0x8e010203U, 0x9239724bU, 0xd1bf63dcU, 0x77eec12fU,
498 0x933b764dU, 0x458a0983U, 0x9a29527bU, 0xce811f9eU,
499 0x2d5ab4eeU, 0x03060c0aU, 0x62c49551U, 0xb671e293U,
500 0xb96fdeb1U, 0xbf63c6a5U, 0x96316253U, 0x6bd6b167U,
501 0x3f7efc82U, 0x070e1c12U, 0x1224486cU, 0xae4182c3U,
502 0x40801d9dU, 0x3468d0b8U, 0x468c0589U, 0x3e7cf884U,
503 0xdbab4be0U, 0xcf831b98U, 0xecc59752U, 0xcc851792U,
504 0xc19f23bcU, 0xa15fbee1U, 0xc09d27baU, 0xd6b17fceU,
505 0x1d3a744eU, 0xf4f5f702U, 0x61c2995bU, 0x3b76ec9aU,
506 0x10204060U, 0xd8ad47eaU, 0x68d0bd6dU, 0xa05dbae7U,
507 0xb17ffe81U, 0x0a14283cU, 0x69d2b96bU, 0x6cd8ad75U,
508 0x499239abU, 0xfae9cf26U, 0x76ecc529U, 0xc49537a2U,
509 0x9e214263U, 0x9b2b567dU, 0x6edca579U, 0x992f5e71U,
510 0xc2992fb6U, 0xb773e695U, 0x982d5a77U, 0xbc65caafU,
511 0x8f030605U, 0x85172e39U, 0x1f3e7c42U, 0xb475ea9fU,
512 0xf8edc72aU, 0x11224466U, 0x2e5cb8e4U, 0x00000000U,
513 0x254a94deU, 0x1c387048U, 0x2a54a8fcU, 0x3d7af48eU,
514 0x050a141eU, 0x4f9e21bfU, 0x7bf6f107U, 0xb279f28bU,
515 0x3264c8acU, 0x903d7a47U, 0xaf4386c5U, 0x19326456U,
516 0xa35bb6edU, 0xf7f3fb08U, 0x73e6d137U, 0x9d274e69U,
517 0x152a547eU, 0x74e8cd25U, 0xeec19f5eU, 0xca890f86U,
518 0x9f234665U, 0x0f1e3c22U, 0x1b366c5aU, 0x75eac923U,
519 0x86112233U, 0x84152a3fU, 0x9c254a6fU, 0x4a9435a1U,
520 0x97336655U, 0x1a34685cU, 0x65ca8943U, 0xf6f1ff0eU,
521 0xedc79354U, 0x09122436U, 0xbb6bd6bdU, 0x264c98d4U,
522 0x831b362dU, 0xebcb8b40U, 0x6fdea17fU, 0x811f3e21U,
523 0x04081018U, 0x6ad4b561U, 0x43861197U, 0x01020406U,
524 0x172e5c72U, 0xe1dfa37cU, 0x87132635U, 0xf5f7f304U,
525 0x8d070e09U, 0xe3dbab70U, 0x23468ccaU, 0x801d3a27U,
526 0x44880d85U, 0x162c5874U, 0x66cc8549U, 0x214284c6U,
527 0xfee1df3eU, 0xd5b773c4U, 0x3162c4a6U, 0xd9af43ecU,
528 0x356ad4beU, 0x18306050U, 0x0204080cU, 0x64c88d45U,
529 0xf2f9ef16U, 0xf1ffe31cU, 0x56ac45e9U, 0xcd871394U,
530 0x8219322bU, 0xc88d078aU, 0xba69d2bbU, 0xf0fde71aU,
531 0xefc39b58U, 0xe9cf834cU, 0xe8cd874aU, 0xfde7d334U,
532 0x890f1e11U, 0xd7b37bc8U, 0xc7933ba8U, 0xb577ee99U,
533 0xa455aaffU, 0x2f5ebce2U, 0x95376e59U, 0x13264c6aU,
534 0x0b162c3aU, 0xf3fbeb10U, 0xe0dda77aU, 0x376edcb2U,
535 };
536
537 static const ulong32 T1[256] = {
538 0x53a7f5a6U, 0xbbd3d06bU, 0xd1e66ebfU, 0xe2713bd9U,
539 0xbdd0da67U, 0x45accf8aU, 0x9a4db329U, 0xf2790bf9U,
540 0x743a9ce8U, 0x8fc98c03U, 0x3f91417eU, 0xe5fc32d7U,
541 0x3c1e4478U, 0x8e478f01U, 0xa854e54dU, 0x67bda9ceU,
542 0x058c0f0aU, 0x57a5f9aeU, 0xf47a01f5U, 0xebfb20cbU,
543 0xc6635791U, 0x6db8b7daU, 0xa7ddf453U, 0xb5d4c277U,
544 0xd7e564b3U, 0x7bb38df6U, 0x97c5a433U, 0x61bea3c2U,
545 0x4fa9d19eU, 0x0d88171aU, 0x180c2830U, 0x59a2ebb2U,
546 0x723996e4U, 0xa3dff85bU, 0x5229f6a4U, 0xa9dae64fU,
547 0x562bfaacU, 0x4da8d79aU, 0x8bcb800bU, 0x984cb52dU,
548 0x964ba731U, 0x4422cc88U, 0x49aadb92U, 0x4824d890U,
549 0x82419b19U, 0xe0703dddU, 0x51a6f3a2U, 0xeff92cc3U,
550 0xb45ac175U, 0xd9e276afU, 0x7db087faU, 0x6c36b4d8U,
551 0xfa7d13e9U, 0xd5e462b7U, 0x6633aaccU, 0xe3ff38dbU,
552 0xc0605d9dU, 0x4020c080U, 0x10083020U, 0x0b8b1d16U,
553 0xbc5ed965U, 0x4babdd96U, 0xfe7f1fe1U, 0xf0780dfdU,
554 0xf87c15edU, 0x582ce8b0U, 0xae57ef41U, 0xb9d2d66fU,
555 0xa5dcf257U, 0xda6d73a9U, 0xfc7e19e5U, 0x1a0d2e34U,
556 0xa653f751U, 0x35945f6aU, 0x9bc3b02bU, 0x5028f0a0U,
557 0x4e27d29cU, 0x0c061418U, 0xbe5fdf61U, 0x47adc98eU,
558 0xce674f81U, 0xb85cd56dU, 0xaa55e349U, 0x9048ad3dU,
559 0x1c0e2438U, 0xa452f155U, 0xc9ea468fU, 0x84429115U,
560 0xb65bc771U, 0xba5dd369U, 0x6030a0c0U, 0xb058cd7dU,
561 0xa251fb59U, 0xb259cb79U, 0x783c88f0U, 0x9c4eb925U,
562 0x703890e0U, 0x098a1b12U, 0xe47231d5U, 0x28147850U,
563 0xd3e768bbU, 0x91c6ae3fU, 0xa1defe5fU, 0xa050fd5dU,
564 0x018e0302U, 0x39924b72U, 0xbfd1dc63U, 0xee772fc1U,
565 0x3b934d76U, 0x8a458309U, 0x299a7b52U, 0x81ce9e1fU,
566 0x5a2deeb4U, 0x06030a0cU, 0xc4625195U, 0x71b693e2U,
567 0x6fb9b1deU, 0x63bfa5c6U, 0x31965362U, 0xd66b67b1U,
568 0x7e3f82fcU, 0x0e07121cU, 0x24126c48U, 0x41aec382U,
569 0x80409d1dU, 0x6834b8d0U, 0x8c468905U, 0x7c3e84f8U,
570 0xabdbe04bU, 0x83cf981bU, 0xc5ec5297U, 0x85cc9217U,
571 0x9fc1bc23U, 0x5fa1e1beU, 0x9dc0ba27U, 0xb1d6ce7fU,
572 0x3a1d4e74U, 0xf5f402f7U, 0xc2615b99U, 0x763b9aecU,
573 0x20106040U, 0xadd8ea47U, 0xd0686dbdU, 0x5da0e7baU,
574 0x7fb181feU, 0x140a3c28U, 0xd2696bb9U, 0xd86c75adU,
575 0x9249ab39U, 0xe9fa26cfU, 0xec7629c5U, 0x95c4a237U,
576 0x219e6342U, 0x2b9b7d56U, 0xdc6e79a5U, 0x2f99715eU,
577 0x99c2b62fU, 0x73b795e6U, 0x2d98775aU, 0x65bcafcaU,
578 0x038f0506U, 0x1785392eU, 0x3e1f427cU, 0x75b49feaU,
579 0xedf82ac7U, 0x22116644U, 0x5c2ee4b8U, 0x00000000U,
580 0x4a25de94U, 0x381c4870U, 0x542afca8U, 0x7a3d8ef4U,
581 0x0a051e14U, 0x9e4fbf21U, 0xf67b07f1U, 0x79b28bf2U,
582 0x6432acc8U, 0x3d90477aU, 0x43afc586U, 0x32195664U,
583 0x5ba3edb6U, 0xf3f708fbU, 0xe67337d1U, 0x279d694eU,
584 0x2a157e54U, 0xe87425cdU, 0xc1ee5e9fU, 0x89ca860fU,
585 0x239f6546U, 0x1e0f223cU, 0x361b5a6cU, 0xea7523c9U,
586 0x11863322U, 0x15843f2aU, 0x259c6f4aU, 0x944aa135U,
587 0x33975566U, 0x341a5c68U, 0xca654389U, 0xf1f60effU,
588 0xc7ed5493U, 0x12093624U, 0x6bbbbdd6U, 0x4c26d498U,
589 0x1b832d36U, 0xcbeb408bU, 0xde6f7fa1U, 0x1f81213eU,
590 0x08041810U, 0xd46a61b5U, 0x86439711U, 0x02010604U,
591 0x2e17725cU, 0xdfe17ca3U, 0x13873526U, 0xf7f504f3U,
592 0x078d090eU, 0xdbe370abU, 0x4623ca8cU, 0x1d80273aU,
593 0x8844850dU, 0x2c167458U, 0xcc664985U, 0x4221c684U,
594 0xe1fe3edfU, 0xb7d5c473U, 0x6231a6c4U, 0xafd9ec43U,
595 0x6a35bed4U, 0x30185060U, 0x04020c08U, 0xc864458dU,
596 0xf9f216efU, 0xfff11ce3U, 0xac56e945U, 0x87cd9413U,
597 0x19822b32U, 0x8dc88a07U, 0x69babbd2U, 0xfdf01ae7U,
598 0xc3ef589bU, 0xcfe94c83U, 0xcde84a87U, 0xe7fd34d3U,
599 0x0f89111eU, 0xb3d7c87bU, 0x93c7a83bU, 0x77b599eeU,
600 0x55a4ffaaU, 0x5e2fe2bcU, 0x3795596eU, 0x26136a4cU,
601 0x160b3a2cU, 0xfbf310ebU, 0xdde07aa7U, 0x6e37b2dcU,
602 };
603
604 static const ulong32 T2[256] = {
605 0xa6f5a753U, 0x6bd0d3bbU, 0xbf6ee6d1U, 0xd93b71e2U,
606 0x67dad0bdU, 0x8acfac45U, 0x29b34d9aU, 0xf90b79f2U,
607 0xe89c3a74U, 0x038cc98fU, 0x7e41913fU, 0xd732fce5U,
608 0x78441e3cU, 0x018f478eU, 0x4de554a8U, 0xcea9bd67U,
609 0x0a0f8c05U, 0xaef9a557U, 0xf5017af4U, 0xcb20fbebU,
610 0x915763c6U, 0xdab7b86dU, 0x53f4dda7U, 0x77c2d4b5U,
611 0xb364e5d7U, 0xf68db37bU, 0x33a4c597U, 0xc2a3be61U,
612 0x9ed1a94fU, 0x1a17880dU, 0x30280c18U, 0xb2eba259U,
613 0xe4963972U, 0x5bf8dfa3U, 0xa4f62952U, 0x4fe6daa9U,
614 0xacfa2b56U, 0x9ad7a84dU, 0x0b80cb8bU, 0x2db54c98U,
615 0x31a74b96U, 0x88cc2244U, 0x92dbaa49U, 0x90d82448U,
616 0x199b4182U, 0xdd3d70e0U, 0xa2f3a651U, 0xc32cf9efU,
617 0x75c15ab4U, 0xaf76e2d9U, 0xfa87b07dU, 0xd8b4366cU,
618 0xe9137dfaU, 0xb762e4d5U, 0xccaa3366U, 0xdb38ffe3U,
619 0x9d5d60c0U, 0x80c02040U, 0x20300810U, 0x161d8b0bU,
620 0x65d95ebcU, 0x96ddab4bU, 0xe11f7ffeU, 0xfd0d78f0U,
621 0xed157cf8U, 0xb0e82c58U, 0x41ef57aeU, 0x6fd6d2b9U,
622 0x57f2dca5U, 0xa9736ddaU, 0xe5197efcU, 0x342e0d1aU,
623 0x51f753a6U, 0x6a5f9435U, 0x2bb0c39bU, 0xa0f02850U,
624 0x9cd2274eU, 0x1814060cU, 0x61df5fbeU, 0x8ec9ad47U,
625 0x814f67ceU, 0x6dd55cb8U, 0x49e355aaU, 0x3dad4890U,
626 0x38240e1cU, 0x55f152a4U, 0x8f46eac9U, 0x15914284U,
627 0x71c75bb6U, 0x69d35dbaU, 0xc0a03060U, 0x7dcd58b0U,
628 0x59fb51a2U, 0x79cb59b2U, 0xf0883c78U, 0x25b94e9cU,
629 0xe0903870U, 0x121b8a09U, 0xd53172e4U, 0x50781428U,
630 0xbb68e7d3U, 0x3faec691U, 0x5ffedea1U, 0x5dfd50a0U,
631 0x02038e01U, 0x724b9239U, 0x63dcd1bfU, 0xc12f77eeU,
632 0x764d933bU, 0x0983458aU, 0x527b9a29U, 0x1f9ece81U,
633 0xb4ee2d5aU, 0x0c0a0306U, 0x955162c4U, 0xe293b671U,
634 0xdeb1b96fU, 0xc6a5bf63U, 0x62539631U, 0xb1676bd6U,
635 0xfc823f7eU, 0x1c12070eU, 0x486c1224U, 0x82c3ae41U,
636 0x1d9d4080U, 0xd0b83468U, 0x0589468cU, 0xf8843e7cU,
637 0x4be0dbabU, 0x1b98cf83U, 0x9752ecc5U, 0x1792cc85U,
638 0x23bcc19fU, 0xbee1a15fU, 0x27bac09dU, 0x7fced6b1U,
639 0x744e1d3aU, 0xf702f4f5U, 0x995b61c2U, 0xec9a3b76U,
640 0x40601020U, 0x47ead8adU, 0xbd6d68d0U, 0xbae7a05dU,
641 0xfe81b17fU, 0x283c0a14U, 0xb96b69d2U, 0xad756cd8U,
642 0x39ab4992U, 0xcf26fae9U, 0xc52976ecU, 0x37a2c495U,
643 0x42639e21U, 0x567d9b2bU, 0xa5796edcU, 0x5e71992fU,
644 0x2fb6c299U, 0xe695b773U, 0x5a77982dU, 0xcaafbc65U,
645 0x06058f03U, 0x2e398517U, 0x7c421f3eU, 0xea9fb475U,
646 0xc72af8edU, 0x44661122U, 0xb8e42e5cU, 0x00000000U,
647 0x94de254aU, 0x70481c38U, 0xa8fc2a54U, 0xf48e3d7aU,
648 0x141e050aU, 0x21bf4f9eU, 0xf1077bf6U, 0xf28bb279U,
649 0xc8ac3264U, 0x7a47903dU, 0x86c5af43U, 0x64561932U,
650 0xb6eda35bU, 0xfb08f7f3U, 0xd13773e6U, 0x4e699d27U,
651 0x547e152aU, 0xcd2574e8U, 0x9f5eeec1U, 0x0f86ca89U,
652 0x46659f23U, 0x3c220f1eU, 0x6c5a1b36U, 0xc92375eaU,
653 0x22338611U, 0x2a3f8415U, 0x4a6f9c25U, 0x35a14a94U,
654 0x66559733U, 0x685c1a34U, 0x894365caU, 0xff0ef6f1U,
655 0x9354edc7U, 0x24360912U, 0xd6bdbb6bU, 0x98d4264cU,
656 0x362d831bU, 0x8b40ebcbU, 0xa17f6fdeU, 0x3e21811fU,
657 0x10180408U, 0xb5616ad4U, 0x11974386U, 0x04060102U,
658 0x5c72172eU, 0xa37ce1dfU, 0x26358713U, 0xf304f5f7U,
659 0x0e098d07U, 0xab70e3dbU, 0x8cca2346U, 0x3a27801dU,
660 0x0d854488U, 0x5874162cU, 0x854966ccU, 0x84c62142U,
661 0xdf3efee1U, 0x73c4d5b7U, 0xc4a63162U, 0x43ecd9afU,
662 0xd4be356aU, 0x60501830U, 0x080c0204U, 0x8d4564c8U,
663 0xef16f2f9U, 0xe31cf1ffU, 0x45e956acU, 0x1394cd87U,
664 0x322b8219U, 0x078ac88dU, 0xd2bbba69U, 0xe71af0fdU,
665 0x9b58efc3U, 0x834ce9cfU, 0x874ae8cdU, 0xd334fde7U,
666 0x1e11890fU, 0x7bc8d7b3U, 0x3ba8c793U, 0xee99b577U,
667 0xaaffa455U, 0xbce22f5eU, 0x6e599537U, 0x4c6a1326U,
668 0x2c3a0b16U, 0xeb10f3fbU, 0xa77ae0ddU, 0xdcb2376eU,
669 };
670
671 static const ulong32 T3[256] = {
672 0xf5a653a7U, 0xd06bbbd3U, 0x6ebfd1e6U, 0x3bd9e271U,
673 0xda67bdd0U, 0xcf8a45acU, 0xb3299a4dU, 0x0bf9f279U,
674 0x9ce8743aU, 0x8c038fc9U, 0x417e3f91U, 0x32d7e5fcU,
675 0x44783c1eU, 0x8f018e47U, 0xe54da854U, 0xa9ce67bdU,
676 0x0f0a058cU, 0xf9ae57a5U, 0x01f5f47aU, 0x20cbebfbU,
677 0x5791c663U, 0xb7da6db8U, 0xf453a7ddU, 0xc277b5d4U,
678 0x64b3d7e5U, 0x8df67bb3U, 0xa43397c5U, 0xa3c261beU,
679 0xd19e4fa9U, 0x171a0d88U, 0x2830180cU, 0xebb259a2U,
680 0x96e47239U, 0xf85ba3dfU, 0xf6a45229U, 0xe64fa9daU,
681 0xfaac562bU, 0xd79a4da8U, 0x800b8bcbU, 0xb52d984cU,
682 0xa731964bU, 0xcc884422U, 0xdb9249aaU, 0xd8904824U,
683 0x9b198241U, 0x3ddde070U, 0xf3a251a6U, 0x2cc3eff9U,
684 0xc175b45aU, 0x76afd9e2U, 0x87fa7db0U, 0xb4d86c36U,
685 0x13e9fa7dU, 0x62b7d5e4U, 0xaacc6633U, 0x38dbe3ffU,
686 0x5d9dc060U, 0xc0804020U, 0x30201008U, 0x1d160b8bU,
687 0xd965bc5eU, 0xdd964babU, 0x1fe1fe7fU, 0x0dfdf078U,
688 0x15edf87cU, 0xe8b0582cU, 0xef41ae57U, 0xd66fb9d2U,
689 0xf257a5dcU, 0x73a9da6dU, 0x19e5fc7eU, 0x2e341a0dU,
690 0xf751a653U, 0x5f6a3594U, 0xb02b9bc3U, 0xf0a05028U,
691 0xd29c4e27U, 0x14180c06U, 0xdf61be5fU, 0xc98e47adU,
692 0x4f81ce67U, 0xd56db85cU, 0xe349aa55U, 0xad3d9048U,
693 0x24381c0eU, 0xf155a452U, 0x468fc9eaU, 0x91158442U,
694 0xc771b65bU, 0xd369ba5dU, 0xa0c06030U, 0xcd7db058U,
695 0xfb59a251U, 0xcb79b259U, 0x88f0783cU, 0xb9259c4eU,
696 0x90e07038U, 0x1b12098aU, 0x31d5e472U, 0x78502814U,
697 0x68bbd3e7U, 0xae3f91c6U, 0xfe5fa1deU, 0xfd5da050U,
698 0x0302018eU, 0x4b723992U, 0xdc63bfd1U, 0x2fc1ee77U,
699 0x4d763b93U, 0x83098a45U, 0x7b52299aU, 0x9e1f81ceU,
700 0xeeb45a2dU, 0x0a0c0603U, 0x5195c462U, 0x93e271b6U,
701 0xb1de6fb9U, 0xa5c663bfU, 0x53623196U, 0x67b1d66bU,
702 0x82fc7e3fU, 0x121c0e07U, 0x6c482412U, 0xc38241aeU,
703 0x9d1d8040U, 0xb8d06834U, 0x89058c46U, 0x84f87c3eU,
704 0xe04babdbU, 0x981b83cfU, 0x5297c5ecU, 0x921785ccU,
705 0xbc239fc1U, 0xe1be5fa1U, 0xba279dc0U, 0xce7fb1d6U,
706 0x4e743a1dU, 0x02f7f5f4U, 0x5b99c261U, 0x9aec763bU,
707 0x60402010U, 0xea47add8U, 0x6dbdd068U, 0xe7ba5da0U,
708 0x81fe7fb1U, 0x3c28140aU, 0x6bb9d269U, 0x75add86cU,
709 0xab399249U, 0x26cfe9faU, 0x29c5ec76U, 0xa23795c4U,
710 0x6342219eU, 0x7d562b9bU, 0x79a5dc6eU, 0x715e2f99U,
711 0xb62f99c2U, 0x95e673b7U, 0x775a2d98U, 0xafca65bcU,
712 0x0506038fU, 0x392e1785U, 0x427c3e1fU, 0x9fea75b4U,
713 0x2ac7edf8U, 0x66442211U, 0xe4b85c2eU, 0x00000000U,
714 0xde944a25U, 0x4870381cU, 0xfca8542aU, 0x8ef47a3dU,
715 0x1e140a05U, 0xbf219e4fU, 0x07f1f67bU, 0x8bf279b2U,
716 0xacc86432U, 0x477a3d90U, 0xc58643afU, 0x56643219U,
717 0xedb65ba3U, 0x08fbf3f7U, 0x37d1e673U, 0x694e279dU,
718 0x7e542a15U, 0x25cde874U, 0x5e9fc1eeU, 0x860f89caU,
719 0x6546239fU, 0x223c1e0fU, 0x5a6c361bU, 0x23c9ea75U,
720 0x33221186U, 0x3f2a1584U, 0x6f4a259cU, 0xa135944aU,
721 0x55663397U, 0x5c68341aU, 0x4389ca65U, 0x0efff1f6U,
722 0x5493c7edU, 0x36241209U, 0xbdd66bbbU, 0xd4984c26U,
723 0x2d361b83U, 0x408bcbebU, 0x7fa1de6fU, 0x213e1f81U,
724 0x18100804U, 0x61b5d46aU, 0x97118643U, 0x06040201U,
725 0x725c2e17U, 0x7ca3dfe1U, 0x35261387U, 0x04f3f7f5U,
726 0x090e078dU, 0x70abdbe3U, 0xca8c4623U, 0x273a1d80U,
727 0x850d8844U, 0x74582c16U, 0x4985cc66U, 0xc6844221U,
728 0x3edfe1feU, 0xc473b7d5U, 0xa6c46231U, 0xec43afd9U,
729 0xbed46a35U, 0x50603018U, 0x0c080402U, 0x458dc864U,
730 0x16eff9f2U, 0x1ce3fff1U, 0xe945ac56U, 0x941387cdU,
731 0x2b321982U, 0x8a078dc8U, 0xbbd269baU, 0x1ae7fdf0U,
732 0x589bc3efU, 0x4c83cfe9U, 0x4a87cde8U, 0x34d3e7fdU,
733 0x111e0f89U, 0xc87bb3d7U, 0xa83b93c7U, 0x99ee77b5U,
734 0xffaa55a4U, 0xe2bc5e2fU, 0x596e3795U, 0x6a4c2613U,
735 0x3a2c160bU, 0x10ebfbf3U, 0x7aa7dde0U, 0xb2dc6e37U,
736 };
737
738 static const ulong32 T4[256] = {
739 0xa7a7a7a7U, 0xd3d3d3d3U, 0xe6e6e6e6U, 0x71717171U,
740 0xd0d0d0d0U, 0xacacacacU, 0x4d4d4d4dU, 0x79797979U,
741 0x3a3a3a3aU, 0xc9c9c9c9U, 0x91919191U, 0xfcfcfcfcU,
742 0x1e1e1e1eU, 0x47474747U, 0x54545454U, 0xbdbdbdbdU,
743 0x8c8c8c8cU, 0xa5a5a5a5U, 0x7a7a7a7aU, 0xfbfbfbfbU,
744 0x63636363U, 0xb8b8b8b8U, 0xddddddddU, 0xd4d4d4d4U,
745 0xe5e5e5e5U, 0xb3b3b3b3U, 0xc5c5c5c5U, 0xbebebebeU,
746 0xa9a9a9a9U, 0x88888888U, 0x0c0c0c0cU, 0xa2a2a2a2U,
747 0x39393939U, 0xdfdfdfdfU, 0x29292929U, 0xdadadadaU,
748 0x2b2b2b2bU, 0xa8a8a8a8U, 0xcbcbcbcbU, 0x4c4c4c4cU,
749 0x4b4b4b4bU, 0x22222222U, 0xaaaaaaaaU, 0x24242424U,
750 0x41414141U, 0x70707070U, 0xa6a6a6a6U, 0xf9f9f9f9U,
751 0x5a5a5a5aU, 0xe2e2e2e2U, 0xb0b0b0b0U, 0x36363636U,
752 0x7d7d7d7dU, 0xe4e4e4e4U, 0x33333333U, 0xffffffffU,
753 0x60606060U, 0x20202020U, 0x08080808U, 0x8b8b8b8bU,
754 0x5e5e5e5eU, 0xababababU, 0x7f7f7f7fU, 0x78787878U,
755 0x7c7c7c7cU, 0x2c2c2c2cU, 0x57575757U, 0xd2d2d2d2U,
756 0xdcdcdcdcU, 0x6d6d6d6dU, 0x7e7e7e7eU, 0x0d0d0d0dU,
757 0x53535353U, 0x94949494U, 0xc3c3c3c3U, 0x28282828U,
758 0x27272727U, 0x06060606U, 0x5f5f5f5fU, 0xadadadadU,
759 0x67676767U, 0x5c5c5c5cU, 0x55555555U, 0x48484848U,
760 0x0e0e0e0eU, 0x52525252U, 0xeaeaeaeaU, 0x42424242U,
761 0x5b5b5b5bU, 0x5d5d5d5dU, 0x30303030U, 0x58585858U,
762 0x51515151U, 0x59595959U, 0x3c3c3c3cU, 0x4e4e4e4eU,
763 0x38383838U, 0x8a8a8a8aU, 0x72727272U, 0x14141414U,
764 0xe7e7e7e7U, 0xc6c6c6c6U, 0xdedededeU, 0x50505050U,
765 0x8e8e8e8eU, 0x92929292U, 0xd1d1d1d1U, 0x77777777U,
766 0x93939393U, 0x45454545U, 0x9a9a9a9aU, 0xcecececeU,
767 0x2d2d2d2dU, 0x03030303U, 0x62626262U, 0xb6b6b6b6U,
768 0xb9b9b9b9U, 0xbfbfbfbfU, 0x96969696U, 0x6b6b6b6bU,
769 0x3f3f3f3fU, 0x07070707U, 0x12121212U, 0xaeaeaeaeU,
770 0x40404040U, 0x34343434U, 0x46464646U, 0x3e3e3e3eU,
771 0xdbdbdbdbU, 0xcfcfcfcfU, 0xececececU, 0xccccccccU,
772 0xc1c1c1c1U, 0xa1a1a1a1U, 0xc0c0c0c0U, 0xd6d6d6d6U,
773 0x1d1d1d1dU, 0xf4f4f4f4U, 0x61616161U, 0x3b3b3b3bU,
774 0x10101010U, 0xd8d8d8d8U, 0x68686868U, 0xa0a0a0a0U,
775 0xb1b1b1b1U, 0x0a0a0a0aU, 0x69696969U, 0x6c6c6c6cU,
776 0x49494949U, 0xfafafafaU, 0x76767676U, 0xc4c4c4c4U,
777 0x9e9e9e9eU, 0x9b9b9b9bU, 0x6e6e6e6eU, 0x99999999U,
778 0xc2c2c2c2U, 0xb7b7b7b7U, 0x98989898U, 0xbcbcbcbcU,
779 0x8f8f8f8fU, 0x85858585U, 0x1f1f1f1fU, 0xb4b4b4b4U,
780 0xf8f8f8f8U, 0x11111111U, 0x2e2e2e2eU, 0x00000000U,
781 0x25252525U, 0x1c1c1c1cU, 0x2a2a2a2aU, 0x3d3d3d3dU,
782 0x05050505U, 0x4f4f4f4fU, 0x7b7b7b7bU, 0xb2b2b2b2U,
783 0x32323232U, 0x90909090U, 0xafafafafU, 0x19191919U,
784 0xa3a3a3a3U, 0xf7f7f7f7U, 0x73737373U, 0x9d9d9d9dU,
785 0x15151515U, 0x74747474U, 0xeeeeeeeeU, 0xcacacacaU,
786 0x9f9f9f9fU, 0x0f0f0f0fU, 0x1b1b1b1bU, 0x75757575U,
787 0x86868686U, 0x84848484U, 0x9c9c9c9cU, 0x4a4a4a4aU,
788 0x97979797U, 0x1a1a1a1aU, 0x65656565U, 0xf6f6f6f6U,
789 0xededededU, 0x09090909U, 0xbbbbbbbbU, 0x26262626U,
790 0x83838383U, 0xebebebebU, 0x6f6f6f6fU, 0x81818181U,
791 0x04040404U, 0x6a6a6a6aU, 0x43434343U, 0x01010101U,
792 0x17171717U, 0xe1e1e1e1U, 0x87878787U, 0xf5f5f5f5U,
793 0x8d8d8d8dU, 0xe3e3e3e3U, 0x23232323U, 0x80808080U,
794 0x44444444U, 0x16161616U, 0x66666666U, 0x21212121U,
795 0xfefefefeU, 0xd5d5d5d5U, 0x31313131U, 0xd9d9d9d9U,
796 0x35353535U, 0x18181818U, 0x02020202U, 0x64646464U,
797 0xf2f2f2f2U, 0xf1f1f1f1U, 0x56565656U, 0xcdcdcdcdU,
798 0x82828282U, 0xc8c8c8c8U, 0xbabababaU, 0xf0f0f0f0U,
799 0xefefefefU, 0xe9e9e9e9U, 0xe8e8e8e8U, 0xfdfdfdfdU,
800 0x89898989U, 0xd7d7d7d7U, 0xc7c7c7c7U, 0xb5b5b5b5U,
801 0xa4a4a4a4U, 0x2f2f2f2fU, 0x95959595U, 0x13131313U,
802 0x0b0b0b0bU, 0xf3f3f3f3U, 0xe0e0e0e0U, 0x37373737U,
803 };
804
805 static const ulong32 T5[256] = {
806 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U,
807 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U,
808 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U,
809 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U,
810 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U,
811 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U,
812 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U,
813 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U,
814 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U,
815 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U,
816 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U,
817 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U,
818 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U,
819 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U,
820 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U,
821 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U,
822 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U,
823 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U,
824 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U,
825 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U,
826 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U,
827 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U,
828 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U,
829 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U,
830 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU,
831 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU,
832 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU,
833 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU,
834 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU,
835 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU,
836 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU,
837 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU,
838 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU,
839 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU,
840 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU,
841 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU,
842 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU,
843 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU,
844 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU,
845 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU,
846 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U,
847 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U,
848 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U,
849 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U,
850 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U,
851 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U,
852 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U,
853 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U,
854 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U,
855 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U,
856 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U,
857 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U,
858 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U,
859 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U,
860 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U,
861 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U,
862 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU,
863 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU,
864 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU,
865 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU,
866 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU,
867 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU,
868 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU,
869 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU,
870 };
871
872 /**
873 * The round constants.
874 */
875 static const ulong32 rc[] = {
876 0xa7d3e671U, 0xd0ac4d79U, 0x3ac991fcU, 0x1e4754bdU,
877 0x8ca57afbU, 0x63b8ddd4U, 0xe5b3c5beU, 0xa9880ca2U,
878 0x39df29daU, 0x2ba8cb4cU, 0x4b22aa24U, 0x4170a6f9U,
879 0x5ae2b036U, 0x7de433ffU, 0x6020088bU, 0x5eab7f78U,
880 0x7c2c57d2U, 0xdc6d7e0dU, 0x5394c328U,
881 };
882
883 #endif
884
885 /**
886 Initialize the Anubis block cipher
887 @param key The symmetric key you wish to pass
888 @param keylen The key length in bytes
889 @param num_rounds The number of rounds desired (0 for default)
890 @param skey The key in as scheduled by this function.
891 @return CRYPT_OK if successful
892 */
893 #ifdef LTC_CLEAN_STACK
894 static int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
895 #else
896 int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
897 #endif
898 {
899 int N, R, i, pos, r;
900 ulong32 kappa[MAX_N];
901 ulong32 inter[MAX_N];
902 ulong32 v, K0, K1, K2, K3;
903
904 LTC_ARGCHK(key != NULL);
905 LTC_ARGCHK(skey != NULL);
906
907 /* Valid sizes (in bytes) are 16, 20, 24, 28, 32, 36, and 40. */
908 if ((keylen & 3) || (keylen < 16) || (keylen > 40)) {
909 return CRYPT_INVALID_KEYSIZE;
910 }
911 skey->anubis.keyBits = keylen*8;
912
913 /*
914 * determine the N length parameter:
915 * (N.B. it is assumed that the key length is valid!)
916 */
917 N = skey->anubis.keyBits >> 5;
918
919 /*
920 * determine number of rounds from key size:
921 */
922 skey->anubis.R = R = 8 + N;
923
924 if (num_rounds != 0 && num_rounds != skey->anubis.R) {
925 return CRYPT_INVALID_ROUNDS;
926 }
927
928 /*
929 * map cipher key to initial key state (mu):
930 */
931 for (i = 0, pos = 0; i < N; i++, pos += 4) {
932 kappa[i] =
933 (key[pos ] << 24) ^
934 (key[pos + 1] << 16) ^
935 (key[pos + 2] << 8) ^
936 (key[pos + 3] );
937 }
938
939 /*
940 * generate R + 1 round keys:
941 */
942 for (r = 0; r <= R; r++) {
943 /*
944 * generate r-th round key K^r:
945 */
946 K0 = T4[(kappa[N - 1] >> 24) & 0xff];
947 K1 = T4[(kappa[N - 1] >> 16) & 0xff];
948 K2 = T4[(kappa[N - 1] >> 8) & 0xff];
949 K3 = T4[(kappa[N - 1] ) & 0xff];
950 for (i = N - 2; i >= 0; i--) {
951 K0 = T4[(kappa[i] >> 24) & 0xff] ^
952 (T5[(K0 >> 24) & 0xff] & 0xff000000U) ^
953 (T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^
954 (T5[(K0 >> 8) & 0xff] & 0x0000ff00U) ^
955 (T5[(K0 ) & 0xff] & 0x000000ffU);
956 K1 = T4[(kappa[i] >> 16) & 0xff] ^
957 (T5[(K1 >> 24) & 0xff] & 0xff000000U) ^
958 (T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^
959 (T5[(K1 >> 8) & 0xff] & 0x0000ff00U) ^
960 (T5[(K1 ) & 0xff] & 0x000000ffU);
961 K2 = T4[(kappa[i] >> 8) & 0xff] ^
962 (T5[(K2 >> 24) & 0xff] & 0xff000000U) ^
963 (T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^
964 (T5[(K2 >> 8) & 0xff] & 0x0000ff00U) ^
965 (T5[(K2 ) & 0xff] & 0x000000ffU);
966 K3 = T4[(kappa[i] ) & 0xff] ^
967 (T5[(K3 >> 24) & 0xff] & 0xff000000U) ^
968 (T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^
969 (T5[(K3 >> 8) & 0xff] & 0x0000ff00U) ^
970 (T5[(K3 ) & 0xff] & 0x000000ffU);
971 }
972 /*
973 -- this is the code to use with the large U tables:
974 K0 = K1 = K2 = K3 = 0;
975 for (i = 0; i < N; i++) {
976 K0 ^= U[i][(kappa[i] >> 24) & 0xff];
977 K1 ^= U[i][(kappa[i] >> 16) & 0xff];
978 K2 ^= U[i][(kappa[i] >> 8) & 0xff];
979 K3 ^= U[i][(kappa[i] ) & 0xff];
980 }
981 */
982 skey->anubis.roundKeyEnc[r][0] = K0;
983 skey->anubis.roundKeyEnc[r][1] = K1;
984 skey->anubis.roundKeyEnc[r][2] = K2;
985 skey->anubis.roundKeyEnc[r][3] = K3;
986
987 /*
988 * compute kappa^{r+1} from kappa^r:
989 */
990 if (r == R) {
991 break;
992 }
993 for (i = 0; i < N; i++) {
994 int j = i;
995 inter[i] = T0[(kappa[j--] >> 24) & 0xff]; if (j < 0) j = N - 1;
996 inter[i] ^= T1[(kappa[j--] >> 16) & 0xff]; if (j < 0) j = N - 1;
997 inter[i] ^= T2[(kappa[j--] >> 8) & 0xff]; if (j < 0) j = N - 1;
998 inter[i] ^= T3[(kappa[j ] ) & 0xff];
999 }
1000 kappa[0] = inter[0] ^ rc[r];
1001 for (i = 1; i < N; i++) {
1002 kappa[i] = inter[i];
1003 }
1004 }
1005
1006 /*
1007 * generate inverse key schedule: K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}):
1008 */
1009 for (i = 0; i < 4; i++) {
1010 skey->anubis.roundKeyDec[0][i] = skey->anubis.roundKeyEnc[R][i];
1011 skey->anubis.roundKeyDec[R][i] = skey->anubis.roundKeyEnc[0][i];
1012 }
1013 for (r = 1; r < R; r++) {
1014 for (i = 0; i < 4; i++) {
1015 v = skey->anubis.roundKeyEnc[R - r][i];
1016 skey->anubis.roundKeyDec[r][i] =
1017 T0[T4[(v >> 24) & 0xff] & 0xff] ^
1018 T1[T4[(v >> 16) & 0xff] & 0xff] ^
1019 T2[T4[(v >> 8) & 0xff] & 0xff] ^
1020 T3[T4[(v ) & 0xff] & 0xff];
1021 }
1022 }
1023
1024 return CRYPT_OK;
1025 }
1026
1027 #ifdef LTC_CLEAN_STACK
1028 int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
1029 {
1030 int err;
1031 err = _anubis_setup(key, keylen, num_rounds, skey);
1032 burn_stack(sizeof(int) * 5 + sizeof(ulong32) * (MAX_N + MAX_N + 5));
1033 return err;
1034 }
1035 #endif
1036
1037
1038 static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext,
1039 ulong32 roundKey[18 + 1][4], int R) {
1040 int i, pos, r;
1041 ulong32 state[4];
1042 ulong32 inter[4];
1043
1044 /*
1045 * map plaintext block to cipher state (mu)
1046 * and add initial round key (sigma[K^0]):
1047 */
1048 for (i = 0, pos = 0; i < 4; i++, pos += 4) {
1049 state[i] =
1050 (plaintext[pos ] << 24) ^
1051 (plaintext[pos + 1] << 16) ^
1052 (plaintext[pos + 2] << 8) ^
1053 (plaintext[pos + 3] ) ^
1054 roundKey[0][i];
1055 }
1056
1057 /*
1058 * R - 1 full rounds:
1059 */
1060 for (r = 1; r < R; r++) {
1061 inter[0] =
1062 T0[(state[0] >> 24) & 0xff] ^
1063 T1[(state[1] >> 24) & 0xff] ^
1064 T2[(state[2] >> 24) & 0xff] ^
1065 T3[(state[3] >> 24) & 0xff] ^
1066 roundKey[r][0];
1067 inter[1] =
1068 T0[(state[0] >> 16) & 0xff] ^
1069 T1[(state[1] >> 16) & 0xff] ^
1070 T2[(state[2] >> 16) & 0xff] ^
1071 T3[(state[3] >> 16) & 0xff] ^
1072 roundKey[r][1];
1073 inter[2] =
1074 T0[(state[0] >> 8) & 0xff] ^
1075 T1[(state[1] >> 8) & 0xff] ^
1076 T2[(state[2] >> 8) & 0xff] ^
1077 T3[(state[3] >> 8) & 0xff] ^
1078 roundKey[r][2];
1079 inter[3] =
1080 T0[(state[0] ) & 0xff] ^
1081 T1[(state[1] ) & 0xff] ^
1082 T2[(state[2] ) & 0xff] ^
1083 T3[(state[3] ) & 0xff] ^
1084 roundKey[r][3];
1085 state[0] = inter[0];
1086 state[1] = inter[1];
1087 state[2] = inter[2];
1088 state[3] = inter[3];
1089 }
1090
1091 /*
1092 * last round:
1093 */
1094 inter[0] =
1095 (T0[(state[0] >> 24) & 0xff] & 0xff000000U) ^
1096 (T1[(state[1] >> 24) & 0xff] & 0x00ff0000U) ^
1097 (T2[(state[2] >> 24) & 0xff] & 0x0000ff00U) ^
1098 (T3[(state[3] >> 24) & 0xff] & 0x000000ffU) ^
1099 roundKey[R][0];
1100 inter[1] =
1101 (T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^
1102 (T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^
1103 (T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^
1104 (T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^
1105 roundKey[R][1];
1106 inter[2] =
1107 (T0[(state[0] >> 8) & 0xff] & 0xff000000U) ^
1108 (T1[(state[1] >> 8) & 0xff] & 0x00ff0000U) ^
1109 (T2[(state[2] >> 8) & 0xff] & 0x0000ff00U) ^
1110 (T3[(state[3] >> 8) & 0xff] & 0x000000ffU) ^
1111 roundKey[R][2];
1112 inter[3] =
1113 (T0[(state[0] ) & 0xff] & 0xff000000U) ^
1114 (T1[(state[1] ) & 0xff] & 0x00ff0000U) ^
1115 (T2[(state[2] ) & 0xff] & 0x0000ff00U) ^
1116 (T3[(state[3] ) & 0xff] & 0x000000ffU) ^
1117 roundKey[R][3];
1118
1119 /*
1120 * map cipher state to ciphertext block (mu^{-1}):
1121 */
1122 for (i = 0, pos = 0; i < 4; i++, pos += 4) {
1123 ulong32 w = inter[i];
1124 ciphertext[pos ] = (unsigned char)(w >> 24);
1125 ciphertext[pos + 1] = (unsigned char)(w >> 16);
1126 ciphertext[pos + 2] = (unsigned char)(w >> 8);
1127 ciphertext[pos + 3] = (unsigned char)(w );
1128 }
1129 }
1130
1131 /**
1132 Encrypts a block of text with Anubis
1133 @param pt The input plaintext (16 bytes)
1134 @param ct The output ciphertext (16 bytes)
1135 @param skey The key as scheduled
1136 @return CRYPT_OK if successful
1137 */
1138 int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
1139 {
1140 LTC_ARGCHK(pt != NULL);
1141 LTC_ARGCHK(ct != NULL);
1142 LTC_ARGCHK(skey != NULL);
1143 anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R);
1144 return CRYPT_OK;
1145 }
1146
1147 /**
1148 Decrypts a block of text with Anubis
1149 @param ct The input ciphertext (16 bytes)
1150 @param pt The output plaintext (16 bytes)
1151 @param skey The key as scheduled
1152 @return CRYPT_OK if successful
1153 */
1154 int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
1155 {
1156 LTC_ARGCHK(pt != NULL);
1157 LTC_ARGCHK(ct != NULL);
1158 LTC_ARGCHK(skey != NULL);
1159 anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R);
1160 return CRYPT_OK;
1161 }
1162
1163 /**
1164 Performs a self-test of the Anubis block cipher
1165 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
1166 */
1167 int anubis_test(void)
1168 {
1169 #if !defined(LTC_TEST)
1170 return CRYPT_NOP;
1171 #else
1172 static const struct test {
1173 int keylen;
1174 unsigned char pt[16], ct[16], key[40];
1175 } tests[] = {
1176 #ifndef LTC_ANUBIS_TWEAK
1177 /**** ORIGINAL LTC_ANUBIS ****/
1178 /* 128 bit keys */
1179 {
1180 16,
1181 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1183 { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18,
1184 0xF1, 0x32, 0xC7, 0x8A, 0xF4, 0x13, 0x2A, 0xFE },
1185 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1187 }, {
1188 16,
1189 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1191 { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89,
1192 0xFC, 0x5E, 0xB5, 0xBA, 0xD4, 0xFE, 0x32, 0x6D },
1193 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1195 },
1196
1197 /* 160-bit keys */
1198 {
1199 20,
1200 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1202 { 0xBD, 0x5E, 0x32, 0xBE, 0x51, 0x67, 0xA8, 0xE2,
1203 0x72, 0xD7, 0x95, 0x0F, 0x83, 0xC6, 0x8C, 0x31 },
1204 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1206 0x00, 0x00, 0x00, 0x00 }
1207 }, {
1208 20,
1209 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1211 { 0x4C, 0x1F, 0x86, 0x2E, 0x11, 0xEB, 0xCE, 0xEB,
1212 0xFE, 0xB9, 0x73, 0xC9, 0xDF, 0xEF, 0x7A, 0xDB },
1213 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1215 0x00, 0x00, 0x00, 0x01 }
1216 },
1217
1218 /* 192-bit keys */
1219 {
1220 24,
1221 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1223 { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66,
1224 0xD0, 0xC7, 0x9E, 0x04, 0x7C, 0xC7, 0x58, 0xF0 },
1225 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1228 }, {
1229 24,
1230 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1232 { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD,
1233 0x57, 0x14, 0x5F, 0x57, 0x04, 0x9F, 0x70, 0x74 },
1234 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1237 },
1238
1239 /* 224-bit keys */
1240 {
1241 28,
1242 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1244 { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B,
1245 0xEF, 0x08, 0xE8, 0x7A, 0x58, 0xD6, 0xF8, 0x53 },
1246 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x00 }
1250 }, {
1251 28,
1252 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1254 { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53,
1255 0x8B, 0xC4, 0x32, 0x6A, 0xF5, 0xB9, 0x1B, 0x5F },
1256 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1259 0x00, 0x00, 0x00, 0x01 }
1260 },
1261
1262 /* 256-bit keys */
1263 {
1264 32,
1265 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1267 { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13,
1268 0xED, 0xF5, 0xDF, 0xDD, 0xD6, 0x3B, 0x71, 0x93 },
1269 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1273 }, {
1274 32,
1275 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1277 { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29,
1278 0x00, 0xD5, 0xEC, 0x98, 0x2B, 0x9E, 0xE8, 0x21 },
1279 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1282 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1283 },
1284
1285 /* 288-bit keys */
1286 {
1287 36,
1288 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1290 { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B,
1291 0x41, 0x95, 0xB9, 0x71, 0x75, 0x79, 0x04, 0x7C },
1292 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1296 0x00, 0x00, 0x00, 0x00 }
1297 }, {
1298 36,
1299 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1301 { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2,
1302 0xBD, 0xA7, 0xA7, 0x53, 0xAB, 0x40, 0x22, 0xE0 },
1303 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307 0x00, 0x00, 0x00, 0x01 }
1308 },
1309
1310 /* 320-bit keys */
1311 {
1312 40,
1313 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1315 { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02,
1316 0x4B, 0xCC, 0x39, 0x80, 0xD8, 0x22, 0xEA, 0xA4 },
1317 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1322 }, {
1323 40,
1324 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1326 { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0,
1327 0x44, 0xA8, 0x3C, 0x73, 0x81, 0x7E, 0x53, 0xD8 },
1328 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1333 }
1334 #else
1335 /**** Tweaked LTC_ANUBIS ****/
1336 /* 128 bit keys */
1337 {
1338 16,
1339 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1341 { 0xB8, 0x35, 0xBD, 0xC3, 0x34, 0x82, 0x9D, 0x83,
1342 0x71, 0xBF, 0xA3, 0x71, 0xE4, 0xB3, 0xC4, 0xFD },
1343 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1345 }, {
1346 16,
1347 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1349 { 0xE6, 0x14, 0x1E, 0xAF, 0xEB, 0xE0, 0x59, 0x3C,
1350 0x48, 0xE1, 0xCD, 0xF2, 0x1B, 0xBA, 0xA1, 0x89 },
1351 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1353 },
1354
1355 /* 160-bit keys */
1356 {
1357 20,
1358 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1360 { 0x97, 0x59, 0x79, 0x4B, 0x5C, 0xA0, 0x70, 0x73,
1361 0x24, 0xEF, 0xB3, 0x58, 0x67, 0xCA, 0xD4, 0xB3 },
1362 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00 }
1365 }, {
1366 20,
1367 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1369 { 0xB8, 0x0D, 0xFB, 0x9B, 0xE4, 0xA1, 0x58, 0x87,
1370 0xB3, 0x76, 0xD5, 0x02, 0x18, 0x95, 0xC1, 0x2E },
1371 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373 0x00, 0x00, 0x00, 0x01 }
1374 },
1375
1376 /* 192-bit keys */
1377 {
1378 24,
1379 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1381 { 0x7D, 0x62, 0x3B, 0x52, 0xC7, 0x4C, 0x64, 0xD8,
1382 0xEB, 0xC7, 0x2D, 0x57, 0x97, 0x85, 0x43, 0x8F },
1383 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1386 }, {
1387 24,
1388 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1390 { 0xB1, 0x0A, 0x59, 0xDD, 0x5D, 0x5D, 0x8D, 0x67,
1391 0xEC, 0xEE, 0x4A, 0xC4, 0xBE, 0x4F, 0xA8, 0x4F },
1392 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1395 },
1396
1397 /* 224-bit keys */
1398 {
1399 28,
1400 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1402 { 0x68, 0x9E, 0x05, 0x94, 0x6A, 0x94, 0x43, 0x8F,
1403 0xE7, 0x8E, 0x37, 0x3D, 0x24, 0x97, 0x92, 0xF5 },
1404 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1407 0x00, 0x00, 0x00, 0x00 }
1408 }, {
1409 28,
1410 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1412 { 0xDD, 0xB7, 0xB0, 0xB4, 0xE9, 0xB4, 0x9B, 0x9C,
1413 0x38, 0x20, 0x25, 0x0B, 0x47, 0xC2, 0x1F, 0x89 },
1414 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1417 0x00, 0x00, 0x00, 0x01 }
1418 },
1419
1420 /* 256-bit keys */
1421 {
1422 32,
1423 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1425 { 0x96, 0x00, 0xF0, 0x76, 0x91, 0x69, 0x29, 0x87,
1426 0xF5, 0xE5, 0x97, 0xDB, 0xDB, 0xAF, 0x1B, 0x0A },
1427 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1431 }, {
1432 32,
1433 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1435 { 0x69, 0x9C, 0xAF, 0xDD, 0x94, 0xC7, 0xBC, 0x60,
1436 0x44, 0xFE, 0x02, 0x05, 0x8A, 0x6E, 0xEF, 0xBD },
1437 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1441 },
1442
1443 /* 288-bit keys */
1444 {
1445 36,
1446 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1448 { 0x0F, 0xC7, 0xA2, 0xC0, 0x11, 0x17, 0xAC, 0x43,
1449 0x52, 0x5E, 0xDF, 0x6C, 0xF3, 0x96, 0x33, 0x6C },
1450 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1454 0x00, 0x00, 0x00, 0x00 }
1455 }, {
1456 36,
1457 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1459 { 0xAD, 0x08, 0x4F, 0xED, 0x55, 0xA6, 0x94, 0x3E,
1460 0x7E, 0x5E, 0xED, 0x05, 0xA1, 0x9D, 0x41, 0xB4 },
1461 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1465 0x00, 0x00, 0x00, 0x01 }
1466 },
1467
1468 /* 320-bit keys */
1469 {
1470 40,
1471 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1473 { 0xFE, 0xE2, 0x0E, 0x2A, 0x9D, 0xC5, 0x83, 0xBA,
1474 0xA3, 0xA6, 0xD6, 0xA6, 0xF2, 0xE8, 0x06, 0xA5 },
1475 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1480 }, {
1481 40,
1482 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1484 { 0x86, 0x3D, 0xCC, 0x4A, 0x60, 0x34, 0x9C, 0x28,
1485 0xA7, 0xDA, 0xA4, 0x3B, 0x0A, 0xD7, 0xFD, 0xC7 },
1486 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1491 }
1492 #endif
1493 };
1494 int x, y;
1495 unsigned char buf[2][16];
1496 symmetric_key skey;
1497
1498 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
1499 anubis_setup(tests[x].key, tests[x].keylen, 0, &skey);
1500 anubis_ecb_encrypt(tests[x].pt, buf[0], &skey);
1501 anubis_ecb_decrypt(buf[0], buf[1], &skey);
1502 if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) {
1503 return CRYPT_FAIL_TESTVECTOR;
1504 }
1505
1506 for (y = 0; y < 1000; y++) anubis_ecb_encrypt(buf[0], buf[0], &skey);
1507 for (y = 0; y < 1000; y++) anubis_ecb_decrypt(buf[0], buf[0], &skey);
1508 if (XMEMCMP(buf[0], tests[x].ct, 16)) {
1509 return CRYPT_FAIL_TESTVECTOR;
1510 }
1511
1512 }
1513 return CRYPT_OK;
1514 #endif
1515 }
1516
1517 /** Terminate the context
1518 @param skey The scheduled key
1519 */
1520 void anubis_done(symmetric_key *skey)
1521 {
1522 }
1523
1524 /**
1525 Gets suitable key size
1526 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
1527 @return CRYPT_OK if the input key size is acceptable.
1528 */
1529 int anubis_keysize(int *keysize)
1530 {
1531 LTC_ARGCHK(keysize != NULL);
1532 if (*keysize >= 40) {
1533 *keysize = 40;
1534 } else if (*keysize >= 36) {
1535 *keysize = 36;
1536 } else if (*keysize >= 32) {
1537 *keysize = 32;
1538 } else if (*keysize >= 28) {
1539 *keysize = 28;
1540 } else if (*keysize >= 24) {
1541 *keysize = 24;
1542 } else if (*keysize >= 20) {
1543 *keysize = 20;
1544 } else if (*keysize >= 16) {
1545 *keysize = 16;
1546 } else {
1547 return CRYPT_INVALID_KEYSIZE;
1548 }
1549 return CRYPT_OK;
1550 }
1551
1552 #endif
1553
1554
1555 /* $Source$ */
1556 /* $Revision$ */
1557 /* $Date$ */
+0
-594
libtom-src/ciphers/blowfish.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @file blowfish.c
12 Implementation of the Blowfish block cipher, Tom St Denis
13 */
14 #include "tomcrypt.h"
15
16 #ifdef LTC_BLOWFISH
17
18 const struct ltc_cipher_descriptor blowfish_desc =
19 {
20 "blowfish",
21 0,
22 8, 56, 8, 16,
23 &blowfish_setup,
24 &blowfish_ecb_encrypt,
25 &blowfish_ecb_decrypt,
26 &blowfish_test,
27 &blowfish_done,
28 &blowfish_keysize,
29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
30 };
31
32 static const ulong32 ORIG_P[16 + 2] = {
33 0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL,
34 0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL,
35 0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL,
36 0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL,
37 0x9216D5D9UL, 0x8979FB1BUL
38 };
39
40 static const ulong32 ORIG_S[4][256] = {
41 { 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL,
42 0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL,
43 0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL,
44 0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL,
45 0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL,
46 0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL,
47 0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL,
48 0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL,
49 0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL,
50 0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL,
51 0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL,
52 0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL,
53 0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL,
54 0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL,
55 0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL,
56 0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL,
57 0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL,
58 0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL,
59 0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL,
60 0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL,
61 0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL,
62 0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL,
63 0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL,
64 0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL,
65 0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL,
66 0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL,
67 0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL,
68 0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL,
69 0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL,
70 0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL,
71 0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL,
72 0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL,
73 0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL,
74 0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL,
75 0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL,
76 0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL,
77 0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL,
78 0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL,
79 0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL,
80 0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL,
81 0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL,
82 0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL,
83 0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL,
84 0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL,
85 0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL,
86 0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL,
87 0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL,
88 0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL,
89 0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL,
90 0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL,
91 0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL,
92 0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL,
93 0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL,
94 0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL,
95 0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL,
96 0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL,
97 0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL,
98 0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL,
99 0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL,
100 0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL,
101 0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL,
102 0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL,
103 0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL,
104 0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL },
105 { 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL,
106 0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL,
107 0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL,
108 0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL,
109 0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL,
110 0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL,
111 0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL,
112 0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL,
113 0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL,
114 0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL,
115 0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL,
116 0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL,
117 0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL,
118 0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL,
119 0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL,
120 0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL,
121 0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL,
122 0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL,
123 0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL,
124 0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL,
125 0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL,
126 0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL,
127 0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL,
128 0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL,
129 0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL,
130 0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL,
131 0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL,
132 0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL,
133 0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL,
134 0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL,
135 0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL,
136 0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL,
137 0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL,
138 0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL,
139 0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL,
140 0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL,
141 0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL,
142 0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL,
143 0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL,
144 0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL,
145 0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL,
146 0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL,
147 0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL,
148 0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL,
149 0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL,
150 0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL,
151 0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL,
152 0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL,
153 0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL,
154 0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL,
155 0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL,
156 0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL,
157 0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL,
158 0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL,
159 0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL,
160 0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL,
161 0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL,
162 0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL,
163 0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL,
164 0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL,
165 0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL,
166 0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL,
167 0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL,
168 0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL },
169 { 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL,
170 0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL,
171 0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL,
172 0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL,
173 0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL,
174 0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL,
175 0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL,
176 0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL,
177 0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL,
178 0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL,
179 0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL,
180 0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL,
181 0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL,
182 0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL,
183 0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL,
184 0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL,
185 0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL,
186 0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL,
187 0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL,
188 0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL,
189 0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL,
190 0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL,
191 0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL,
192 0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL,
193 0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL,
194 0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL,
195 0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL,
196 0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL,
197 0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL,
198 0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL,
199 0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL,
200 0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL,
201 0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL,
202 0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL,
203 0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL,
204 0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL,
205 0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL,
206 0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL,
207 0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL,
208 0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL,
209 0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL,
210 0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL,
211 0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL,
212 0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL,
213 0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL,
214 0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL,
215 0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL,
216 0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL,
217 0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL,
218 0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL,
219 0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL,
220 0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL,
221 0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL,
222 0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL,
223 0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL,
224 0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL,
225 0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL,
226 0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL,
227 0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL,
228 0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL,
229 0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL,
230 0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL,
231 0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL,
232 0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL },
233 { 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL,
234 0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL,
235 0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL,
236 0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL,
237 0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL,
238 0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL,
239 0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL,
240 0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL,
241 0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL,
242 0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL,
243 0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL,
244 0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL,
245 0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL,
246 0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL,
247 0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL,
248 0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL,
249 0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL,
250 0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL,
251 0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL,
252 0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL,
253 0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL,
254 0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL,
255 0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL,
256 0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL,
257 0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL,
258 0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL,
259 0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL,
260 0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL,
261 0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL,
262 0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL,
263 0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL,
264 0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL,
265 0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL,
266 0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL,
267 0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL,
268 0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL,
269 0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL,
270 0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL,
271 0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL,
272 0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL,
273 0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL,
274 0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL,
275 0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL,
276 0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL,
277 0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL,
278 0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL,
279 0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL,
280 0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL,
281 0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL,
282 0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL,
283 0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL,
284 0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL,
285 0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL,
286 0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL,
287 0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL,
288 0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL,
289 0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL,
290 0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL,
291 0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL,
292 0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL,
293 0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL,
294 0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL,
295 0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL,
296 0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL }
297 };
298
299 /**
300 Initialize the Blowfish block cipher
301 @param key The symmetric key you wish to pass
302 @param keylen The key length in bytes
303 @param num_rounds The number of rounds desired (0 for default)
304 @param skey The key in as scheduled by this function.
305 @return CRYPT_OK if successful
306 */
307 int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
308 symmetric_key *skey)
309 {
310 ulong32 x, y, z, A;
311 unsigned char B[8];
312
313 LTC_ARGCHK(key != NULL);
314 LTC_ARGCHK(skey != NULL);
315
316 /* check key length */
317 if (keylen < 8 || keylen > 56) {
318 return CRYPT_INVALID_KEYSIZE;
319 }
320
321 /* check rounds */
322 if (num_rounds != 0 && num_rounds != 16) {
323 return CRYPT_INVALID_ROUNDS;
324 }
325
326 /* load in key bytes (Supplied by David Hopwood) */
327 for (x = y = 0; x < 18; x++) {
328 A = 0;
329 for (z = 0; z < 4; z++) {
330 A = (A << 8) | ((ulong32)key[y++] & 255);
331 if (y == (ulong32)keylen) {
332 y = 0;
333 }
334 }
335 skey->blowfish.K[x] = ORIG_P[x] ^ A;
336 }
337
338 /* copy sboxes */
339 for (x = 0; x < 4; x++) {
340 for (y = 0; y < 256; y++) {
341 skey->blowfish.S[x][y] = ORIG_S[x][y];
342 }
343 }
344
345 /* encrypt K array */
346 for (x = 0; x < 8; x++) {
347 B[x] = 0;
348 }
349
350 for (x = 0; x < 18; x += 2) {
351 /* encrypt it */
352 blowfish_ecb_encrypt(B, B, skey);
353 /* copy it */
354 LOAD32H(skey->blowfish.K[x], &B[0]);
355 LOAD32H(skey->blowfish.K[x+1], &B[4]);
356 }
357
358 /* encrypt S array */
359 for (x = 0; x < 4; x++) {
360 for (y = 0; y < 256; y += 2) {
361 /* encrypt it */
362 blowfish_ecb_encrypt(B, B, skey);
363 /* copy it */
364 LOAD32H(skey->blowfish.S[x][y], &B[0]);
365 LOAD32H(skey->blowfish.S[x][y+1], &B[4]);
366 }
367 }
368
369 #ifdef LTC_CLEAN_STACK
370 zeromem(B, sizeof(B));
371 #endif
372
373 return CRYPT_OK;
374 }
375
376 #ifndef __GNUC__
377 #define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)]
378 #else
379 #define F(x) ((skey->blowfish.S[0][byte(x,3)] + skey->blowfish.S[1][byte(x,2)]) ^ skey->blowfish.S[2][byte(x,1)]) + skey->blowfish.S[3][byte(x,0)]
380 #endif
381
382 /**
383 Encrypts a block of text with Blowfish
384 @param pt The input plaintext (8 bytes)
385 @param ct The output ciphertext (8 bytes)
386 @param skey The key as scheduled
387 @return CRYPT_OK if successful
388 */
389 #ifdef LTC_CLEAN_STACK
390 static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
391 #else
392 int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
393 #endif
394 {
395 ulong32 L, R;
396 int r;
397 #ifndef __GNUC__
398 ulong32 *S1, *S2, *S3, *S4;
399 #endif
400
401 LTC_ARGCHK(pt != NULL);
402 LTC_ARGCHK(ct != NULL);
403 LTC_ARGCHK(skey != NULL);
404
405 #ifndef __GNUC__
406 S1 = skey->blowfish.S[0];
407 S2 = skey->blowfish.S[1];
408 S3 = skey->blowfish.S[2];
409 S4 = skey->blowfish.S[3];
410 #endif
411
412 /* load it */
413 LOAD32H(L, &pt[0]);
414 LOAD32H(R, &pt[4]);
415
416 /* do 16 rounds */
417 for (r = 0; r < 16; ) {
418 L ^= skey->blowfish.K[r++]; R ^= F(L);
419 R ^= skey->blowfish.K[r++]; L ^= F(R);
420 L ^= skey->blowfish.K[r++]; R ^= F(L);
421 R ^= skey->blowfish.K[r++]; L ^= F(R);
422 }
423
424 /* last keying */
425 R ^= skey->blowfish.K[17];
426 L ^= skey->blowfish.K[16];
427
428 /* store */
429 STORE32H(R, &ct[0]);
430 STORE32H(L, &ct[4]);
431
432 return CRYPT_OK;
433 }
434
435 #ifdef LTC_CLEAN_STACK
436 int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
437 {
438 int err = _blowfish_ecb_encrypt(pt, ct, skey);
439 burn_stack(sizeof(ulong32) * 2 + sizeof(int));
440 return err;
441 }
442 #endif
443
444 /**
445 Decrypts a block of text with Blowfish
446 @param ct The input ciphertext (8 bytes)
447 @param pt The output plaintext (8 bytes)
448 @param skey The key as scheduled
449 @return CRYPT_OK if successful
450 */
451 #ifdef LTC_CLEAN_STACK
452 static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
453 #else
454 int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
455 #endif
456 {
457 ulong32 L, R;
458 int r;
459 #ifndef __GNUC__
460 ulong32 *S1, *S2, *S3, *S4;
461 #endif
462
463 LTC_ARGCHK(pt != NULL);
464 LTC_ARGCHK(ct != NULL);
465 LTC_ARGCHK(skey != NULL);
466
467 #ifndef __GNUC__
468 S1 = skey->blowfish.S[0];
469 S2 = skey->blowfish.S[1];
470 S3 = skey->blowfish.S[2];
471 S4 = skey->blowfish.S[3];
472 #endif
473
474 /* load it */
475 LOAD32H(R, &ct[0]);
476 LOAD32H(L, &ct[4]);
477
478 /* undo last keying */
479 R ^= skey->blowfish.K[17];
480 L ^= skey->blowfish.K[16];
481
482 /* do 16 rounds */
483 for (r = 15; r > 0; ) {
484 L ^= F(R); R ^= skey->blowfish.K[r--];
485 R ^= F(L); L ^= skey->blowfish.K[r--];
486 L ^= F(R); R ^= skey->blowfish.K[r--];
487 R ^= F(L); L ^= skey->blowfish.K[r--];
488 }
489
490 /* store */
491 STORE32H(L, &pt[0]);
492 STORE32H(R, &pt[4]);
493 return CRYPT_OK;
494 }
495
496 #ifdef LTC_CLEAN_STACK
497 int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
498 {
499 int err = _blowfish_ecb_decrypt(ct, pt, skey);
500 burn_stack(sizeof(ulong32) * 2 + sizeof(int));
501 return err;
502 }
503 #endif
504
505
506 /**
507 Performs a self-test of the Blowfish block cipher
508 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
509 */
510 int blowfish_test(void)
511 {
512 #ifndef LTC_TEST
513 return CRYPT_NOP;
514 #else
515 int err;
516 symmetric_key key;
517 static const struct {
518 unsigned char key[8], pt[8], ct[8];
519 } tests[] = {
520 {
521 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
522 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
523 { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}
524 },
525 {
526 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
527 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
528 { 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}
529 },
530 {
531 { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
532 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
533 { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}
534 }
535 };
536 unsigned char tmp[2][8];
537 int x, y;
538
539 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
540 /* setup key */
541 if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) {
542 return err;
543 }
544
545 /* encrypt and decrypt */
546 blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key);
547 blowfish_ecb_decrypt(tmp[0], tmp[1], &key);
548
549 /* compare */
550 if ((XMEMCMP(tmp[0], tests[x].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[x].pt, 8) != 0)) {
551 return CRYPT_FAIL_TESTVECTOR;
552 }
553
554 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
555 for (y = 0; y < 8; y++) tmp[0][y] = 0;
556 for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key);
557 for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key);
558 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
559 }
560 return CRYPT_OK;
561 #endif
562 }
563
564 /** Terminate the context
565 @param skey The scheduled key
566 */
567 void blowfish_done(symmetric_key *skey)
568 {
569 }
570
571 /**
572 Gets suitable key size
573 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
574 @return CRYPT_OK if the input key size is acceptable.
575 */
576 int blowfish_keysize(int *keysize)
577 {
578 LTC_ARGCHK(keysize != NULL);
579
580 if (*keysize < 8) {
581 return CRYPT_INVALID_KEYSIZE;
582 } else if (*keysize > 56) {
583 *keysize = 56;
584 }
585 return CRYPT_OK;
586 }
587
588 #endif
589
590
591 /* $Source$ */
592 /* $Revision$ */
593 /* $Date$ */
+0
-725
libtom-src/ciphers/camellia.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file camellia.c
13 Implementation by Tom St Denis of Elliptic Semiconductor
14 */
15
16 #include "tomcrypt.h"
17
18 #ifdef LTC_CAMELLIA
19
20 const struct ltc_cipher_descriptor camellia_desc = {
21 "camellia",
22 23,
23 16, 32, 16, 18,
24 &camellia_setup,
25 &camellia_ecb_encrypt,
26 &camellia_ecb_decrypt,
27 &camellia_test,
28 &camellia_done,
29 &camellia_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 static const ulong32 SP1110[] = {
34 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500,
35 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100,
36 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
37 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00,
38 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00,
39 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
40 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00,
41 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00,
42 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
43 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900,
44 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500,
45 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
46 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00,
47 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200,
48 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
49 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000,
50 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700,
51 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
52 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00,
53 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400,
54 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
55 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200,
56 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00,
57 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
58 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00,
59 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900,
60 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
61 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00,
62 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00,
63 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
64 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
65 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
66 };
67
68 static const ulong32 SP0222[] = {
69 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb,
70 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282,
71 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
72 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b,
73 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d,
74 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
75 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a,
76 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a,
77 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
78 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333,
79 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a,
80 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
81 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838,
82 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444,
83 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
84 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0,
85 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f,
86 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
87 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7,
88 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929,
89 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
90 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5,
91 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676,
92 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
93 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d,
94 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2,
95 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
96 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5,
97 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414,
98 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
99 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383,
100 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
101 };
102
103 static const ulong32 SP3033[] = {
104 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2,
105 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0,
106 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
107 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede,
108 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767,
109 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
110 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e,
111 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6,
112 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
113 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc,
114 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282,
115 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
116 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e,
117 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111,
118 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
119 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828,
120 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb,
121 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
122 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded,
123 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a,
124 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
125 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171,
126 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d,
127 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
128 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747,
129 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac,
130 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
131 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d,
132 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505,
133 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
134 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
135 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
136 };
137
138 static const ulong32 SP4404[] = {
139 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae,
140 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092,
141 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
142 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c,
143 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084,
144 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
145 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2,
146 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069,
147 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
148 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd,
149 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf,
150 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
151 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4,
152 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d,
153 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
154 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080,
155 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041,
156 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
157 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a,
158 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d,
159 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
160 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7,
161 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022,
162 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
163 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2,
164 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094,
165 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
166 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e,
167 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059,
168 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
169 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
170 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
171 };
172
173 static ulong64 key_sigma[] = {
174 CONST64(0xA09E667F3BCC908B),
175 CONST64(0xB67AE8584CAA73B2),
176 CONST64(0xC6EF372FE94F82BE),
177 CONST64(0x54FF53A5F1D36F1C),
178 CONST64(0x10E527FADE682D1D),
179 CONST64(0xB05688C2B3E6C1FD)
180 };
181
182 static ulong64 F(ulong64 x)
183 {
184 ulong32 D, U;
185
186 #define loc(i) ((8-i)*8)
187
188 D = SP1110[(x >> loc(8)) & 0xFF] ^ SP0222[(x >> loc(5)) & 0xFF] ^ SP3033[(x >> loc(6)) & 0xFF] ^ SP4404[(x >> loc(7)) & 0xFF];
189 U = SP1110[(x >> loc(1)) & 0xFF] ^ SP0222[(x >> loc(2)) & 0xFF] ^ SP3033[(x >> loc(3)) & 0xFF] ^ SP4404[(x >> loc(4)) & 0xFF];
190
191 D ^= U;
192 U = D ^ ROR(U, (const int)8);
193
194 return ((ulong64)U) | (((ulong64)D) << CONST64(32));
195 }
196
197 static void rot_128(unsigned char *in, unsigned count, unsigned char *out)
198 {
199 unsigned x, w, b;
200
201 w = count >> 3;
202 b = count & 7;
203
204 for (x = 0; x < 16; x++) {
205 out[x] = (in[(x+w)&15] << b) | (in[(x+w+1)&15] >> (8 - b));
206 }
207 }
208
209 int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
210 {
211 unsigned char T[48], kA[16], kB[16], kR[16], kL[16];
212 int x;
213 ulong64 A, B;
214
215 // LTC_ARGCHK(key != NULL);
216 // LTC_ARGCHK(skey != NULL);
217
218 /* Valid sizes (in bytes) are 16, 24, 32 */
219 if (keylen != 16 && keylen != 24 && keylen != 32) {
220 return CRYPT_INVALID_KEYSIZE;
221 }
222
223 /* number of rounds */
224 skey->camellia.R = (keylen == 16) ? 18 : 24;
225
226 if (num_rounds != 0 && num_rounds != skey->camellia.R) {
227 return CRYPT_INVALID_ROUNDS;
228 }
229
230 /* expand key */
231 if (keylen == 16) {
232 for (x = 0; x < 16; x++) {
233 T[x] = key[x];
234 T[x + 16] = 0;
235 }
236 } else if (keylen == 24) {
237 for (x = 0; x < 24; x++) {
238 T[x] = key[x];
239 }
240 for (x = 24; x < 32; x++) {
241 T[x] = key[x-8] ^ 0xFF;
242 }
243 } else {
244 for (x = 0; x < 32; x++) {
245 T[x] = key[x];
246 }
247 }
248
249 for (x = 0; x < 16; x++) {
250 kL[x] = T[x];
251 kR[x] = T[x + 16];
252 }
253
254 for (x = 32; x < 48; x++) {
255 T[x] = T[x - 32] ^ T[x - 16];
256 }
257
258 /* first two rounds */
259 LOAD64H(A, T+32); LOAD64H(B, T+40);
260 B ^= F(A ^ key_sigma[0]);
261 A ^= F(B ^ key_sigma[1]);
262 STORE64H(A, T+32); STORE64H(B, T+40);
263
264 /* xor kL in */
265 for (x = 0; x < 16; x++) { T[x+32] ^= kL[x]; }
266
267 /* next two rounds */
268 LOAD64H(A, T+32); LOAD64H(B, T+40);
269 B ^= F(A ^ key_sigma[2]);
270 A ^= F(B ^ key_sigma[3]);
271 STORE64H(A, T+32); STORE64H(B, T+40);
272
273 /* grab KA */
274 for (x = 0; x < 16; x++) { kA[x] = T[x+32]; }
275
276 /* xor kR in */
277 for (x = 0; x < 16; x++) { T[x+32] ^= kR[x]; }
278
279 if (keylen == 16) {
280 /* grab whitening keys kw1 and kw2 */
281 LOAD64H(skey->camellia.kw[0], kL);
282 LOAD64H(skey->camellia.kw[1], kL+8);
283
284 /* k1-k2 */
285 LOAD64H(skey->camellia.k[0], kA);
286 LOAD64H(skey->camellia.k[1], kA+8);
287
288 /* rotate kL by 15, k3/k4 */
289 rot_128(kL, 15, T+32);
290 LOAD64H(skey->camellia.k[2], T+32);
291 LOAD64H(skey->camellia.k[3], T+40);
292
293 /* rotate kA by 15, k5/k6 */
294 rot_128(kA, 15, T+32);
295 LOAD64H(skey->camellia.k[4], T+32);
296 LOAD64H(skey->camellia.k[5], T+40);
297
298 /* rotate kA by 30, kl1, kl2 */
299 rot_128(kA, 30, T+32);
300 LOAD64H(skey->camellia.kl[0], T+32);
301 LOAD64H(skey->camellia.kl[1], T+40);
302
303 /* rotate kL by 45, k7/k8 */
304 rot_128(kL, 45, T+32);
305 LOAD64H(skey->camellia.k[6], T+32);
306 LOAD64H(skey->camellia.k[7], T+40);
307
308 /* rotate kA by 45, k9/k10 */
309 rot_128(kA, 45, T+32);
310 LOAD64H(skey->camellia.k[8], T+32);
311 rot_128(kL, 60, T+32);
312 LOAD64H(skey->camellia.k[9], T+40);
313
314 /* rotate kA by 60, k11/k12 */
315 rot_128(kA, 60, T+32);
316 LOAD64H(skey->camellia.k[10], T+32);
317 LOAD64H(skey->camellia.k[11], T+40);
318
319 /* rotate kL by 77, kl3, kl4 */
320 rot_128(kL, 77, T+32);
321 LOAD64H(skey->camellia.kl[2], T+32);
322 LOAD64H(skey->camellia.kl[3], T+40);
323
324 /* rotate kL by 94, k13/k14 */
325 rot_128(kL, 94, T+32);
326 LOAD64H(skey->camellia.k[12], T+32);
327 LOAD64H(skey->camellia.k[13], T+40);
328
329 /* rotate kA by 94, k15/k16 */
330 rot_128(kA, 94, T+32);
331 LOAD64H(skey->camellia.k[14], T+32);
332 LOAD64H(skey->camellia.k[15], T+40);
333
334 /* rotate kL by 111, k17/k18 */
335 rot_128(kL, 111, T+32);
336 LOAD64H(skey->camellia.k[16], T+32);
337 LOAD64H(skey->camellia.k[17], T+40);
338
339 /* rotate kA by 111, kw3/kw4 */
340 rot_128(kA, 111, T+32);
341 LOAD64H(skey->camellia.kw[2], T+32);
342 LOAD64H(skey->camellia.kw[3], T+40);
343 } else {
344 /* last two rounds */
345 LOAD64H(A, T+32); LOAD64H(B, T+40);
346 B ^= F(A ^ key_sigma[4]);
347 A ^= F(B ^ key_sigma[5]);
348 STORE64H(A, T+32); STORE64H(B, T+40);
349
350 /* grab kB */
351 for (x = 0; x < 16; x++) { kB[x] = T[x+32]; }
352
353 /* kw1/2 from kL*/
354 LOAD64H(skey->camellia.kw[0], kL);
355 LOAD64H(skey->camellia.kw[1], kL+8);
356
357 /* k1/k2 = kB */
358 LOAD64H(skey->camellia.k[0], kB);
359 LOAD64H(skey->camellia.k[1], kB+8);
360
361 /* k3/k4 = kR by 15 */
362 rot_128(kR, 15, T+32);
363 LOAD64H(skey->camellia.k[2], T+32);
364 LOAD64H(skey->camellia.k[3], T+40);
365
366 /* k5/k7 = kA by 15 */
367 rot_128(kA, 15, T+32);
368 LOAD64H(skey->camellia.k[4], T+32);
369 LOAD64H(skey->camellia.k[5], T+40);
370
371 /* kl1/2 = kR by 30 */
372 rot_128(kR, 30, T+32);
373 LOAD64H(skey->camellia.kl[0], T+32);
374 LOAD64H(skey->camellia.kl[1], T+40);
375
376 /* k7/k8 = kB by 30 */
377 rot_128(kB, 30, T+32);
378 LOAD64H(skey->camellia.k[6], T+32);
379 LOAD64H(skey->camellia.k[7], T+40);
380
381 /* k9/k10 = kL by 45 */
382 rot_128(kL, 45, T+32);
383 LOAD64H(skey->camellia.k[8], T+32);
384 LOAD64H(skey->camellia.k[9], T+40);
385
386 /* k11/k12 = kA by 45 */
387 rot_128(kA, 45, T+32);
388 LOAD64H(skey->camellia.k[10], T+32);
389 LOAD64H(skey->camellia.k[11], T+40);
390
391 /* kl3/4 = kL by 60 */
392 rot_128(kL, 60, T+32);
393 LOAD64H(skey->camellia.kl[2], T+32);
394 LOAD64H(skey->camellia.kl[3], T+40);
395
396 /* k13/k14 = kR by 60 */
397 rot_128(kR, 60, T+32);
398 LOAD64H(skey->camellia.k[12], T+32);
399 LOAD64H(skey->camellia.k[13], T+40);
400
401 /* k15/k16 = kB by 15 */
402 rot_128(kB, 60, T+32);
403 LOAD64H(skey->camellia.k[14], T+32);
404 LOAD64H(skey->camellia.k[15], T+40);
405
406 /* k17/k18 = kL by 77 */
407 rot_128(kL, 77, T+32);
408 LOAD64H(skey->camellia.k[16], T+32);
409 LOAD64H(skey->camellia.k[17], T+40);
410
411 /* kl5/6 = kA by 77 */
412 rot_128(kA, 77, T+32);
413 LOAD64H(skey->camellia.kl[4], T+32);
414 LOAD64H(skey->camellia.kl[5], T+40);
415
416 /* k19/k20 = kR by 94 */
417 rot_128(kR, 94, T+32);
418 LOAD64H(skey->camellia.k[18], T+32);
419 LOAD64H(skey->camellia.k[19], T+40);
420
421 /* k21/k22 = kA by 94 */
422 rot_128(kA, 94, T+32);
423 LOAD64H(skey->camellia.k[20], T+32);
424 LOAD64H(skey->camellia.k[21], T+40);
425
426 /* k23/k24 = kL by 111 */
427 rot_128(kL, 111, T+32);
428 LOAD64H(skey->camellia.k[22], T+32);
429 LOAD64H(skey->camellia.k[23], T+40);
430
431 /* kw2/kw3 = kB by 111 */
432 rot_128(kB, 111, T+32);
433 LOAD64H(skey->camellia.kw[2], T+32);
434 LOAD64H(skey->camellia.kw[3], T+40);
435 }
436
437 return CRYPT_OK;
438 }
439
440 int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
441 {
442 ulong64 L, R;
443 ulong32 a, b;
444
445 LOAD64H(L, pt+0); LOAD64H(R, pt+8);
446 L ^= skey->camellia.kw[0];
447 R ^= skey->camellia.kw[1];
448
449 /* first 6 rounds */
450 R ^= F(L ^ skey->camellia.k[0]);
451 L ^= F(R ^ skey->camellia.k[1]);
452 R ^= F(L ^ skey->camellia.k[2]);
453 L ^= F(R ^ skey->camellia.k[3]);
454 R ^= F(L ^ skey->camellia.k[4]);
455 L ^= F(R ^ skey->camellia.k[5]);
456
457 /* FL */
458 a = (ulong32)(L >> 32);
459 b = (ulong32)(L & 0xFFFFFFFFUL);
460 b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1);
461 a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU);
462 L = (((ulong64)a) << 32) | b;
463
464 /* FL^-1 */
465 a = (ulong32)(R >> 32);
466 b = (ulong32)(R & 0xFFFFFFFFUL);
467 a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU);
468 b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1);
469 R = (((ulong64)a) << 32) | b;
470
471 /* second 6 rounds */
472 R ^= F(L ^ skey->camellia.k[6]);
473 L ^= F(R ^ skey->camellia.k[7]);
474 R ^= F(L ^ skey->camellia.k[8]);
475 L ^= F(R ^ skey->camellia.k[9]);
476 R ^= F(L ^ skey->camellia.k[10]);
477 L ^= F(R ^ skey->camellia.k[11]);
478
479 /* FL */
480 a = (ulong32)(L >> 32);
481 b = (ulong32)(L & 0xFFFFFFFFUL);
482 b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1);
483 a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU);
484 L = (((ulong64)a) << 32) | b;
485
486 /* FL^-1 */
487 a = (ulong32)(R >> 32);
488 b = (ulong32)(R & 0xFFFFFFFFUL);
489 a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU);
490 b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1);
491 R = (((ulong64)a) << 32) | b;
492
493 /* third 6 rounds */
494 R ^= F(L ^ skey->camellia.k[12]);
495 L ^= F(R ^ skey->camellia.k[13]);
496 R ^= F(L ^ skey->camellia.k[14]);
497 L ^= F(R ^ skey->camellia.k[15]);
498 R ^= F(L ^ skey->camellia.k[16]);
499 L ^= F(R ^ skey->camellia.k[17]);
500
501 /* next FL */
502 if (skey->camellia.R == 24) {
503 /* FL */
504 a = (ulong32)(L >> 32);
505 b = (ulong32)(L & 0xFFFFFFFFUL);
506 b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1);
507 a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU);
508 L = (((ulong64)a) << 32) | b;
509
510 /* FL^-1 */
511 a = (ulong32)(R >> 32);
512 b = (ulong32)(R & 0xFFFFFFFFUL);
513 a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU);
514 b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1);
515 R = (((ulong64)a) << 32) | b;
516
517 /* fourth 6 rounds */
518 R ^= F(L ^ skey->camellia.k[18]);
519 L ^= F(R ^ skey->camellia.k[19]);
520 R ^= F(L ^ skey->camellia.k[20]);
521 L ^= F(R ^ skey->camellia.k[21]);
522 R ^= F(L ^ skey->camellia.k[22]);
523 L ^= F(R ^ skey->camellia.k[23]);
524 }
525
526 L ^= skey->camellia.kw[3];
527 R ^= skey->camellia.kw[2];
528
529 STORE64H(R, ct+0); STORE64H(L, ct+8);
530
531 return CRYPT_OK;
532 }
533
534 int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
535 {
536 ulong64 L, R;
537 ulong32 a, b;
538
539 LOAD64H(R, ct+0); LOAD64H(L, ct+8);
540 L ^= skey->camellia.kw[3];
541 R ^= skey->camellia.kw[2];
542
543 /* next FL */
544 if (skey->camellia.R == 24) {
545 /* fourth 6 rounds */
546 L ^= F(R ^ skey->camellia.k[23]);
547 R ^= F(L ^ skey->camellia.k[22]);
548 L ^= F(R ^ skey->camellia.k[21]);
549 R ^= F(L ^ skey->camellia.k[20]);
550 L ^= F(R ^ skey->camellia.k[19]);
551 R ^= F(L ^ skey->camellia.k[18]);
552
553 /* FL */
554 a = (ulong32)(L >> 32);
555 b = (ulong32)(L & 0xFFFFFFFFUL);
556 a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU);
557 b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1);
558 L = (((ulong64)a) << 32) | b;
559
560 /* FL^-1 */
561 a = (ulong32)(R >> 32);
562 b = (ulong32)(R & 0xFFFFFFFFUL);
563 b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1);
564 a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU);
565 R = (((ulong64)a) << 32) | b;
566
567 }
568
569 /* third 6 rounds */
570 L ^= F(R ^ skey->camellia.k[17]);
571 R ^= F(L ^ skey->camellia.k[16]);
572 L ^= F(R ^ skey->camellia.k[15]);
573 R ^= F(L ^ skey->camellia.k[14]);
574 L ^= F(R ^ skey->camellia.k[13]);
575 R ^= F(L ^ skey->camellia.k[12]);
576
577 /* FL */
578 a = (ulong32)(L >> 32);
579 b = (ulong32)(L & 0xFFFFFFFFUL);
580 a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU);
581 b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1);
582 L = (((ulong64)a) << 32) | b;
583
584 /* FL^-1 */
585 a = (ulong32)(R >> 32);
586 b = (ulong32)(R & 0xFFFFFFFFUL);
587 b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1);
588 a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU);
589 R = (((ulong64)a) << 32) | b;
590
591 /* second 6 rounds */
592 L ^= F(R ^ skey->camellia.k[11]);
593 R ^= F(L ^ skey->camellia.k[10]);
594 L ^= F(R ^ skey->camellia.k[9]);
595 R ^= F(L ^ skey->camellia.k[8]);
596 L ^= F(R ^ skey->camellia.k[7]);
597 R ^= F(L ^ skey->camellia.k[6]);
598
599 /* FL */
600 a = (ulong32)(L >> 32);
601 b = (ulong32)(L & 0xFFFFFFFFUL);
602 a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU);
603 b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1);
604 L = (((ulong64)a) << 32) | b;
605
606 /* FL^-1 */
607 a = (ulong32)(R >> 32);
608 b = (ulong32)(R & 0xFFFFFFFFUL);
609 b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1);
610 a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU);
611 R = (((ulong64)a) << 32) | b;
612
613 /* first 6 rounds */
614 L ^= F(R ^ skey->camellia.k[5]);
615 R ^= F(L ^ skey->camellia.k[4]);
616 L ^= F(R ^ skey->camellia.k[3]);
617 R ^= F(L ^ skey->camellia.k[2]);
618 L ^= F(R ^ skey->camellia.k[1]);
619 R ^= F(L ^ skey->camellia.k[0]);
620
621 L ^= skey->camellia.kw[1];
622 R ^= skey->camellia.kw[0];
623
624 STORE64H(R, pt+0); STORE64H(L, pt+8);
625
626 return CRYPT_OK;
627 }
628
629 int camellia_test(void)
630 {
631 static const struct {
632 int keylen;
633 unsigned char key[32], pt[16], ct[16];
634 } tests[] = {
635
636 {
637 16,
638 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
639 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
640 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
641 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
642 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
643 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }
644 },
645
646 {
647 24,
648 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
649 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
650 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
651 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
652 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
653 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
654 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }
655 },
656
657
658 {
659 32,
660 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
661 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
662 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
663 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
664 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
665 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
666 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
667 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }
668 }
669 };
670 unsigned char buf[2][16];
671 symmetric_key skey;
672 int err, x;
673
674 for (x = 0; x < 3; x++) {
675 if ((err = camellia_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
676 return err;
677 }
678 if ((err = camellia_ecb_encrypt(tests[x].pt, buf[0], &skey)) != CRYPT_OK) {
679 camellia_done(&skey);
680 return err;
681 }
682 if ((err = camellia_ecb_decrypt(tests[x].ct, buf[1], &skey)) != CRYPT_OK) {
683 camellia_done(&skey);
684 return err;
685 }
686 camellia_done(&skey);
687 if (XMEMCMP(tests[x].ct, buf[0], 16) || XMEMCMP(tests[x].pt, buf[1], 16)) {
688 #if 0
689 int i, j;
690 printf ("\n\nLTC_CAMELLIA failed for x=%d, I got:\n", x);
691 for (i = 0; i < 2; i++) {
692 const unsigned char *expected, *actual;
693 expected = (i ? tests[x].pt : tests[x].ct);
694 actual = buf[i];
695 printf ("expected actual (%s)\n", (i ? "plaintext" : "ciphertext"));
696 for (j = 0; j < 16; j++) {
697 const char *eq = (expected[j] == actual[j] ? "==" : "!=");
698 printf (" %02x %s %02x\n", expected[j], eq, actual[j]);
699 }
700 printf ("\n");
701 }
702 #endif
703 return CRYPT_FAIL_TESTVECTOR;
704 }
705 }
706 return CRYPT_OK;
707 }
708
709 void camellia_done(symmetric_key *skey) {}
710
711 int camellia_keysize(int *keysize)
712 {
713 if (*keysize >= 32) { *keysize = 32; }
714 else if (*keysize >= 24) { *keysize = 24; }
715 else if (*keysize >= 16) { *keysize = 16; }
716 else return CRYPT_INVALID_KEYSIZE;
717 return CRYPT_OK;
718 }
719
720 #endif
721
722 /* $Source$ */
723 /* $Revision$ */
724 /* $Date$ */
+0
-720
libtom-src/ciphers/cast5.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file cast5.c
13 Implementation of LTC_CAST5 (RFC 2144) by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_CAST5
18
19 const struct ltc_cipher_descriptor cast5_desc = {
20 "cast5",
21 15,
22 5, 16, 8, 16,
23 &cast5_setup,
24 &cast5_ecb_encrypt,
25 &cast5_ecb_decrypt,
26 &cast5_test,
27 &cast5_done,
28 &cast5_keysize,
29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
30 };
31
32 static const ulong32 S1[256] = {
33 0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL,
34 0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL,
35 0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL,
36 0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL,
37 0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL,
38 0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL,
39 0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL,
40 0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL,
41 0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL,
42 0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL,
43 0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL,
44 0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL,
45 0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL,
46 0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL,
47 0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL,
48 0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL,
49 0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL,
50 0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL,
51 0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL,
52 0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL,
53 0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL,
54 0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL,
55 0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL,
56 0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL,
57 0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL,
58 0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL,
59 0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL,
60 0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL,
61 0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL,
62 0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL,
63 0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL,
64 0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL,
65 0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL,
66 0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL,
67 0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL,
68 0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL,
69 0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL,
70 0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL,
71 0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL,
72 0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL,
73 0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL,
74 0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL,
75 0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL};
76
77 static const ulong32 S2[256] = {
78 0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL,
79 0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL,
80 0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL,
81 0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL,
82 0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL,
83 0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL,
84 0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL,
85 0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL,
86 0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL,
87 0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL,
88 0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL,
89 0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL,
90 0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL,
91 0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL,
92 0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL,
93 0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL,
94 0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL,
95 0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL,
96 0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL,
97 0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL,
98 0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL,
99 0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL,
100 0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL,
101 0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL,
102 0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL,
103 0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL,
104 0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL,
105 0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL,
106 0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL,
107 0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL,
108 0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL,
109 0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL,
110 0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL,
111 0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL,
112 0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL,
113 0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL,
114 0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL,
115 0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL,
116 0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL,
117 0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL,
118 0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL,
119 0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL,
120 0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL};
121
122 static const ulong32 S3[256] = {
123 0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL,
124 0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL,
125 0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL,
126 0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL,
127 0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL,
128 0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL,
129 0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL,
130 0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL,
131 0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL,
132 0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL,
133 0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL,
134 0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL,
135 0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL,
136 0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL,
137 0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL,
138 0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL,
139 0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL,
140 0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL,
141 0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL,
142 0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL,
143 0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL,
144 0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL,
145 0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL,
146 0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL,
147 0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL,
148 0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL,
149 0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL,
150 0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL,
151 0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL,
152 0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL,
153 0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL,
154 0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL,
155 0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL,
156 0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL,
157 0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL,
158 0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL,
159 0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL,
160 0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL,
161 0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL,
162 0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL,
163 0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL,
164 0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL,
165 0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL};
166
167 static const ulong32 S4[256] = {
168 0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL,
169 0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL,
170 0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL,
171 0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL,
172 0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL,
173 0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL,
174 0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL,
175 0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL,
176 0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL,
177 0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL,
178 0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL,
179 0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL,
180 0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL,
181 0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL,
182 0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL,
183 0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL,
184 0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL,
185 0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL,
186 0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL,
187 0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL,
188 0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL,
189 0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL,
190 0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL,
191 0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL,
192 0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL,
193 0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL,
194 0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL,
195 0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL,
196 0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL,
197 0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL,
198 0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL,
199 0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL,
200 0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL,
201 0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL,
202 0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL,
203 0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL,
204 0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL,
205 0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL,
206 0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL,
207 0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL,
208 0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL,
209 0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL,
210 0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL};
211
212 static const ulong32 S5[256] = {
213 0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL,
214 0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL,
215 0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL,
216 0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL,
217 0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL,
218 0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL,
219 0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL,
220 0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL,
221 0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL,
222 0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL,
223 0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL,
224 0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL,
225 0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL,
226 0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL,
227 0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL,
228 0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL,
229 0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL,
230 0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL,
231 0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL,
232 0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL,
233 0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL,
234 0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL,
235 0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL,
236 0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL,
237 0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL,
238 0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL,
239 0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL,
240 0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL,
241 0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL,
242 0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL,
243 0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL,
244 0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL,
245 0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL,
246 0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL,
247 0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL,
248 0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL,
249 0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL,
250 0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL,
251 0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL,
252 0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL,
253 0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL,
254 0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL,
255 0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL};
256
257 static const ulong32 S6[256] = {
258 0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL,
259 0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL,
260 0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL,
261 0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL,
262 0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL,
263 0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL,
264 0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL,
265 0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL,
266 0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL,
267 0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL,
268 0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL,
269 0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL,
270 0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL,
271 0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL,
272 0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL,
273 0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL,
274 0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL,
275 0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL,
276 0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL,
277 0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL,
278 0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL,
279 0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL,
280 0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL,
281 0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL,
282 0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL,
283 0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL,
284 0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL,
285 0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL,
286 0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL,
287 0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL,
288 0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL,
289 0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL,
290 0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL,
291 0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL,
292 0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL,
293 0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL,
294 0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL,
295 0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL,
296 0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL,
297 0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL,
298 0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL,
299 0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL,
300 0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL};
301
302 static const ulong32 S7[256] = {
303 0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL,
304 0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL,
305 0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL,
306 0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL,
307 0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL,
308 0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL,
309 0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL,
310 0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL,
311 0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL,
312 0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL,
313 0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL,
314 0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL,
315 0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL,
316 0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL,
317 0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL,
318 0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL,
319 0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL,
320 0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL,
321 0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL,
322 0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL,
323 0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL,
324 0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL,
325 0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL,
326 0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL,
327 0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL,
328 0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL,
329 0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL,
330 0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL,
331 0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL,
332 0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL,
333 0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL,
334 0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL,
335 0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL,
336 0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL,
337 0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL,
338 0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL,
339 0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL,
340 0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL,
341 0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL,
342 0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL,
343 0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL,
344 0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL,
345 0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL};
346
347 static const ulong32 S8[256] = {
348 0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL,
349 0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL,
350 0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL,
351 0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL,
352 0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL,
353 0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL,
354 0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL,
355 0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL,
356 0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL,
357 0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL,
358 0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL,
359 0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL,
360 0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL,
361 0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL,
362 0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL,
363 0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL,
364 0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL,
365 0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL,
366 0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL,
367 0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL,
368 0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL,
369 0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL,
370 0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL,
371 0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL,
372 0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL,
373 0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL,
374 0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL,
375 0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL,
376 0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL,
377 0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL,
378 0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL,
379 0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL,
380 0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL,
381 0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL,
382 0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL,
383 0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL,
384 0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL,
385 0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL,
386 0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL,
387 0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL,
388 0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL,
389 0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL,
390 0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL};
391
392 /* returns the i'th byte of a variable */
393 #ifdef _MSC_VER
394 #define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3))))
395 #else
396 #define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255)
397 #endif
398
399 /**
400 Initialize the LTC_CAST5 block cipher
401 @param key The symmetric key you wish to pass
402 @param keylen The key length in bytes
403 @param num_rounds The number of rounds desired (0 for default)
404 @param skey The key in as scheduled by this function.
405 @return CRYPT_OK if successful
406 */
407 #ifdef LTC_CLEAN_STACK
408 static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
409 #else
410 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
411 #endif
412 {
413 ulong32 x[4], z[4];
414 unsigned char buf[16];
415 int y, i;
416
417 LTC_ARGCHK(key != NULL);
418 LTC_ARGCHK(skey != NULL);
419
420 if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) {
421 return CRYPT_INVALID_ROUNDS;
422 }
423
424 if (num_rounds == 12 && keylen > 10) {
425 return CRYPT_INVALID_ROUNDS;
426 }
427
428 if (keylen < 5 || keylen > 16) {
429 return CRYPT_INVALID_KEYSIZE;
430 }
431
432 /* extend the key as required */
433 zeromem(buf, sizeof(buf));
434 XMEMCPY(buf, key, (size_t)keylen);
435
436 /* load and start the awful looking network */
437 for (y = 0; y < 4; y++) {
438 LOAD32H(x[3-y],buf+4*y);
439 }
440
441 for (i = y = 0; y < 2; y++) {
442 z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
443 z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
444 z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
445 z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
446 skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)];
447 skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)];
448 skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)];
449 skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)];
450
451 x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
452 x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
453 x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
454 x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
455 skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)];
456 skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)];
457 skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)];
458 skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)];
459
460 /* second half */
461 z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
462 z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
463 z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
464 z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
465 skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)];
466 skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)];
467 skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)];
468 skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)];
469
470 x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
471 x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
472 x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
473 x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
474 skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)];
475 skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)];
476 skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)];
477 skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)];
478 }
479
480 skey->cast5.keylen = keylen;
481
482 #ifdef LTC_CLEAN_STACK
483 zeromem(buf, sizeof(buf));
484 zeromem(x, sizeof(x));
485 zeromem(z, sizeof(z));
486 #endif
487
488 return CRYPT_OK;
489 }
490
491 #ifdef LTC_CLEAN_STACK
492 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
493 {
494 int z;
495 z = _cast5_setup(key, keylen, num_rounds, skey);
496 burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2);
497 return z;
498 }
499 #endif
500
501 #ifdef _MSC_VER
502 #define INLINE __inline
503 #else
504 #define INLINE
505 #endif
506
507 INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr)
508 {
509 ulong32 I;
510 I = (Km + R);
511 I = ROL(I, Kr);
512 return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)];
513 }
514
515 INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr)
516 {
517 ulong32 I;
518 I = (Km ^ R);
519 I = ROL(I, Kr);
520 return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)];
521 }
522
523 INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr)
524 {
525 ulong32 I;
526 I = (Km - R);
527 I = ROL(I, Kr);
528 return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)];
529 }
530
531 /**
532 Encrypts a block of text with LTC_CAST5
533 @param pt The input plaintext (8 bytes)
534 @param ct The output ciphertext (8 bytes)
535 @param skey The key as scheduled
536 */
537 #ifdef LTC_CLEAN_STACK
538 static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
539 #else
540 int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
541 #endif
542 {
543 ulong32 R, L;
544
545 LTC_ARGCHK(pt != NULL);
546 LTC_ARGCHK(ct != NULL);
547 LTC_ARGCHK(skey != NULL);
548
549 LOAD32H(L,&pt[0]);
550 LOAD32H(R,&pt[4]);
551 L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
552 R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]);
553 L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]);
554 R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]);
555 L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]);
556 R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]);
557 L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]);
558 R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]);
559 L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]);
560 R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]);
561 L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]);
562 R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]);
563 if (skey->cast5.keylen > 10) {
564 L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]);
565 R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]);
566 L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]);
567 R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]);
568 }
569 STORE32H(R,&ct[0]);
570 STORE32H(L,&ct[4]);
571 return CRYPT_OK;
572 }
573
574
575 #ifdef LTC_CLEAN_STACK
576 int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
577 {
578 int err =_cast5_ecb_encrypt(pt,ct,skey);
579 burn_stack(sizeof(ulong32)*3);
580 return err;
581 }
582 #endif
583
584 /**
585 Decrypts a block of text with LTC_CAST5
586 @param ct The input ciphertext (8 bytes)
587 @param pt The output plaintext (8 bytes)
588 @param skey The key as scheduled
589 */
590 #ifdef LTC_CLEAN_STACK
591 static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
592 #else
593 int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
594 #endif
595 {
596 ulong32 R, L;
597
598 LTC_ARGCHK(pt != NULL);
599 LTC_ARGCHK(ct != NULL);
600 LTC_ARGCHK(skey != NULL);
601
602 LOAD32H(R,&ct[0]);
603 LOAD32H(L,&ct[4]);
604 if (skey->cast5.keylen > 10) {
605 R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]);
606 L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]);
607 R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]);
608 L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]);
609 }
610 R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]);
611 L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]);
612 R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]);
613 L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]);
614 R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]);
615 L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]);
616 R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]);
617 L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]);
618 R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]);
619 L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]);
620 R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]);
621 L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
622 STORE32H(L,&pt[0]);
623 STORE32H(R,&pt[4]);
624
625 return CRYPT_OK;
626 }
627
628 #ifdef LTC_CLEAN_STACK
629 int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
630 {
631 int err = _cast5_ecb_decrypt(ct,pt,skey);
632 burn_stack(sizeof(ulong32)*3);
633 return err;
634 }
635 #endif
636
637 /**
638 Performs a self-test of the LTC_CAST5 block cipher
639 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
640 */
641 int cast5_test(void)
642 {
643 #ifndef LTC_TEST
644 return CRYPT_NOP;
645 #else
646 static const struct {
647 int keylen;
648 unsigned char key[16];
649 unsigned char pt[8];
650 unsigned char ct[8];
651 } tests[] = {
652 { 16,
653 {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
654 {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
655 {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2}
656 },
657 { 10,
658 {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
659 {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
660 {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B},
661 },
662 { 5,
663 {0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
664 {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
665 {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E}
666 }
667 };
668 int i, y, err;
669 symmetric_key key;
670 unsigned char tmp[2][8];
671
672 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
673 if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
674 return err;
675 }
676 cast5_ecb_encrypt(tests[i].pt, tmp[0], &key);
677 cast5_ecb_decrypt(tmp[0], tmp[1], &key);
678 if ((XMEMCMP(tmp[0], tests[i].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[i].pt, 8) != 0)) {
679 return CRYPT_FAIL_TESTVECTOR;
680 }
681 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
682 for (y = 0; y < 8; y++) tmp[0][y] = 0;
683 for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key);
684 for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key);
685 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
686
687 }
688 return CRYPT_OK;
689 #endif
690 }
691
692 /** Terminate the context
693 @param skey The scheduled key
694 */
695 void cast5_done(symmetric_key *skey)
696 {
697 }
698
699 /**
700 Gets suitable key size
701 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
702 @return CRYPT_OK if the input key size is acceptable.
703 */
704 int cast5_keysize(int *keysize)
705 {
706 LTC_ARGCHK(keysize != NULL);
707 if (*keysize < 5) {
708 return CRYPT_INVALID_KEYSIZE;
709 } else if (*keysize > 16) {
710 *keysize = 16;
711 }
712 return CRYPT_OK;
713 }
714
715 #endif
716
717 /* $Source$ */
718 /* $Revision$ */
719 /* $Date$ */
+0
-1902
libtom-src/ciphers/des.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file des.c
14 LTC_DES code submitted by Dobes Vandermeer
15 */
16
17 #ifdef LTC_DES
18
19 #define EN0 0
20 #define DE1 1
21
22 const struct ltc_cipher_descriptor des_desc =
23 {
24 "des",
25 13,
26 8, 8, 8, 16,
27 &des_setup,
28 &des_ecb_encrypt,
29 &des_ecb_decrypt,
30 &des_test,
31 &des_done,
32 &des_keysize,
33 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
34 };
35
36 const struct ltc_cipher_descriptor des3_desc =
37 {
38 "3des",
39 14,
40 24, 24, 8, 16,
41 &des3_setup,
42 &des3_ecb_encrypt,
43 &des3_ecb_decrypt,
44 &des3_test,
45 &des3_done,
46 &des3_keysize,
47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
48 };
49
50 static const ulong32 bytebit[8] =
51 {
52 0200, 0100, 040, 020, 010, 04, 02, 01
53 };
54
55 static const ulong32 bigbyte[24] =
56 {
57 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL,
58 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL,
59 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL,
60 0x800UL, 0x400UL, 0x200UL, 0x100UL,
61 0x80UL, 0x40UL, 0x20UL, 0x10UL,
62 0x8UL, 0x4UL, 0x2UL, 0x1L
63 };
64
65 /* Use the key schedule specific in the standard (ANSI X3.92-1981) */
66
67 static const unsigned char pc1[56] = {
68 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
69 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
70 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
71 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
72 };
73
74 static const unsigned char totrot[16] = {
75 1, 2, 4, 6,
76 8, 10, 12, 14,
77 15, 17, 19, 21,
78 23, 25, 27, 28
79 };
80
81 static const unsigned char pc2[48] = {
82 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
83 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
84 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
85 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
86 };
87
88
89 static const ulong32 SP1[64] =
90 {
91 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL,
92 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL,
93 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL,
94 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL,
95 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL,
96 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL,
97 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL,
98 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL,
99 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL,
100 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL,
101 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL,
102 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL,
103 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL,
104 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL,
105 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL,
106 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL
107 };
108
109 static const ulong32 SP2[64] =
110 {
111 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL,
112 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL,
113 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL,
114 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL,
115 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL,
116 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL,
117 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL,
118 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL,
119 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL,
120 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL,
121 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL,
122 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL,
123 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL,
124 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL,
125 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL,
126 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL
127 };
128
129 static const ulong32 SP3[64] =
130 {
131 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL,
132 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL,
133 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL,
134 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL,
135 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL,
136 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL,
137 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL,
138 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL,
139 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL,
140 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL,
141 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL,
142 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL,
143 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL,
144 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL,
145 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL,
146 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL
147 };
148
149 static const ulong32 SP4[64] =
150 {
151 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
152 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL,
153 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL,
154 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL,
155 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL,
156 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL,
157 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL,
158 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL,
159 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL,
160 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL,
161 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL,
162 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
163 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL,
164 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL,
165 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL,
166 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL
167 };
168
169 static const ulong32 SP5[64] =
170 {
171 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL,
172 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL,
173 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL,
174 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL,
175 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL,
176 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL,
177 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL,
178 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL,
179 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL,
180 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL,
181 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL,
182 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL,
183 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL,
184 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL,
185 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL,
186 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL
187 };
188
189 static const ulong32 SP6[64] =
190 {
191 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL,
192 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL,
193 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL,
194 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
195 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL,
196 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL,
197 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL,
198 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL,
199 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL,
200 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL,
201 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
202 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL,
203 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL,
204 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL,
205 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL,
206 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL
207 };
208
209 static const ulong32 SP7[64] =
210 {
211 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL,
212 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL,
213 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL,
214 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL,
215 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL,
216 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL,
217 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL,
218 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL,
219 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL,
220 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL,
221 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL,
222 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL,
223 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL,
224 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL,
225 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL,
226 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL
227 };
228
229 static const ulong32 SP8[64] =
230 {
231 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL,
232 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL,
233 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL,
234 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL,
235 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL,
236 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL,
237 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL,
238 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL,
239 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL,
240 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL,
241 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL,
242 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL,
243 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL,
244 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL,
245 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL,
246 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL
247 };
248
249 #ifndef LTC_SMALL_CODE
250
251 static const ulong64 des_ip[8][256] = {
252
253 { CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010),
254 CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010),
255 CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010),
256 CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010),
257 CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010),
258 CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010),
259 CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010),
260 CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010),
261 CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010),
262 CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010),
263 CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010),
264 CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010),
265 CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010),
266 CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010),
267 CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010),
268 CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010),
269 CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010),
270 CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010),
271 CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010),
272 CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010),
273 CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010),
274 CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010),
275 CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010),
276 CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010),
277 CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010),
278 CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010),
279 CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010),
280 CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010),
281 CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010),
282 CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010),
283 CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010),
284 CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010),
285 CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010),
286 CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010),
287 CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010),
288 CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010),
289 CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010),
290 CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010),
291 CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010),
292 CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010),
293 CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010),
294 CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010),
295 CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010),
296 CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010),
297 CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010),
298 CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010),
299 CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010),
300 CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010),
301 CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010),
302 CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010),
303 CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010),
304 CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010),
305 CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010),
306 CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010),
307 CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010),
308 CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010),
309 CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010),
310 CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010),
311 CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010),
312 CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010),
313 CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010),
314 CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010),
315 CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010),
316 CONST64(0x1010100010101000), CONST64(0x1010101010101000), CONST64(0x1010100010101010), CONST64(0x1010101010101010)
317 },
318 { CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008),
319 CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008),
320 CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808),
321 CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808),
322 CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008),
323 CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008),
324 CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808),
325 CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808),
326 CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008),
327 CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008),
328 CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808),
329 CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808),
330 CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008),
331 CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008),
332 CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808),
333 CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808),
334 CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008),
335 CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008),
336 CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808),
337 CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808),
338 CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008),
339 CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008),
340 CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808),
341 CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808),
342 CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008),
343 CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008),
344 CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808),
345 CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808),
346 CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008),
347 CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008),
348 CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808),
349 CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808),
350 CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008),
351 CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008),
352 CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808),
353 CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808),
354 CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008),
355 CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008),
356 CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808),
357 CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808),
358 CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008),
359 CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008),
360 CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808),
361 CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808),
362 CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008),
363 CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008),
364 CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808),
365 CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808),
366 CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008),
367 CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008),
368 CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808),
369 CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808),
370 CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008),
371 CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008),
372 CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808),
373 CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808),
374 CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008),
375 CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008),
376 CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808),
377 CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808),
378 CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008),
379 CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008),
380 CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808),
381 CONST64(0x0808080008080800), CONST64(0x0808080808080800), CONST64(0x0808080008080808), CONST64(0x0808080808080808)
382 },
383 { CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004),
384 CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004),
385 CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404),
386 CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404),
387 CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004),
388 CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004),
389 CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404),
390 CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404),
391 CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004),
392 CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004),
393 CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404),
394 CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404),
395 CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004),
396 CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004),
397 CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404),
398 CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404),
399 CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004),
400 CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004),
401 CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404),
402 CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404),
403 CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004),
404 CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004),
405 CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404),
406 CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404),
407 CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004),
408 CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004),
409 CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404),
410 CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404),
411 CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004),
412 CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004),
413 CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404),
414 CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404),
415 CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004),
416 CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004),
417 CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404),
418 CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404),
419 CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004),
420 CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004),
421 CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404),
422 CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404),
423 CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004),
424 CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004),
425 CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404),
426 CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404),
427 CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004),
428 CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004),
429 CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404),
430 CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404),
431 CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004),
432 CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004),
433 CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404),
434 CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404),
435 CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004),
436 CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004),
437 CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404),
438 CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404),
439 CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004),
440 CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004),
441 CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404),
442 CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404),
443 CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004),
444 CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004),
445 CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404),
446 CONST64(0x0404040004040400), CONST64(0x0404040404040400), CONST64(0x0404040004040404), CONST64(0x0404040404040404)
447 },
448 { CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002),
449 CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002),
450 CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202),
451 CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202),
452 CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002),
453 CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002),
454 CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202),
455 CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202),
456 CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002),
457 CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002),
458 CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202),
459 CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202),
460 CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002),
461 CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002),
462 CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202),
463 CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202),
464 CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002),
465 CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002),
466 CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202),
467 CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202),
468 CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002),
469 CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002),
470 CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202),
471 CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202),
472 CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002),
473 CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002),
474 CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202),
475 CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202),
476 CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002),
477 CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002),
478 CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202),
479 CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202),
480 CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002),
481 CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002),
482 CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202),
483 CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202),
484 CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002),
485 CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002),
486 CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202),
487 CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202),
488 CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002),
489 CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002),
490 CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202),
491 CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202),
492 CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002),
493 CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002),
494 CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202),
495 CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202),
496 CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002),
497 CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002),
498 CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202),
499 CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202),
500 CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002),
501 CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002),
502 CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202),
503 CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202),
504 CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002),
505 CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002),
506 CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202),
507 CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202),
508 CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002),
509 CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002),
510 CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202),
511 CONST64(0x0202020002020200), CONST64(0x0202020202020200), CONST64(0x0202020002020202), CONST64(0x0202020202020202)
512 },
513 { CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100),
514 CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100),
515 CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100),
516 CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100),
517 CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100),
518 CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100),
519 CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100),
520 CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100),
521 CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100),
522 CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100),
523 CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100),
524 CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100),
525 CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100),
526 CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100),
527 CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100),
528 CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100),
529 CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100),
530 CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100),
531 CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100),
532 CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100),
533 CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100),
534 CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100),
535 CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100),
536 CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100),
537 CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100),
538 CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100),
539 CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100),
540 CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100),
541 CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100),
542 CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100),
543 CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100),
544 CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100),
545 CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101),
546 CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101),
547 CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101),
548 CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101),
549 CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101),
550 CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101),
551 CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101),
552 CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101),
553 CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101),
554 CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101),
555 CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101),
556 CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101),
557 CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101),
558 CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101),
559 CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101),
560 CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101),
561 CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101),
562 CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101),
563 CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101),
564 CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101),
565 CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101),
566 CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101),
567 CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101),
568 CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101),
569 CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101),
570 CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101),
571 CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101),
572 CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101),
573 CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101),
574 CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101),
575 CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101),
576 CONST64(0x0101000101010001), CONST64(0x0101010101010001), CONST64(0x0101000101010101), CONST64(0x0101010101010101)
577 },
578 { CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080),
579 CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080),
580 CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080),
581 CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080),
582 CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080),
583 CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080),
584 CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080),
585 CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080),
586 CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080),
587 CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080),
588 CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080),
589 CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080),
590 CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080),
591 CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080),
592 CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080),
593 CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080),
594 CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080),
595 CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080),
596 CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080),
597 CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080),
598 CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080),
599 CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080),
600 CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080),
601 CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080),
602 CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080),
603 CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080),
604 CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080),
605 CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080),
606 CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080),
607 CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080),
608 CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080),
609 CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080),
610 CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080),
611 CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080),
612 CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080),
613 CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080),
614 CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080),
615 CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080),
616 CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080),
617 CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080),
618 CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080),
619 CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080),
620 CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080),
621 CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080),
622 CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080),
623 CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080),
624 CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080),
625 CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080),
626 CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080),
627 CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080),
628 CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080),
629 CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080),
630 CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080),
631 CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080),
632 CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080),
633 CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080),
634 CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080),
635 CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080),
636 CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080),
637 CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080),
638 CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080),
639 CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080),
640 CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080),
641 CONST64(0x8080800080808000), CONST64(0x8080808080808000), CONST64(0x8080800080808080), CONST64(0x8080808080808080)
642 },
643 { CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040),
644 CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040),
645 CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040),
646 CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040),
647 CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040),
648 CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040),
649 CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040),
650 CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040),
651 CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040),
652 CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040),
653 CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040),
654 CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040),
655 CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040),
656 CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040),
657 CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040),
658 CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040),
659 CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040),
660 CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040),
661 CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040),
662 CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040),
663 CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040),
664 CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040),
665 CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040),
666 CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040),
667 CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040),
668 CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040),
669 CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040),
670 CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040),
671 CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040),
672 CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040),
673 CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040),
674 CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040),
675 CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040),
676 CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040),
677 CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040),
678 CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040),
679 CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040),
680 CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040),
681 CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040),
682 CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040),
683 CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040),
684 CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040),
685 CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040),
686 CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040),
687 CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040),
688 CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040),
689 CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040),
690 CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040),
691 CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040),
692 CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040),
693 CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040),
694 CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040),
695 CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040),
696 CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040),
697 CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040),
698 CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040),
699 CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040),
700 CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040),
701 CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040),
702 CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040),
703 CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040),
704 CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040),
705 CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040),
706 CONST64(0x4040400040404000), CONST64(0x4040404040404000), CONST64(0x4040400040404040), CONST64(0x4040404040404040)
707 },
708 { CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020),
709 CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020),
710 CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020),
711 CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020),
712 CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020),
713 CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020),
714 CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020),
715 CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020),
716 CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020),
717 CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020),
718 CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020),
719 CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020),
720 CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020),
721 CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020),
722 CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020),
723 CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020),
724 CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020),
725 CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020),
726 CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020),
727 CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020),
728 CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020),
729 CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020),
730 CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020),
731 CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020),
732 CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020),
733 CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020),
734 CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020),
735 CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020),
736 CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020),
737 CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020),
738 CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020),
739 CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020),
740 CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020),
741 CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020),
742 CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020),
743 CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020),
744 CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020),
745 CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020),
746 CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020),
747 CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020),
748 CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020),
749 CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020),
750 CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020),
751 CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020),
752 CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020),
753 CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020),
754 CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020),
755 CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020),
756 CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020),
757 CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020),
758 CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020),
759 CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020),
760 CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020),
761 CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020),
762 CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020),
763 CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020),
764 CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020),
765 CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020),
766 CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020),
767 CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020),
768 CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020),
769 CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020),
770 CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020),
771 CONST64(0x2020200020202000), CONST64(0x2020202020202000), CONST64(0x2020200020202020), CONST64(0x2020202020202020)
772 }};
773
774 static const ulong64 des_fp[8][256] = {
775
776 { CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000),
777 CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000),
778 CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200),
779 CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200),
780 CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002),
781 CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002),
782 CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202),
783 CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202),
784 CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000),
785 CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000),
786 CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200),
787 CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200),
788 CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002),
789 CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002),
790 CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202),
791 CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202),
792 CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000),
793 CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000),
794 CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200),
795 CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200),
796 CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002),
797 CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002),
798 CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202),
799 CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202),
800 CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000),
801 CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000),
802 CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200),
803 CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200),
804 CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002),
805 CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002),
806 CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202),
807 CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202),
808 CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000),
809 CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000),
810 CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200),
811 CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200),
812 CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002),
813 CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002),
814 CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202),
815 CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202),
816 CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000),
817 CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000),
818 CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200),
819 CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200),
820 CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002),
821 CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002),
822 CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202),
823 CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202),
824 CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000),
825 CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000),
826 CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200),
827 CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200),
828 CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002),
829 CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002),
830 CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202),
831 CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202),
832 CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000),
833 CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000),
834 CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200),
835 CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200),
836 CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002),
837 CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002),
838 CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202),
839 CONST64(0x0202020000020202), CONST64(0x0202028000020202), CONST64(0x0202020002020202), CONST64(0x0202028002020202)
840 },
841 { CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000),
842 CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000),
843 CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800),
844 CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800),
845 CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008),
846 CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008),
847 CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808),
848 CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808),
849 CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000),
850 CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000),
851 CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800),
852 CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800),
853 CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008),
854 CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008),
855 CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808),
856 CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808),
857 CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000),
858 CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000),
859 CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800),
860 CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800),
861 CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008),
862 CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008),
863 CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808),
864 CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808),
865 CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000),
866 CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000),
867 CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800),
868 CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800),
869 CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008),
870 CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008),
871 CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808),
872 CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808),
873 CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000),
874 CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000),
875 CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800),
876 CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800),
877 CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008),
878 CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008),
879 CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808),
880 CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808),
881 CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000),
882 CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000),
883 CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800),
884 CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800),
885 CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008),
886 CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008),
887 CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808),
888 CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808),
889 CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000),
890 CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000),
891 CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800),
892 CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800),
893 CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008),
894 CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008),
895 CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808),
896 CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808),
897 CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000),
898 CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000),
899 CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800),
900 CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800),
901 CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008),
902 CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008),
903 CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808),
904 CONST64(0x0808080000080808), CONST64(0x0808080200080808), CONST64(0x0808080008080808), CONST64(0x0808080208080808)
905 },
906 { CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000),
907 CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000),
908 CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000),
909 CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000),
910 CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020),
911 CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020),
912 CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020),
913 CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020),
914 CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000),
915 CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000),
916 CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000),
917 CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000),
918 CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020),
919 CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020),
920 CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020),
921 CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020),
922 CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000),
923 CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000),
924 CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000),
925 CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000),
926 CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020),
927 CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020),
928 CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020),
929 CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020),
930 CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000),
931 CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000),
932 CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000),
933 CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000),
934 CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020),
935 CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020),
936 CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020),
937 CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020),
938 CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000),
939 CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000),
940 CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000),
941 CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000),
942 CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020),
943 CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020),
944 CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020),
945 CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020),
946 CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000),
947 CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000),
948 CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000),
949 CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000),
950 CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020),
951 CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020),
952 CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020),
953 CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020),
954 CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000),
955 CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000),
956 CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000),
957 CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000),
958 CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020),
959 CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020),
960 CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020),
961 CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020),
962 CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000),
963 CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000),
964 CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000),
965 CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000),
966 CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020),
967 CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020),
968 CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020),
969 CONST64(0x2020200000202020), CONST64(0x2020200800202020), CONST64(0x2020200020202020), CONST64(0x2020200820202020)
970 },
971 { CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000),
972 CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000),
973 CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000),
974 CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000),
975 CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080),
976 CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080),
977 CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080),
978 CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080),
979 CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000),
980 CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000),
981 CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000),
982 CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000),
983 CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080),
984 CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080),
985 CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080),
986 CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080),
987 CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000),
988 CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000),
989 CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000),
990 CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000),
991 CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080),
992 CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080),
993 CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080),
994 CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080),
995 CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000),
996 CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000),
997 CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000),
998 CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000),
999 CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080),
1000 CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080),
1001 CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080),
1002 CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080),
1003 CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000),
1004 CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000),
1005 CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000),
1006 CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000),
1007 CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080),
1008 CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080),
1009 CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080),
1010 CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080),
1011 CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000),
1012 CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000),
1013 CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000),
1014 CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000),
1015 CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080),
1016 CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080),
1017 CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080),
1018 CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080),
1019 CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000),
1020 CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000),
1021 CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000),
1022 CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000),
1023 CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080),
1024 CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080),
1025 CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080),
1026 CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080),
1027 CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000),
1028 CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000),
1029 CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000),
1030 CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000),
1031 CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080),
1032 CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080),
1033 CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080),
1034 CONST64(0x8080800000808080), CONST64(0x8080802000808080), CONST64(0x8080800080808080), CONST64(0x8080802080808080)
1035 },
1036 { CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000),
1037 CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000),
1038 CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100),
1039 CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100),
1040 CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001),
1041 CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001),
1042 CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101),
1043 CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101),
1044 CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000),
1045 CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000),
1046 CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100),
1047 CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100),
1048 CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001),
1049 CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001),
1050 CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101),
1051 CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101),
1052 CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000),
1053 CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000),
1054 CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100),
1055 CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100),
1056 CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001),
1057 CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001),
1058 CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101),
1059 CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101),
1060 CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000),
1061 CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000),
1062 CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100),
1063 CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100),
1064 CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001),
1065 CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001),
1066 CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101),
1067 CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101),
1068 CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000),
1069 CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000),
1070 CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100),
1071 CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100),
1072 CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001),
1073 CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001),
1074 CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101),
1075 CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101),
1076 CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000),
1077 CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000),
1078 CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100),
1079 CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100),
1080 CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001),
1081 CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001),
1082 CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101),
1083 CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101),
1084 CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000),
1085 CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000),
1086 CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100),
1087 CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100),
1088 CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001),
1089 CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001),
1090 CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101),
1091 CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101),
1092 CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000),
1093 CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000),
1094 CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100),
1095 CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100),
1096 CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001),
1097 CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001),
1098 CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101),
1099 CONST64(0x0101010000010101), CONST64(0x0101014000010101), CONST64(0x0101010001010101), CONST64(0x0101014001010101)
1100 },
1101 { CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000),
1102 CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000),
1103 CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400),
1104 CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400),
1105 CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004),
1106 CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004),
1107 CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404),
1108 CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404),
1109 CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000),
1110 CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000),
1111 CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400),
1112 CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400),
1113 CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004),
1114 CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004),
1115 CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404),
1116 CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404),
1117 CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000),
1118 CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000),
1119 CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400),
1120 CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400),
1121 CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004),
1122 CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004),
1123 CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404),
1124 CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404),
1125 CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000),
1126 CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000),
1127 CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400),
1128 CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400),
1129 CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004),
1130 CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004),
1131 CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404),
1132 CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404),
1133 CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000),
1134 CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000),
1135 CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400),
1136 CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400),
1137 CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004),
1138 CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004),
1139 CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404),
1140 CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404),
1141 CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000),
1142 CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000),
1143 CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400),
1144 CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400),
1145 CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004),
1146 CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004),
1147 CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404),
1148 CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404),
1149 CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000),
1150 CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000),
1151 CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400),
1152 CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400),
1153 CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004),
1154 CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004),
1155 CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404),
1156 CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404),
1157 CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000),
1158 CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000),
1159 CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400),
1160 CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400),
1161 CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004),
1162 CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004),
1163 CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404),
1164 CONST64(0x0404040000040404), CONST64(0x0404040100040404), CONST64(0x0404040004040404), CONST64(0x0404040104040404)
1165 },
1166 { CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000),
1167 CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000),
1168 CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000),
1169 CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000),
1170 CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010),
1171 CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010),
1172 CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010),
1173 CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010),
1174 CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000),
1175 CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000),
1176 CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000),
1177 CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000),
1178 CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010),
1179 CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010),
1180 CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010),
1181 CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010),
1182 CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000),
1183 CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000),
1184 CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000),
1185 CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000),
1186 CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010),
1187 CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010),
1188 CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010),
1189 CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010),
1190 CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000),
1191 CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000),
1192 CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000),
1193 CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000),
1194 CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010),
1195 CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010),
1196 CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010),
1197 CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010),
1198 CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000),
1199 CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000),
1200 CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000),
1201 CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000),
1202 CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010),
1203 CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010),
1204 CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010),
1205 CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010),
1206 CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000),
1207 CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000),
1208 CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000),
1209 CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000),
1210 CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010),
1211 CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010),
1212 CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010),
1213 CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010),
1214 CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000),
1215 CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000),
1216 CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000),
1217 CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000),
1218 CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010),
1219 CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010),
1220 CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010),
1221 CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010),
1222 CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000),
1223 CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000),
1224 CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000),
1225 CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000),
1226 CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010),
1227 CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010),
1228 CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010),
1229 CONST64(0x1010100000101010), CONST64(0x1010100400101010), CONST64(0x1010100010101010), CONST64(0x1010100410101010)
1230 },
1231 { CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000),
1232 CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000),
1233 CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000),
1234 CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000),
1235 CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040),
1236 CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040),
1237 CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040),
1238 CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040),
1239 CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000),
1240 CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000),
1241 CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000),
1242 CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000),
1243 CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040),
1244 CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040),
1245 CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040),
1246 CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040),
1247 CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000),
1248 CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000),
1249 CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000),
1250 CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000),
1251 CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040),
1252 CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040),
1253 CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040),
1254 CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040),
1255 CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000),
1256 CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000),
1257 CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000),
1258 CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000),
1259 CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040),
1260 CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040),
1261 CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040),
1262 CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040),
1263 CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000),
1264 CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000),
1265 CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000),
1266 CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000),
1267 CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040),
1268 CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040),
1269 CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040),
1270 CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040),
1271 CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000),
1272 CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000),
1273 CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000),
1274 CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000),
1275 CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040),
1276 CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040),
1277 CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040),
1278 CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040),
1279 CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000),
1280 CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000),
1281 CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000),
1282 CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000),
1283 CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040),
1284 CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040),
1285 CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040),
1286 CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040),
1287 CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000),
1288 CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000),
1289 CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000),
1290 CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000),
1291 CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040),
1292 CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040),
1293 CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040),
1294 CONST64(0x4040400000404040), CONST64(0x4040401000404040), CONST64(0x4040400040404040), CONST64(0x4040401040404040)
1295 }};
1296
1297 #endif
1298
1299
1300 static void cookey(const ulong32 *raw1, ulong32 *keyout);
1301
1302 #ifdef LTC_CLEAN_STACK
1303 static void _deskey(const unsigned char *key, short edf, ulong32 *keyout)
1304 #else
1305 static void deskey(const unsigned char *key, short edf, ulong32 *keyout)
1306 #endif
1307 {
1308 ulong32 i, j, l, m, n, kn[32];
1309 unsigned char pc1m[56], pcr[56];
1310
1311 for (j=0; j < 56; j++) {
1312 l = (ulong32)pc1[j];
1313 m = l & 7;
1314 pc1m[j] = (unsigned char)((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0);
1315 }
1316
1317 for (i=0; i < 16; i++) {
1318 if (edf == DE1) {
1319 m = (15 - i) << 1;
1320 } else {
1321 m = i << 1;
1322 }
1323 n = m + 1;
1324 kn[m] = kn[n] = 0L;
1325 for (j=0; j < 28; j++) {
1326 l = j + (ulong32)totrot[i];
1327 if (l < 28) {
1328 pcr[j] = pc1m[l];
1329 } else {
1330 pcr[j] = pc1m[l - 28];
1331 }
1332 }
1333 for (/*j = 28*/; j < 56; j++) {
1334 l = j + (ulong32)totrot[i];
1335 if (l < 56) {
1336 pcr[j] = pc1m[l];
1337 } else {
1338 pcr[j] = pc1m[l - 28];
1339 }
1340 }
1341 for (j=0; j < 24; j++) {
1342 if ((int)pcr[(int)pc2[j]] != 0) {
1343 kn[m] |= bigbyte[j];
1344 }
1345 if ((int)pcr[(int)pc2[j+24]] != 0) {
1346 kn[n] |= bigbyte[j];
1347 }
1348 }
1349 }
1350
1351 cookey(kn, keyout);
1352 }
1353
1354 #ifdef LTC_CLEAN_STACK
1355 static void deskey(const unsigned char *key, short edf, ulong32 *keyout)
1356 {
1357 _deskey(key, edf, keyout);
1358 burn_stack(sizeof(int)*5 + sizeof(ulong32)*32 + sizeof(unsigned char)*112);
1359 }
1360 #endif
1361
1362 #ifdef LTC_CLEAN_STACK
1363 static void _cookey(const ulong32 *raw1, ulong32 *keyout)
1364 #else
1365 static void cookey(const ulong32 *raw1, ulong32 *keyout)
1366 #endif
1367 {
1368 ulong32 *cook;
1369 const ulong32 *raw0;
1370 ulong32 dough[32];
1371 int i;
1372
1373 cook = dough;
1374 for(i=0; i < 16; i++, raw1++)
1375 {
1376 raw0 = raw1++;
1377 *cook = (*raw0 & 0x00fc0000L) << 6;
1378 *cook |= (*raw0 & 0x00000fc0L) << 10;
1379 *cook |= (*raw1 & 0x00fc0000L) >> 10;
1380 *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
1381 *cook = (*raw0 & 0x0003f000L) << 12;
1382 *cook |= (*raw0 & 0x0000003fL) << 16;
1383 *cook |= (*raw1 & 0x0003f000L) >> 4;
1384 *cook++ |= (*raw1 & 0x0000003fL);
1385 }
1386
1387 XMEMCPY(keyout, dough, sizeof dough);
1388 }
1389
1390 #ifdef LTC_CLEAN_STACK
1391 static void cookey(const ulong32 *raw1, ulong32 *keyout)
1392 {
1393 _cookey(raw1, keyout);
1394 burn_stack(sizeof(ulong32 *) * 2 + sizeof(ulong32)*32 + sizeof(int));
1395 }
1396 #endif
1397
1398 #ifndef LTC_CLEAN_STACK
1399 static void desfunc(ulong32 *block, const ulong32 *keys)
1400 #else
1401 static void _desfunc(ulong32 *block, const ulong32 *keys)
1402 #endif
1403 {
1404 ulong32 work, right, leftt;
1405 int cur_round;
1406
1407 leftt = block[0];
1408 right = block[1];
1409
1410 #ifdef LTC_SMALL_CODE
1411 work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
1412 right ^= work;
1413 leftt ^= (work << 4);
1414
1415 work = ((leftt >> 16) ^ right) & 0x0000ffffL;
1416 right ^= work;
1417 leftt ^= (work << 16);
1418
1419 work = ((right >> 2) ^ leftt) & 0x33333333L;
1420 leftt ^= work;
1421 right ^= (work << 2);
1422
1423 work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
1424 leftt ^= work;
1425 right ^= (work << 8);
1426
1427 right = ROLc(right, 1);
1428 work = (leftt ^ right) & 0xaaaaaaaaL;
1429
1430 leftt ^= work;
1431 right ^= work;
1432 leftt = ROLc(leftt, 1);
1433 #else
1434 {
1435 ulong64 tmp;
1436 tmp = des_ip[0][byte(leftt, 0)] ^
1437 des_ip[1][byte(leftt, 1)] ^
1438 des_ip[2][byte(leftt, 2)] ^
1439 des_ip[3][byte(leftt, 3)] ^
1440 des_ip[4][byte(right, 0)] ^
1441 des_ip[5][byte(right, 1)] ^
1442 des_ip[6][byte(right, 2)] ^
1443 des_ip[7][byte(right, 3)];
1444 leftt = (ulong32)(tmp >> 32);
1445 right = (ulong32)(tmp & 0xFFFFFFFFUL);
1446 }
1447 #endif
1448
1449 for (cur_round = 0; cur_round < 8; cur_round++) {
1450 work = RORc(right, 4) ^ *keys++;
1451 leftt ^= SP7[work & 0x3fL]
1452 ^ SP5[(work >> 8) & 0x3fL]
1453 ^ SP3[(work >> 16) & 0x3fL]
1454 ^ SP1[(work >> 24) & 0x3fL];
1455 work = right ^ *keys++;
1456 leftt ^= SP8[ work & 0x3fL]
1457 ^ SP6[(work >> 8) & 0x3fL]
1458 ^ SP4[(work >> 16) & 0x3fL]
1459 ^ SP2[(work >> 24) & 0x3fL];
1460
1461 work = RORc(leftt, 4) ^ *keys++;
1462 right ^= SP7[ work & 0x3fL]
1463 ^ SP5[(work >> 8) & 0x3fL]
1464 ^ SP3[(work >> 16) & 0x3fL]
1465 ^ SP1[(work >> 24) & 0x3fL];
1466 work = leftt ^ *keys++;
1467 right ^= SP8[ work & 0x3fL]
1468 ^ SP6[(work >> 8) & 0x3fL]
1469 ^ SP4[(work >> 16) & 0x3fL]
1470 ^ SP2[(work >> 24) & 0x3fL];
1471 }
1472
1473 #ifdef LTC_SMALL_CODE
1474 right = RORc(right, 1);
1475 work = (leftt ^ right) & 0xaaaaaaaaL;
1476 leftt ^= work;
1477 right ^= work;
1478 leftt = RORc(leftt, 1);
1479 work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
1480 right ^= work;
1481 leftt ^= (work << 8);
1482 /* -- */
1483 work = ((leftt >> 2) ^ right) & 0x33333333L;
1484 right ^= work;
1485 leftt ^= (work << 2);
1486 work = ((right >> 16) ^ leftt) & 0x0000ffffL;
1487 leftt ^= work;
1488 right ^= (work << 16);
1489 work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
1490 leftt ^= work;
1491 right ^= (work << 4);
1492 #else
1493 {
1494 ulong64 tmp;
1495 tmp = des_fp[0][byte(leftt, 0)] ^
1496 des_fp[1][byte(leftt, 1)] ^
1497 des_fp[2][byte(leftt, 2)] ^
1498 des_fp[3][byte(leftt, 3)] ^
1499 des_fp[4][byte(right, 0)] ^
1500 des_fp[5][byte(right, 1)] ^
1501 des_fp[6][byte(right, 2)] ^
1502 des_fp[7][byte(right, 3)];
1503 leftt = (ulong32)(tmp >> 32);
1504 right = (ulong32)(tmp & 0xFFFFFFFFUL);
1505 }
1506 #endif
1507
1508 block[0] = right;
1509 block[1] = leftt;
1510 }
1511
1512 #ifdef LTC_CLEAN_STACK
1513 static void desfunc(ulong32 *block, const ulong32 *keys)
1514 {
1515 _desfunc(block, keys);
1516 burn_stack(sizeof(ulong32) * 4 + sizeof(int));
1517 }
1518 #endif
1519
1520 /**
1521 Initialize the LTC_DES block cipher
1522 @param key The symmetric key you wish to pass
1523 @param keylen The key length in bytes
1524 @param num_rounds The number of rounds desired (0 for default)
1525 @param skey The key in as scheduled by this function.
1526 @return CRYPT_OK if successful
1527 */
1528 int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
1529 {
1530 LTC_ARGCHK(key != NULL);
1531 LTC_ARGCHK(skey != NULL);
1532
1533 if (num_rounds != 0 && num_rounds != 16) {
1534 return CRYPT_INVALID_ROUNDS;
1535 }
1536
1537 if (keylen != 8) {
1538 return CRYPT_INVALID_KEYSIZE;
1539 }
1540
1541 deskey(key, EN0, skey->des.ek);
1542 deskey(key, DE1, skey->des.dk);
1543
1544 return CRYPT_OK;
1545 }
1546
1547 /**
1548 Initialize the 3LTC_DES-EDE block cipher
1549 @param key The symmetric key you wish to pass
1550 @param keylen The key length in bytes
1551 @param num_rounds The number of rounds desired (0 for default)
1552 @param skey The key in as scheduled by this function.
1553 @return CRYPT_OK if successful
1554 */
1555 int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
1556 {
1557 LTC_ARGCHK(key != NULL);
1558 LTC_ARGCHK(skey != NULL);
1559
1560 if(num_rounds != 0 && num_rounds != 16) {
1561 return CRYPT_INVALID_ROUNDS;
1562 }
1563
1564 if (keylen != 24) {
1565 return CRYPT_INVALID_KEYSIZE;
1566 }
1567
1568 deskey(key, EN0, skey->des3.ek[0]);
1569 deskey(key+8, DE1, skey->des3.ek[1]);
1570 deskey(key+16, EN0, skey->des3.ek[2]);
1571
1572 deskey(key, DE1, skey->des3.dk[2]);
1573 deskey(key+8, EN0, skey->des3.dk[1]);
1574 deskey(key+16, DE1, skey->des3.dk[0]);
1575
1576 return CRYPT_OK;
1577 }
1578
1579 /**
1580 Encrypts a block of text with LTC_DES
1581 @param pt The input plaintext (8 bytes)
1582 @param ct The output ciphertext (8 bytes)
1583 @param skey The key as scheduled
1584 @return CRYPT_OK if successful
1585 */
1586 int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
1587 {
1588 ulong32 work[2];
1589 LTC_ARGCHK(pt != NULL);
1590 LTC_ARGCHK(ct != NULL);
1591 LTC_ARGCHK(skey != NULL);
1592 LOAD32H(work[0], pt+0);
1593 LOAD32H(work[1], pt+4);
1594 desfunc(work, skey->des.ek);
1595 STORE32H(work[0],ct+0);
1596 STORE32H(work[1],ct+4);
1597 return CRYPT_OK;
1598 }
1599
1600 /**
1601 Decrypts a block of text with LTC_DES
1602 @param ct The input ciphertext (8 bytes)
1603 @param pt The output plaintext (8 bytes)
1604 @param skey The key as scheduled
1605 @return CRYPT_OK if successful
1606 */
1607 int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
1608 {
1609 ulong32 work[2];
1610 LTC_ARGCHK(pt != NULL);
1611 LTC_ARGCHK(ct != NULL);
1612 LTC_ARGCHK(skey != NULL);
1613 LOAD32H(work[0], ct+0);
1614 LOAD32H(work[1], ct+4);
1615 desfunc(work, skey->des.dk);
1616 STORE32H(work[0],pt+0);
1617 STORE32H(work[1],pt+4);
1618 return CRYPT_OK;
1619 }
1620
1621 /**
1622 Encrypts a block of text with 3LTC_DES-EDE
1623 @param pt The input plaintext (8 bytes)
1624 @param ct The output ciphertext (8 bytes)
1625 @param skey The key as scheduled
1626 @return CRYPT_OK if successful
1627 */
1628 int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
1629 {
1630 ulong32 work[2];
1631
1632 LTC_ARGCHK(pt != NULL);
1633 LTC_ARGCHK(ct != NULL);
1634 LTC_ARGCHK(skey != NULL);
1635 LOAD32H(work[0], pt+0);
1636 LOAD32H(work[1], pt+4);
1637 desfunc(work, skey->des3.ek[0]);
1638 desfunc(work, skey->des3.ek[1]);
1639 desfunc(work, skey->des3.ek[2]);
1640 STORE32H(work[0],ct+0);
1641 STORE32H(work[1],ct+4);
1642 return CRYPT_OK;
1643 }
1644
1645 /**
1646 Decrypts a block of text with 3LTC_DES-EDE
1647 @param ct The input ciphertext (8 bytes)
1648 @param pt The output plaintext (8 bytes)
1649 @param skey The key as scheduled
1650 @return CRYPT_OK if successful
1651 */
1652 int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
1653 {
1654 ulong32 work[2];
1655 LTC_ARGCHK(pt != NULL);
1656 LTC_ARGCHK(ct != NULL);
1657 LTC_ARGCHK(skey != NULL);
1658 LOAD32H(work[0], ct+0);
1659 LOAD32H(work[1], ct+4);
1660 desfunc(work, skey->des3.dk[0]);
1661 desfunc(work, skey->des3.dk[1]);
1662 desfunc(work, skey->des3.dk[2]);
1663 STORE32H(work[0],pt+0);
1664 STORE32H(work[1],pt+4);
1665 return CRYPT_OK;
1666 }
1667
1668 /**
1669 Performs a self-test of the LTC_DES block cipher
1670 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
1671 */
1672 int des_test(void)
1673 {
1674 #ifndef LTC_TEST
1675 return CRYPT_NOP;
1676 #else
1677 int err;
1678 static const struct des_test_case {
1679 int num, mode; /* mode 1 = encrypt */
1680 unsigned char key[8], txt[8], out[8];
1681 } cases[] = {
1682 { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A },
1683 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1684 { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } },
1685 { 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1686 { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 },
1687 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1688 { 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1689 { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 },
1690 { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1691 { 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1692 { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA },
1693 { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1694 { 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1695 { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F },
1696 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1697 { 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1698 { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 },
1699 { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1700 { 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1701 { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF },
1702 { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1703 { 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1704 { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F },
1705 { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1706 { 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1707 { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 },
1708 { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1709 {10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1710 { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A },
1711 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1712
1713 { 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A },
1714 { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 },
1715 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1716 { 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1717 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1718 { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } },
1719 { 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1720 { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1721 { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } },
1722 { 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1723 { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1724 { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } },
1725 { 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1726 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1727 { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } },
1728 { 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1729 { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1730 { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } },
1731 { 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1732 { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1733 { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } },
1734 { 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1735 { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1736 { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } },
1737 { 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1738 { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1739 { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } },
1740 {10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1741 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1742 { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } }
1743
1744 /*** more test cases you could add if you are not convinced (the above test cases aren't really too good):
1745
1746 key plaintext ciphertext
1747 0000000000000000 0000000000000000 8CA64DE9C1B123A7
1748 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58
1749 3000000000000000 1000000000000001 958E6E627A05557B
1750 1111111111111111 1111111111111111 F40379AB9E0EC533
1751 0123456789ABCDEF 1111111111111111 17668DFC7292532D
1752 1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD
1753 0000000000000000 0000000000000000 8CA64DE9C1B123A7
1754 FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4
1755 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B
1756 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271
1757 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A
1758 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A
1759 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095
1760 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B
1761 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09
1762 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A
1763 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F
1764 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088
1765 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77
1766 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A
1767 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56
1768 025816164629B007 480D39006EE762F2 A1F9915541020B56
1769 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556
1770 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC
1771 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A
1772 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41
1773 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
1774 0101010101010101 0123456789ABCDEF 617B3A0CE8F07100
1775 1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606
1776 E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7
1777 0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451
1778 FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE
1779 0123456789ABCDEF 0000000000000000 D5D44FF720683D0D
1780 FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2
1781
1782 http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt
1783 ***/
1784 };
1785 int i, y;
1786 unsigned char tmp[8];
1787 symmetric_key des;
1788
1789 for(i=0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++)
1790 {
1791 if ((err = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) {
1792 return err;
1793 }
1794 if (cases[i].mode != 0) {
1795 des_ecb_encrypt(cases[i].txt, tmp, &des);
1796 } else {
1797 des_ecb_decrypt(cases[i].txt, tmp, &des);
1798 }
1799
1800 if (XMEMCMP(cases[i].out, tmp, sizeof(tmp)) != 0) {
1801 return CRYPT_FAIL_TESTVECTOR;
1802 }
1803
1804 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
1805 for (y = 0; y < 8; y++) tmp[y] = 0;
1806 for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des);
1807 for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des);
1808 for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR;
1809 }
1810
1811 return CRYPT_OK;
1812 #endif
1813 }
1814
1815 int des3_test(void)
1816 {
1817 #ifndef LTC_TEST
1818 return CRYPT_NOP;
1819 #else
1820 unsigned char key[24], pt[8], ct[8], tmp[8];
1821 symmetric_key skey;
1822 int x, err;
1823
1824 if ((err = des_test()) != CRYPT_OK) {
1825 return err;
1826 }
1827
1828 for (x = 0; x < 8; x++) {
1829 pt[x] = x;
1830 }
1831
1832 for (x = 0; x < 24; x++) {
1833 key[x] = x;
1834 }
1835
1836 if ((err = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) {
1837 return err;
1838 }
1839
1840 des3_ecb_encrypt(pt, ct, &skey);
1841 des3_ecb_decrypt(ct, tmp, &skey);
1842
1843 if (XMEMCMP(pt, tmp, 8) != 0) {
1844 return CRYPT_FAIL_TESTVECTOR;
1845 }
1846
1847 return CRYPT_OK;
1848 #endif
1849 }
1850
1851 /** Terminate the context
1852 @param skey The scheduled key
1853 */
1854 void des_done(symmetric_key *skey)
1855 {
1856 }
1857
1858 /** Terminate the context
1859 @param skey The scheduled key
1860 */
1861 void des3_done(symmetric_key *skey)
1862 {
1863 }
1864
1865
1866 /**
1867 Gets suitable key size
1868 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
1869 @return CRYPT_OK if the input key size is acceptable.
1870 */
1871 int des_keysize(int *keysize)
1872 {
1873 LTC_ARGCHK(keysize != NULL);
1874 if(*keysize < 8) {
1875 return CRYPT_INVALID_KEYSIZE;
1876 }
1877 *keysize = 8;
1878 return CRYPT_OK;
1879 }
1880
1881 /**
1882 Gets suitable key size
1883 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
1884 @return CRYPT_OK if the input key size is acceptable.
1885 */
1886 int des3_keysize(int *keysize)
1887 {
1888 LTC_ARGCHK(keysize != NULL);
1889 if(*keysize < 24) {
1890 return CRYPT_INVALID_KEYSIZE;
1891 }
1892 *keysize = 24;
1893 return CRYPT_OK;
1894 }
1895
1896 #endif
1897
1898
1899 /* $Source$ */
1900 /* $Revision$ */
1901 /* $Date$ */
+0
-318
libtom-src/ciphers/kasumi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file kasumi.c
13 Implementation of the 3GPP Kasumi block cipher
14 Derived from the 3GPP standard source code
15 */
16
17 #include "tomcrypt.h"
18
19 #ifdef LTC_KASUMI
20
21 typedef unsigned u16;
22
23 #define ROL16(x, y) ((((x)<<(y)) | ((x)>>(16-(y)))) & 0xFFFF)
24
25 const struct ltc_cipher_descriptor kasumi_desc = {
26 "kasumi",
27 21,
28 16, 16, 8, 8,
29 &kasumi_setup,
30 &kasumi_ecb_encrypt,
31 &kasumi_ecb_decrypt,
32 &kasumi_test,
33 &kasumi_done,
34 &kasumi_keysize,
35 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
36 };
37
38 static u16 FI( u16 in, u16 subkey )
39 {
40 u16 nine, seven;
41 static const u16 S7[128] = {
42 54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18,123, 33,
43 55,113, 39,114, 21, 67, 65, 12, 47, 73, 46, 27, 25,111,124, 81,
44 53, 9,121, 79, 52, 60, 58, 48,101,127, 40,120,104, 70, 71, 43,
45 20,122, 72, 61, 23,109, 13,100, 77, 1, 16, 7, 82, 10,105, 98,
46 117,116, 76, 11, 89,106, 0,125,118, 99, 86, 69, 30, 57,126, 87,
47 112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66,
48 102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29,115, 44,
49 64,107,108, 24,110, 83, 36, 78, 42, 19, 15, 41, 88,119, 59, 3 };
50 static const u16 S9[512] = {
51 167,239,161,379,391,334, 9,338, 38,226, 48,358,452,385, 90,397,
52 183,253,147,331,415,340, 51,362,306,500,262, 82,216,159,356,177,
53 175,241,489, 37,206, 17, 0,333, 44,254,378, 58,143,220, 81,400,
54 95, 3,315,245, 54,235,218,405,472,264,172,494,371,290,399, 76,
55 165,197,395,121,257,480,423,212,240, 28,462,176,406,507,288,223,
56 501,407,249,265, 89,186,221,428,164, 74,440,196,458,421,350,163,
57 232,158,134,354, 13,250,491,142,191, 69,193,425,152,227,366,135,
58 344,300,276,242,437,320,113,278, 11,243, 87,317, 36, 93,496, 27,
59 487,446,482, 41, 68,156,457,131,326,403,339, 20, 39,115,442,124,
60 475,384,508, 53,112,170,479,151,126,169, 73,268,279,321,168,364,
61 363,292, 46,499,393,327,324, 24,456,267,157,460,488,426,309,229,
62 439,506,208,271,349,401,434,236, 16,209,359, 52, 56,120,199,277,
63 465,416,252,287,246, 6, 83,305,420,345,153,502, 65, 61,244,282,
64 173,222,418, 67,386,368,261,101,476,291,195,430, 49, 79,166,330,
65 280,383,373,128,382,408,155,495,367,388,274,107,459,417, 62,454,
66 132,225,203,316,234, 14,301, 91,503,286,424,211,347,307,140,374,
67 35,103,125,427, 19,214,453,146,498,314,444,230,256,329,198,285,
68 50,116, 78,410, 10,205,510,171,231, 45,139,467, 29, 86,505, 32,
69 72, 26,342,150,313,490,431,238,411,325,149,473, 40,119,174,355,
70 185,233,389, 71,448,273,372, 55,110,178,322, 12,469,392,369,190,
71 1,109,375,137,181, 88, 75,308,260,484, 98,272,370,275,412,111,
72 336,318, 4,504,492,259,304, 77,337,435, 21,357,303,332,483, 18,
73 47, 85, 25,497,474,289,100,269,296,478,270,106, 31,104,433, 84,
74 414,486,394, 96, 99,154,511,148,413,361,409,255,162,215,302,201,
75 266,351,343,144,441,365,108,298,251, 34,182,509,138,210,335,133,
76 311,352,328,141,396,346,123,319,450,281,429,228,443,481, 92,404,
77 485,422,248,297, 23,213,130,466, 22,217,283, 70,294,360,419,127,
78 312,377, 7,468,194, 2,117,295,463,258,224,447,247,187, 80,398,
79 284,353,105,390,299,471,470,184, 57,200,348, 63,204,188, 33,451,
80 97, 30,310,219, 94,160,129,493, 64,179,263,102,189,207,114,402,
81 438,477,387,122,192, 42,381, 5,145,118,180,449,293,323,136,380,
82 43, 66, 60,455,341,445,202,432, 8,237, 15,376,436,464, 59,461};
83
84 /* The sixteen bit input is split into two unequal halves, *
85 * nine bits and seven bits - as is the subkey */
86
87 nine = (u16)(in>>7)&0x1FF;
88 seven = (u16)(in&0x7F);
89
90 /* Now run the various operations */
91 nine = (u16)(S9[nine] ^ seven);
92 seven = (u16)(S7[seven] ^ (nine & 0x7F));
93 seven ^= (subkey>>9);
94 nine ^= (subkey&0x1FF);
95 nine = (u16)(S9[nine] ^ seven);
96 seven = (u16)(S7[seven] ^ (nine & 0x7F));
97 return (u16)(seven<<9) + nine;
98 }
99
100 static ulong32 FO( ulong32 in, int round_no, symmetric_key *key)
101 {
102 u16 left, right;
103
104 /* Split the input into two 16-bit words */
105 left = (u16)(in>>16);
106 right = (u16) in&0xFFFF;
107
108 /* Now apply the same basic transformation three times */
109 left ^= key->kasumi.KOi1[round_no];
110 left = FI( left, key->kasumi.KIi1[round_no] );
111 left ^= right;
112
113 right ^= key->kasumi.KOi2[round_no];
114 right = FI( right, key->kasumi.KIi2[round_no] );
115 right ^= left;
116
117 left ^= key->kasumi.KOi3[round_no];
118 left = FI( left, key->kasumi.KIi3[round_no] );
119 left ^= right;
120
121 return (((ulong32)right)<<16)+left;
122 }
123
124 static ulong32 FL( ulong32 in, int round_no, symmetric_key *key )
125 {
126 u16 l, r, a, b;
127 /* split out the left and right halves */
128 l = (u16)(in>>16);
129 r = (u16)(in)&0xFFFF;
130 /* do the FL() operations */
131 a = (u16) (l & key->kasumi.KLi1[round_no]);
132 r ^= ROL16(a,1);
133 b = (u16)(r | key->kasumi.KLi2[round_no]);
134 l ^= ROL16(b,1);
135 /* put the two halves back together */
136
137 return (((ulong32)l)<<16) + r;
138 }
139
140 int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
141 {
142 ulong32 left, right, temp;
143 int n;
144
145 LTC_ARGCHK(pt != NULL);
146 LTC_ARGCHK(ct != NULL);
147 LTC_ARGCHK(skey != NULL);
148
149 LOAD32H(left, pt);
150 LOAD32H(right, pt+4);
151
152 for (n = 0; n <= 7; ) {
153 temp = FL(left, n, skey);
154 temp = FO(temp, n++, skey);
155 right ^= temp;
156 temp = FO(right, n, skey);
157 temp = FL(temp, n++, skey);
158 left ^= temp;
159 }
160
161 STORE32H(left, ct);
162 STORE32H(right, ct+4);
163
164 return CRYPT_OK;
165 }
166
167 int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
168 {
169 ulong32 left, right, temp;
170 int n;
171
172 LTC_ARGCHK(pt != NULL);
173 LTC_ARGCHK(ct != NULL);
174 LTC_ARGCHK(skey != NULL);
175
176 LOAD32H(left, ct);
177 LOAD32H(right, ct+4);
178
179 for (n = 7; n >= 0; ) {
180 temp = FO(right, n, skey);
181 temp = FL(temp, n--, skey);
182 left ^= temp;
183 temp = FL(left, n, skey);
184 temp = FO(temp, n--, skey);
185 right ^= temp;
186 }
187
188 STORE32H(left, pt);
189 STORE32H(right, pt+4);
190
191 return CRYPT_OK;
192 }
193
194 int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
195 {
196 static const u16 C[8] = { 0x0123,0x4567,0x89AB,0xCDEF, 0xFEDC,0xBA98,0x7654,0x3210 };
197 u16 ukey[8], Kprime[8];
198 int n;
199
200 LTC_ARGCHK(key != NULL);
201 LTC_ARGCHK(skey != NULL);
202
203 if (keylen != 16) {
204 return CRYPT_INVALID_KEYSIZE;
205 }
206
207 if (num_rounds != 0 && num_rounds != 8) {
208 return CRYPT_INVALID_ROUNDS;
209 }
210
211 /* Start by ensuring the subkeys are endian correct on a 16-bit basis */
212 for (n = 0; n < 8; n++ ) {
213 ukey[n] = (((u16)key[2*n]) << 8) | key[2*n+1];
214 }
215
216 /* Now build the K'[] keys */
217 for (n = 0; n < 8; n++) {
218 Kprime[n] = ukey[n] ^ C[n];
219 }
220
221 /* Finally construct the various sub keys */
222 for(n = 0; n < 8; n++) {
223 skey->kasumi.KLi1[n] = ROL16(ukey[n],1);
224 skey->kasumi.KLi2[n] = Kprime[(n+2)&0x7];
225 skey->kasumi.KOi1[n] = ROL16(ukey[(n+1)&0x7],5);
226 skey->kasumi.KOi2[n] = ROL16(ukey[(n+5)&0x7],8);
227 skey->kasumi.KOi3[n] = ROL16(ukey[(n+6)&0x7],13);
228 skey->kasumi.KIi1[n] = Kprime[(n+4)&0x7];
229 skey->kasumi.KIi2[n] = Kprime[(n+3)&0x7];
230 skey->kasumi.KIi3[n] = Kprime[(n+7)&0x7];
231 }
232
233 return CRYPT_OK;
234 }
235
236 void kasumi_done(symmetric_key *skey)
237 {
238 }
239
240 int kasumi_keysize(int *keysize)
241 {
242 LTC_ARGCHK(keysize != NULL);
243 if (*keysize >= 16) {
244 *keysize = 16;
245 return CRYPT_OK;
246 } else {
247 return CRYPT_INVALID_KEYSIZE;
248 }
249 }
250
251 int kasumi_test(void)
252 {
253 #ifndef LTC_TEST
254 return CRYPT_NOP;
255 #else
256 static const struct {
257 unsigned char key[16], pt[8], ct[8];
258 } tests[] = {
259
260 {
261 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
262 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
263 { 0x4B, 0x58, 0xA7, 0x71, 0xAF, 0xC7, 0xE5, 0xE8 }
264 },
265
266 {
267 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
268 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
269 { 0x7E, 0xEF, 0x11, 0x3C, 0x95, 0xBB, 0x5A, 0x77 }
270 },
271
272 {
273 { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
274 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
275 { 0x5F, 0x14, 0x06, 0x86, 0xD7, 0xAD, 0x5A, 0x39 },
276 },
277
278 {
279 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
280 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
281 { 0x2E, 0x14, 0x91, 0xCF, 0x70, 0xAA, 0x46, 0x5D }
282 },
283
284 {
285 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 },
286 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
287 { 0xB5, 0x45, 0x86, 0xF4, 0xAB, 0x9A, 0xE5, 0x46 }
288 },
289
290 };
291 unsigned char buf[2][8];
292 symmetric_key key;
293 int err, x;
294
295 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
296 if ((err = kasumi_setup(tests[x].key, 16, 0, &key)) != CRYPT_OK) {
297 return err;
298 }
299 if ((err = kasumi_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
300 return err;
301 }
302 if ((err = kasumi_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
303 return err;
304 }
305 if (XMEMCMP(tests[x].pt, buf[1], 8) || XMEMCMP(tests[x].ct, buf[0], 8)) {
306 return CRYPT_FAIL_TESTVECTOR;
307 }
308 }
309 return CRYPT_OK;
310 #endif
311 }
312
313 #endif
314
315 /* $Source$ */
316 /* $Revision$ */
317 /* $Date$ */
+0
-855
libtom-src/ciphers/khazad.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file khazad.c
14 Khazad implementation derived from public domain source
15 Authors: Paulo S.L.M. Barreto and Vincent Rijmen.
16 */
17
18 #ifdef LTC_KHAZAD
19
20 const struct ltc_cipher_descriptor khazad_desc = {
21 "khazad",
22 18,
23 16, 16, 8, 8,
24 &khazad_setup,
25 &khazad_ecb_encrypt,
26 &khazad_ecb_decrypt,
27 &khazad_test,
28 &khazad_done,
29 &khazad_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 #define R 8
34 #define KEYSIZE 128
35 #define KEYSIZEB (KEYSIZE/8)
36 #define BLOCKSIZE 64
37 #define BLOCKSIZEB (BLOCKSIZE/8)
38
39 static const ulong64 T0[256] = {
40 CONST64(0xbad3d268bbb96a01), CONST64(0x54fc4d19e59a66b1), CONST64(0x2f71bc93e26514cd), CONST64(0x749ccdb925871b51),
41 CONST64(0x53f55102f7a257a4), CONST64(0xd3686bb8d0d6be03), CONST64(0xd26b6fbdd6deb504), CONST64(0x4dd72964b35285fe),
42 CONST64(0x50f05d0dfdba4aad), CONST64(0xace98a26cf09e063), CONST64(0x8d8a0e83091c9684), CONST64(0xbfdcc679a5914d1a),
43 CONST64(0x7090ddad3da7374d), CONST64(0x52f65507f1aa5ca3), CONST64(0x9ab352c87ba417e1), CONST64(0x4cd42d61b55a8ef9),
44 CONST64(0xea238f65460320ac), CONST64(0xd56273a6c4e68411), CONST64(0x97a466f155cc68c2), CONST64(0xd16e63b2dcc6a80d),
45 CONST64(0x3355ccffaa85d099), CONST64(0x51f35908fbb241aa), CONST64(0x5bed712ac7e20f9c), CONST64(0xa6f7a204f359ae55),
46 CONST64(0xde7f5f81febec120), CONST64(0x48d83d75ad7aa2e5), CONST64(0xa8e59a32d729cc7f), CONST64(0x99b65ec771bc0ae8),
47 CONST64(0xdb704b90e096e63b), CONST64(0x3256c8faac8ddb9e), CONST64(0xb7c4e65195d11522), CONST64(0xfc19d72b32b3aace),
48 CONST64(0xe338ab48704b7393), CONST64(0x9ebf42dc63843bfd), CONST64(0x91ae7eef41fc52d0), CONST64(0x9bb056cd7dac1ce6),
49 CONST64(0xe23baf4d76437894), CONST64(0xbbd0d66dbdb16106), CONST64(0x41c319589b32f1da), CONST64(0x6eb2a5cb7957e517),
50 CONST64(0xa5f2ae0bf941b35c), CONST64(0xcb400bc08016564b), CONST64(0x6bbdb1da677fc20c), CONST64(0x95a26efb59dc7ecc),
51 CONST64(0xa1febe1fe1619f40), CONST64(0xf308eb1810cbc3e3), CONST64(0xb1cefe4f81e12f30), CONST64(0x0206080a0c10160e),
52 CONST64(0xcc4917db922e675e), CONST64(0xc45137f3a26e3f66), CONST64(0x1d2774694ee8cf53), CONST64(0x143c504478a09c6c),
53 CONST64(0xc3582be8b0560e73), CONST64(0x63a591f2573f9a34), CONST64(0xda734f95e69eed3c), CONST64(0x5de76934d3d2358e),
54 CONST64(0x5fe1613edfc22380), CONST64(0xdc79578bf2aed72e), CONST64(0x7d87e99413cf486e), CONST64(0xcd4a13de94266c59),
55 CONST64(0x7f81e19e1fdf5e60), CONST64(0x5aee752fc1ea049b), CONST64(0x6cb4adc17547f319), CONST64(0x5ce46d31d5da3e89),
56 CONST64(0xf704fb0c08ebefff), CONST64(0x266a98bed42d47f2), CONST64(0xff1cdb2438abb7c7), CONST64(0xed2a937e543b11b9),
57 CONST64(0xe825876f4a1336a2), CONST64(0x9dba4ed3699c26f4), CONST64(0x6fb1a1ce7f5fee10), CONST64(0x8e8f028c03048b8d),
58 CONST64(0x192b647d56c8e34f), CONST64(0xa0fdba1ae7699447), CONST64(0xf00de7171ad3deea), CONST64(0x89861e97113cba98),
59 CONST64(0x0f113c332278692d), CONST64(0x07091c1b12383115), CONST64(0xafec8629c511fd6a), CONST64(0xfb10cb30208b9bdb),
60 CONST64(0x0818202830405838), CONST64(0x153f54417ea8976b), CONST64(0x0d1734392e687f23), CONST64(0x040c101418202c1c),
61 CONST64(0x0103040506080b07), CONST64(0x64ac8de94507ab21), CONST64(0xdf7c5b84f8b6ca27), CONST64(0x769ac5b329970d5f),
62 CONST64(0x798bf9800bef6472), CONST64(0xdd7a538ef4a6dc29), CONST64(0x3d47f4c98ef5b2b3), CONST64(0x163a584e74b08a62),
63 CONST64(0x3f41fcc382e5a4bd), CONST64(0x3759dcebb2a5fc85), CONST64(0x6db7a9c4734ff81e), CONST64(0x3848e0d890dd95a8),
64 CONST64(0xb9d6de67b1a17708), CONST64(0x7395d1a237bf2a44), CONST64(0xe926836a4c1b3da5), CONST64(0x355fd4e1beb5ea8b),
65 CONST64(0x55ff491ce3926db6), CONST64(0x7193d9a83baf3c4a), CONST64(0x7b8df18a07ff727c), CONST64(0x8c890a860f149d83),
66 CONST64(0x7296d5a731b72143), CONST64(0x88851a921734b19f), CONST64(0xf607ff090ee3e4f8), CONST64(0x2a7ea882fc4d33d6),
67 CONST64(0x3e42f8c684edafba), CONST64(0x5ee2653bd9ca2887), CONST64(0x27699cbbd2254cf5), CONST64(0x46ca0543890ac0cf),
68 CONST64(0x0c14303c28607424), CONST64(0x65af89ec430fa026), CONST64(0x68b8bdd56d67df05), CONST64(0x61a399f85b2f8c3a),
69 CONST64(0x03050c0f0a181d09), CONST64(0xc15e23e2bc46187d), CONST64(0x57f94116ef827bb8), CONST64(0xd6677fa9cefe9918),
70 CONST64(0xd976439aec86f035), CONST64(0x58e87d25cdfa1295), CONST64(0xd875479fea8efb32), CONST64(0x66aa85e34917bd2f),
71 CONST64(0xd7647bacc8f6921f), CONST64(0x3a4ee8d29ccd83a6), CONST64(0xc84507cf8a0e4b42), CONST64(0x3c44f0cc88fdb9b4),
72 CONST64(0xfa13cf35268390dc), CONST64(0x96a762f453c463c5), CONST64(0xa7f4a601f551a552), CONST64(0x98b55ac277b401ef),
73 CONST64(0xec29977b52331abe), CONST64(0xb8d5da62b7a97c0f), CONST64(0xc7543bfca876226f), CONST64(0xaeef822cc319f66d),
74 CONST64(0x69bbb9d06b6fd402), CONST64(0x4bdd317aa762bfec), CONST64(0xabe0963ddd31d176), CONST64(0xa9e69e37d121c778),
75 CONST64(0x67a981e64f1fb628), CONST64(0x0a1e28223c504e36), CONST64(0x47c901468f02cbc8), CONST64(0xf20bef1d16c3c8e4),
76 CONST64(0xb5c2ee5b99c1032c), CONST64(0x226688aacc0d6bee), CONST64(0xe532b356647b4981), CONST64(0xee2f9f715e230cb0),
77 CONST64(0xbedfc27ca399461d), CONST64(0x2b7dac87fa4538d1), CONST64(0x819e3ebf217ce2a0), CONST64(0x1236485a6c90a67e),
78 CONST64(0x839836b52d6cf4ae), CONST64(0x1b2d6c775ad8f541), CONST64(0x0e1238362470622a), CONST64(0x23658cafca0560e9),
79 CONST64(0xf502f30604fbf9f1), CONST64(0x45cf094c8312ddc6), CONST64(0x216384a5c61576e7), CONST64(0xce4f1fd19e3e7150),
80 CONST64(0x49db3970ab72a9e2), CONST64(0x2c74b09ce87d09c4), CONST64(0xf916c33a2c9b8dd5), CONST64(0xe637bf596e635488),
81 CONST64(0xb6c7e25493d91e25), CONST64(0x2878a088f05d25d8), CONST64(0x17395c4b72b88165), CONST64(0x829b32b02b64ffa9),
82 CONST64(0x1a2e68725cd0fe46), CONST64(0x8b80169d1d2cac96), CONST64(0xfe1fdf213ea3bcc0), CONST64(0x8a8312981b24a791),
83 CONST64(0x091b242d3648533f), CONST64(0xc94603ca8c064045), CONST64(0x879426a1354cd8b2), CONST64(0x4ed2256bb94a98f7),
84 CONST64(0xe13ea3427c5b659d), CONST64(0x2e72b896e46d1fca), CONST64(0xe431b75362734286), CONST64(0xe03da7477a536e9a),
85 CONST64(0xeb208b60400b2bab), CONST64(0x90ad7aea47f459d7), CONST64(0xa4f1aa0eff49b85b), CONST64(0x1e22786644f0d25a),
86 CONST64(0x85922eab395ccebc), CONST64(0x60a09dfd5d27873d), CONST64(0x0000000000000000), CONST64(0x256f94b1de355afb),
87 CONST64(0xf401f70302f3f2f6), CONST64(0xf10ee3121cdbd5ed), CONST64(0x94a16afe5fd475cb), CONST64(0x0b1d2c273a584531),
88 CONST64(0xe734bb5c686b5f8f), CONST64(0x759fc9bc238f1056), CONST64(0xef2c9b74582b07b7), CONST64(0x345cd0e4b8bde18c),
89 CONST64(0x3153c4f5a695c697), CONST64(0xd46177a3c2ee8f16), CONST64(0xd06d67b7dacea30a), CONST64(0x869722a43344d3b5),
90 CONST64(0x7e82e59b19d75567), CONST64(0xadea8e23c901eb64), CONST64(0xfd1ad32e34bba1c9), CONST64(0x297ba48df6552edf),
91 CONST64(0x3050c0f0a09dcd90), CONST64(0x3b4decd79ac588a1), CONST64(0x9fbc46d9658c30fa), CONST64(0xf815c73f2a9386d2),
92 CONST64(0xc6573ff9ae7e2968), CONST64(0x13354c5f6a98ad79), CONST64(0x060a181e14303a12), CONST64(0x050f14111e28271b),
93 CONST64(0xc55233f6a4663461), CONST64(0x113344556688bb77), CONST64(0x7799c1b62f9f0658), CONST64(0x7c84ed9115c74369),
94 CONST64(0x7a8ef58f01f7797b), CONST64(0x7888fd850de76f75), CONST64(0x365ad8eeb4adf782), CONST64(0x1c24706c48e0c454),
95 CONST64(0x394be4dd96d59eaf), CONST64(0x59eb7920cbf21992), CONST64(0x1828607850c0e848), CONST64(0x56fa4513e98a70bf),
96 CONST64(0xb3c8f6458df1393e), CONST64(0xb0cdfa4a87e92437), CONST64(0x246c90b4d83d51fc), CONST64(0x206080a0c01d7de0),
97 CONST64(0xb2cbf2408bf93239), CONST64(0x92ab72e04be44fd9), CONST64(0xa3f8b615ed71894e), CONST64(0xc05d27e7ba4e137a),
98 CONST64(0x44cc0d49851ad6c1), CONST64(0x62a695f751379133), CONST64(0x103040506080b070), CONST64(0xb4c1ea5e9fc9082b),
99 CONST64(0x84912aae3f54c5bb), CONST64(0x43c511529722e7d4), CONST64(0x93a876e54dec44de), CONST64(0xc25b2fedb65e0574),
100 CONST64(0x4ade357fa16ab4eb), CONST64(0xbddace73a9815b14), CONST64(0x8f8c0689050c808a), CONST64(0x2d77b499ee7502c3),
101 CONST64(0xbcd9ca76af895013), CONST64(0x9cb94ad66f942df3), CONST64(0x6abeb5df6177c90b), CONST64(0x40c01d5d9d3afadd),
102 CONST64(0xcf4c1bd498367a57), CONST64(0xa2fbb210eb798249), CONST64(0x809d3aba2774e9a7), CONST64(0x4fd1216ebf4293f0),
103 CONST64(0x1f217c6342f8d95d), CONST64(0xca430fc5861e5d4c), CONST64(0xaae39238db39da71), CONST64(0x42c61557912aecd3),
104 };
105
106 static const ulong64 T1[256] = {
107 CONST64(0xd3ba68d2b9bb016a), CONST64(0xfc54194d9ae5b166), CONST64(0x712f93bc65e2cd14), CONST64(0x9c74b9cd8725511b),
108 CONST64(0xf5530251a2f7a457), CONST64(0x68d3b86bd6d003be), CONST64(0x6bd2bd6fded604b5), CONST64(0xd74d642952b3fe85),
109 CONST64(0xf0500d5dbafdad4a), CONST64(0xe9ac268a09cf63e0), CONST64(0x8a8d830e1c098496), CONST64(0xdcbf79c691a51a4d),
110 CONST64(0x9070addda73d4d37), CONST64(0xf6520755aaf1a35c), CONST64(0xb39ac852a47be117), CONST64(0xd44c612d5ab5f98e),
111 CONST64(0x23ea658f0346ac20), CONST64(0x62d5a673e6c41184), CONST64(0xa497f166cc55c268), CONST64(0x6ed1b263c6dc0da8),
112 CONST64(0x5533ffcc85aa99d0), CONST64(0xf3510859b2fbaa41), CONST64(0xed5b2a71e2c79c0f), CONST64(0xf7a604a259f355ae),
113 CONST64(0x7fde815fbefe20c1), CONST64(0xd848753d7aade5a2), CONST64(0xe5a8329a29d77fcc), CONST64(0xb699c75ebc71e80a),
114 CONST64(0x70db904b96e03be6), CONST64(0x5632fac88dac9edb), CONST64(0xc4b751e6d1952215), CONST64(0x19fc2bd7b332ceaa),
115 CONST64(0x38e348ab4b709373), CONST64(0xbf9edc428463fd3b), CONST64(0xae91ef7efc41d052), CONST64(0xb09bcd56ac7de61c),
116 CONST64(0x3be24daf43769478), CONST64(0xd0bb6dd6b1bd0661), CONST64(0xc3415819329bdaf1), CONST64(0xb26ecba5577917e5),
117 CONST64(0xf2a50bae41f95cb3), CONST64(0x40cbc00b16804b56), CONST64(0xbd6bdab17f670cc2), CONST64(0xa295fb6edc59cc7e),
118 CONST64(0xfea11fbe61e1409f), CONST64(0x08f318ebcb10e3c3), CONST64(0xceb14ffee181302f), CONST64(0x06020a08100c0e16),
119 CONST64(0x49ccdb172e925e67), CONST64(0x51c4f3376ea2663f), CONST64(0x271d6974e84e53cf), CONST64(0x3c144450a0786c9c),
120 CONST64(0x58c3e82b56b0730e), CONST64(0xa563f2913f57349a), CONST64(0x73da954f9ee63ced), CONST64(0xe75d3469d2d38e35),
121 CONST64(0xe15f3e61c2df8023), CONST64(0x79dc8b57aef22ed7), CONST64(0x877d94e9cf136e48), CONST64(0x4acdde132694596c),
122 CONST64(0x817f9ee1df1f605e), CONST64(0xee5a2f75eac19b04), CONST64(0xb46cc1ad477519f3), CONST64(0xe45c316ddad5893e),
123 CONST64(0x04f70cfbeb08ffef), CONST64(0x6a26be982dd4f247), CONST64(0x1cff24dbab38c7b7), CONST64(0x2aed7e933b54b911),
124 CONST64(0x25e86f87134aa236), CONST64(0xba9dd34e9c69f426), CONST64(0xb16fcea15f7f10ee), CONST64(0x8f8e8c0204038d8b),
125 CONST64(0x2b197d64c8564fe3), CONST64(0xfda01aba69e74794), CONST64(0x0df017e7d31aeade), CONST64(0x8689971e3c1198ba),
126 CONST64(0x110f333c78222d69), CONST64(0x09071b1c38121531), CONST64(0xecaf298611c56afd), CONST64(0x10fb30cb8b20db9b),
127 CONST64(0x1808282040303858), CONST64(0x3f154154a87e6b97), CONST64(0x170d3934682e237f), CONST64(0x0c04141020181c2c),
128 CONST64(0x030105040806070b), CONST64(0xac64e98d074521ab), CONST64(0x7cdf845bb6f827ca), CONST64(0x9a76b3c597295f0d),
129 CONST64(0x8b7980f9ef0b7264), CONST64(0x7add8e53a6f429dc), CONST64(0x473dc9f4f58eb3b2), CONST64(0x3a164e58b074628a),
130 CONST64(0x413fc3fce582bda4), CONST64(0x5937ebdca5b285fc), CONST64(0xb76dc4a94f731ef8), CONST64(0x4838d8e0dd90a895),
131 CONST64(0xd6b967dea1b10877), CONST64(0x9573a2d1bf37442a), CONST64(0x26e96a831b4ca53d), CONST64(0x5f35e1d4b5be8bea),
132 CONST64(0xff551c4992e3b66d), CONST64(0x9371a8d9af3b4a3c), CONST64(0x8d7b8af1ff077c72), CONST64(0x898c860a140f839d),
133 CONST64(0x9672a7d5b7314321), CONST64(0x8588921a34179fb1), CONST64(0x07f609ffe30ef8e4), CONST64(0x7e2a82a84dfcd633),
134 CONST64(0x423ec6f8ed84baaf), CONST64(0xe25e3b65cad98728), CONST64(0x6927bb9c25d2f54c), CONST64(0xca4643050a89cfc0),
135 CONST64(0x140c3c3060282474), CONST64(0xaf65ec890f4326a0), CONST64(0xb868d5bd676d05df), CONST64(0xa361f8992f5b3a8c),
136 CONST64(0x05030f0c180a091d), CONST64(0x5ec1e22346bc7d18), CONST64(0xf957164182efb87b), CONST64(0x67d6a97ffece1899),
137 CONST64(0x76d99a4386ec35f0), CONST64(0xe858257dfacd9512), CONST64(0x75d89f478eea32fb), CONST64(0xaa66e38517492fbd),
138 CONST64(0x64d7ac7bf6c81f92), CONST64(0x4e3ad2e8cd9ca683), CONST64(0x45c8cf070e8a424b), CONST64(0x443cccf0fd88b4b9),
139 CONST64(0x13fa35cf8326dc90), CONST64(0xa796f462c453c563), CONST64(0xf4a701a651f552a5), CONST64(0xb598c25ab477ef01),
140 CONST64(0x29ec7b973352be1a), CONST64(0xd5b862daa9b70f7c), CONST64(0x54c7fc3b76a86f22), CONST64(0xefae2c8219c36df6),
141 CONST64(0xbb69d0b96f6b02d4), CONST64(0xdd4b7a3162a7ecbf), CONST64(0xe0ab3d9631dd76d1), CONST64(0xe6a9379e21d178c7),
142 CONST64(0xa967e6811f4f28b6), CONST64(0x1e0a2228503c364e), CONST64(0xc9474601028fc8cb), CONST64(0x0bf21defc316e4c8),
143 CONST64(0xc2b55beec1992c03), CONST64(0x6622aa880dccee6b), CONST64(0x32e556b37b648149), CONST64(0x2fee719f235eb00c),
144 CONST64(0xdfbe7cc299a31d46), CONST64(0x7d2b87ac45fad138), CONST64(0x9e81bf3e7c21a0e2), CONST64(0x36125a48906c7ea6),
145 CONST64(0x9883b5366c2daef4), CONST64(0x2d1b776cd85a41f5), CONST64(0x120e363870242a62), CONST64(0x6523af8c05cae960),
146 CONST64(0x02f506f3fb04f1f9), CONST64(0xcf454c091283c6dd), CONST64(0x6321a58415c6e776), CONST64(0x4fced11f3e9e5071),
147 CONST64(0xdb49703972abe2a9), CONST64(0x742c9cb07de8c409), CONST64(0x16f93ac39b2cd58d), CONST64(0x37e659bf636e8854),
148 CONST64(0xc7b654e2d993251e), CONST64(0x782888a05df0d825), CONST64(0x39174b5cb8726581), CONST64(0x9b82b032642ba9ff),
149 CONST64(0x2e1a7268d05c46fe), CONST64(0x808b9d162c1d96ac), CONST64(0x1ffe21dfa33ec0bc), CONST64(0x838a9812241b91a7),
150 CONST64(0x1b092d2448363f53), CONST64(0x46c9ca03068c4540), CONST64(0x9487a1264c35b2d8), CONST64(0xd24e6b254ab9f798),
151 CONST64(0x3ee142a35b7c9d65), CONST64(0x722e96b86de4ca1f), CONST64(0x31e453b773628642), CONST64(0x3de047a7537a9a6e),
152 CONST64(0x20eb608b0b40ab2b), CONST64(0xad90ea7af447d759), CONST64(0xf1a40eaa49ff5bb8), CONST64(0x221e6678f0445ad2),
153 CONST64(0x9285ab2e5c39bcce), CONST64(0xa060fd9d275d3d87), CONST64(0x0000000000000000), CONST64(0x6f25b19435defb5a),
154 CONST64(0x01f403f7f302f6f2), CONST64(0x0ef112e3db1cedd5), CONST64(0xa194fe6ad45fcb75), CONST64(0x1d0b272c583a3145),
155 CONST64(0x34e75cbb6b688f5f), CONST64(0x9f75bcc98f235610), CONST64(0x2cef749b2b58b707), CONST64(0x5c34e4d0bdb88ce1),
156 CONST64(0x5331f5c495a697c6), CONST64(0x61d4a377eec2168f), CONST64(0x6dd0b767ceda0aa3), CONST64(0x9786a4224433b5d3),
157 CONST64(0x827e9be5d7196755), CONST64(0xeaad238e01c964eb), CONST64(0x1afd2ed3bb34c9a1), CONST64(0x7b298da455f6df2e),
158 CONST64(0x5030f0c09da090cd), CONST64(0x4d3bd7ecc59aa188), CONST64(0xbc9fd9468c65fa30), CONST64(0x15f83fc7932ad286),
159 CONST64(0x57c6f93f7eae6829), CONST64(0x35135f4c986a79ad), CONST64(0x0a061e183014123a), CONST64(0x0f051114281e1b27),
160 CONST64(0x52c5f63366a46134), CONST64(0x33115544886677bb), CONST64(0x9977b6c19f2f5806), CONST64(0x847c91edc7156943),
161 CONST64(0x8e7a8ff5f7017b79), CONST64(0x887885fde70d756f), CONST64(0x5a36eed8adb482f7), CONST64(0x241c6c70e04854c4),
162 CONST64(0x4b39dde4d596af9e), CONST64(0xeb592079f2cb9219), CONST64(0x28187860c05048e8), CONST64(0xfa5613458ae9bf70),
163 CONST64(0xc8b345f6f18d3e39), CONST64(0xcdb04afae9873724), CONST64(0x6c24b4903dd8fc51), CONST64(0x6020a0801dc0e07d),
164 CONST64(0xcbb240f2f98b3932), CONST64(0xab92e072e44bd94f), CONST64(0xf8a315b671ed4e89), CONST64(0x5dc0e7274eba7a13),
165 CONST64(0xcc44490d1a85c1d6), CONST64(0xa662f79537513391), CONST64(0x30105040806070b0), CONST64(0xc1b45eeac99f2b08),
166 CONST64(0x9184ae2a543fbbc5), CONST64(0xc54352112297d4e7), CONST64(0xa893e576ec4dde44), CONST64(0x5bc2ed2f5eb67405),
167 CONST64(0xde4a7f356aa1ebb4), CONST64(0xdabd73ce81a9145b), CONST64(0x8c8f89060c058a80), CONST64(0x772d99b475eec302),
168 CONST64(0xd9bc76ca89af1350), CONST64(0xb99cd64a946ff32d), CONST64(0xbe6adfb577610bc9), CONST64(0xc0405d1d3a9dddfa),
169 CONST64(0x4ccfd41b3698577a), CONST64(0xfba210b279eb4982), CONST64(0x9d80ba3a7427a7e9), CONST64(0xd14f6e2142bff093),
170 CONST64(0x211f637cf8425dd9), CONST64(0x43cac50f1e864c5d), CONST64(0xe3aa389239db71da), CONST64(0xc64257152a91d3ec),
171 };
172
173 static const ulong64 T2[256] = {
174 CONST64(0xd268bad36a01bbb9), CONST64(0x4d1954fc66b1e59a), CONST64(0xbc932f7114cde265), CONST64(0xcdb9749c1b512587),
175 CONST64(0x510253f557a4f7a2), CONST64(0x6bb8d368be03d0d6), CONST64(0x6fbdd26bb504d6de), CONST64(0x29644dd785feb352),
176 CONST64(0x5d0d50f04aadfdba), CONST64(0x8a26ace9e063cf09), CONST64(0x0e838d8a9684091c), CONST64(0xc679bfdc4d1aa591),
177 CONST64(0xddad7090374d3da7), CONST64(0x550752f65ca3f1aa), CONST64(0x52c89ab317e17ba4), CONST64(0x2d614cd48ef9b55a),
178 CONST64(0x8f65ea2320ac4603), CONST64(0x73a6d5628411c4e6), CONST64(0x66f197a468c255cc), CONST64(0x63b2d16ea80ddcc6),
179 CONST64(0xccff3355d099aa85), CONST64(0x590851f341aafbb2), CONST64(0x712a5bed0f9cc7e2), CONST64(0xa204a6f7ae55f359),
180 CONST64(0x5f81de7fc120febe), CONST64(0x3d7548d8a2e5ad7a), CONST64(0x9a32a8e5cc7fd729), CONST64(0x5ec799b60ae871bc),
181 CONST64(0x4b90db70e63be096), CONST64(0xc8fa3256db9eac8d), CONST64(0xe651b7c4152295d1), CONST64(0xd72bfc19aace32b3),
182 CONST64(0xab48e3387393704b), CONST64(0x42dc9ebf3bfd6384), CONST64(0x7eef91ae52d041fc), CONST64(0x56cd9bb01ce67dac),
183 CONST64(0xaf4de23b78947643), CONST64(0xd66dbbd06106bdb1), CONST64(0x195841c3f1da9b32), CONST64(0xa5cb6eb2e5177957),
184 CONST64(0xae0ba5f2b35cf941), CONST64(0x0bc0cb40564b8016), CONST64(0xb1da6bbdc20c677f), CONST64(0x6efb95a27ecc59dc),
185 CONST64(0xbe1fa1fe9f40e161), CONST64(0xeb18f308c3e310cb), CONST64(0xfe4fb1ce2f3081e1), CONST64(0x080a0206160e0c10),
186 CONST64(0x17dbcc49675e922e), CONST64(0x37f3c4513f66a26e), CONST64(0x74691d27cf534ee8), CONST64(0x5044143c9c6c78a0),
187 CONST64(0x2be8c3580e73b056), CONST64(0x91f263a59a34573f), CONST64(0x4f95da73ed3ce69e), CONST64(0x69345de7358ed3d2),
188 CONST64(0x613e5fe12380dfc2), CONST64(0x578bdc79d72ef2ae), CONST64(0xe9947d87486e13cf), CONST64(0x13decd4a6c599426),
189 CONST64(0xe19e7f815e601fdf), CONST64(0x752f5aee049bc1ea), CONST64(0xadc16cb4f3197547), CONST64(0x6d315ce43e89d5da),
190 CONST64(0xfb0cf704efff08eb), CONST64(0x98be266a47f2d42d), CONST64(0xdb24ff1cb7c738ab), CONST64(0x937eed2a11b9543b),
191 CONST64(0x876fe82536a24a13), CONST64(0x4ed39dba26f4699c), CONST64(0xa1ce6fb1ee107f5f), CONST64(0x028c8e8f8b8d0304),
192 CONST64(0x647d192be34f56c8), CONST64(0xba1aa0fd9447e769), CONST64(0xe717f00ddeea1ad3), CONST64(0x1e978986ba98113c),
193 CONST64(0x3c330f11692d2278), CONST64(0x1c1b070931151238), CONST64(0x8629afecfd6ac511), CONST64(0xcb30fb109bdb208b),
194 CONST64(0x2028081858383040), CONST64(0x5441153f976b7ea8), CONST64(0x34390d177f232e68), CONST64(0x1014040c2c1c1820),
195 CONST64(0x040501030b070608), CONST64(0x8de964acab214507), CONST64(0x5b84df7cca27f8b6), CONST64(0xc5b3769a0d5f2997),
196 CONST64(0xf980798b64720bef), CONST64(0x538edd7adc29f4a6), CONST64(0xf4c93d47b2b38ef5), CONST64(0x584e163a8a6274b0),
197 CONST64(0xfcc33f41a4bd82e5), CONST64(0xdceb3759fc85b2a5), CONST64(0xa9c46db7f81e734f), CONST64(0xe0d8384895a890dd),
198 CONST64(0xde67b9d67708b1a1), CONST64(0xd1a273952a4437bf), CONST64(0x836ae9263da54c1b), CONST64(0xd4e1355fea8bbeb5),
199 CONST64(0x491c55ff6db6e392), CONST64(0xd9a871933c4a3baf), CONST64(0xf18a7b8d727c07ff), CONST64(0x0a868c899d830f14),
200 CONST64(0xd5a77296214331b7), CONST64(0x1a928885b19f1734), CONST64(0xff09f607e4f80ee3), CONST64(0xa8822a7e33d6fc4d),
201 CONST64(0xf8c63e42afba84ed), CONST64(0x653b5ee22887d9ca), CONST64(0x9cbb27694cf5d225), CONST64(0x054346cac0cf890a),
202 CONST64(0x303c0c1474242860), CONST64(0x89ec65afa026430f), CONST64(0xbdd568b8df056d67), CONST64(0x99f861a38c3a5b2f),
203 CONST64(0x0c0f03051d090a18), CONST64(0x23e2c15e187dbc46), CONST64(0x411657f97bb8ef82), CONST64(0x7fa9d6679918cefe),
204 CONST64(0x439ad976f035ec86), CONST64(0x7d2558e81295cdfa), CONST64(0x479fd875fb32ea8e), CONST64(0x85e366aabd2f4917),
205 CONST64(0x7bacd764921fc8f6), CONST64(0xe8d23a4e83a69ccd), CONST64(0x07cfc8454b428a0e), CONST64(0xf0cc3c44b9b488fd),
206 CONST64(0xcf35fa1390dc2683), CONST64(0x62f496a763c553c4), CONST64(0xa601a7f4a552f551), CONST64(0x5ac298b501ef77b4),
207 CONST64(0x977bec291abe5233), CONST64(0xda62b8d57c0fb7a9), CONST64(0x3bfcc754226fa876), CONST64(0x822caeeff66dc319),
208 CONST64(0xb9d069bbd4026b6f), CONST64(0x317a4bddbfeca762), CONST64(0x963dabe0d176dd31), CONST64(0x9e37a9e6c778d121),
209 CONST64(0x81e667a9b6284f1f), CONST64(0x28220a1e4e363c50), CONST64(0x014647c9cbc88f02), CONST64(0xef1df20bc8e416c3),
210 CONST64(0xee5bb5c2032c99c1), CONST64(0x88aa22666beecc0d), CONST64(0xb356e5324981647b), CONST64(0x9f71ee2f0cb05e23),
211 CONST64(0xc27cbedf461da399), CONST64(0xac872b7d38d1fa45), CONST64(0x3ebf819ee2a0217c), CONST64(0x485a1236a67e6c90),
212 CONST64(0x36b58398f4ae2d6c), CONST64(0x6c771b2df5415ad8), CONST64(0x38360e12622a2470), CONST64(0x8caf236560e9ca05),
213 CONST64(0xf306f502f9f104fb), CONST64(0x094c45cfddc68312), CONST64(0x84a5216376e7c615), CONST64(0x1fd1ce4f71509e3e),
214 CONST64(0x397049dba9e2ab72), CONST64(0xb09c2c7409c4e87d), CONST64(0xc33af9168dd52c9b), CONST64(0xbf59e63754886e63),
215 CONST64(0xe254b6c71e2593d9), CONST64(0xa088287825d8f05d), CONST64(0x5c4b1739816572b8), CONST64(0x32b0829bffa92b64),
216 CONST64(0x68721a2efe465cd0), CONST64(0x169d8b80ac961d2c), CONST64(0xdf21fe1fbcc03ea3), CONST64(0x12988a83a7911b24),
217 CONST64(0x242d091b533f3648), CONST64(0x03cac94640458c06), CONST64(0x26a18794d8b2354c), CONST64(0x256b4ed298f7b94a),
218 CONST64(0xa342e13e659d7c5b), CONST64(0xb8962e721fcae46d), CONST64(0xb753e43142866273), CONST64(0xa747e03d6e9a7a53),
219 CONST64(0x8b60eb202bab400b), CONST64(0x7aea90ad59d747f4), CONST64(0xaa0ea4f1b85bff49), CONST64(0x78661e22d25a44f0),
220 CONST64(0x2eab8592cebc395c), CONST64(0x9dfd60a0873d5d27), CONST64(0x0000000000000000), CONST64(0x94b1256f5afbde35),
221 CONST64(0xf703f401f2f602f3), CONST64(0xe312f10ed5ed1cdb), CONST64(0x6afe94a175cb5fd4), CONST64(0x2c270b1d45313a58),
222 CONST64(0xbb5ce7345f8f686b), CONST64(0xc9bc759f1056238f), CONST64(0x9b74ef2c07b7582b), CONST64(0xd0e4345ce18cb8bd),
223 CONST64(0xc4f53153c697a695), CONST64(0x77a3d4618f16c2ee), CONST64(0x67b7d06da30adace), CONST64(0x22a48697d3b53344),
224 CONST64(0xe59b7e82556719d7), CONST64(0x8e23adeaeb64c901), CONST64(0xd32efd1aa1c934bb), CONST64(0xa48d297b2edff655),
225 CONST64(0xc0f03050cd90a09d), CONST64(0xecd73b4d88a19ac5), CONST64(0x46d99fbc30fa658c), CONST64(0xc73ff81586d22a93),
226 CONST64(0x3ff9c6572968ae7e), CONST64(0x4c5f1335ad796a98), CONST64(0x181e060a3a121430), CONST64(0x1411050f271b1e28),
227 CONST64(0x33f6c5523461a466), CONST64(0x44551133bb776688), CONST64(0xc1b6779906582f9f), CONST64(0xed917c84436915c7),
228 CONST64(0xf58f7a8e797b01f7), CONST64(0xfd8578886f750de7), CONST64(0xd8ee365af782b4ad), CONST64(0x706c1c24c45448e0),
229 CONST64(0xe4dd394b9eaf96d5), CONST64(0x792059eb1992cbf2), CONST64(0x60781828e84850c0), CONST64(0x451356fa70bfe98a),
230 CONST64(0xf645b3c8393e8df1), CONST64(0xfa4ab0cd243787e9), CONST64(0x90b4246c51fcd83d), CONST64(0x80a020607de0c01d),
231 CONST64(0xf240b2cb32398bf9), CONST64(0x72e092ab4fd94be4), CONST64(0xb615a3f8894eed71), CONST64(0x27e7c05d137aba4e),
232 CONST64(0x0d4944ccd6c1851a), CONST64(0x95f762a691335137), CONST64(0x40501030b0706080), CONST64(0xea5eb4c1082b9fc9),
233 CONST64(0x2aae8491c5bb3f54), CONST64(0x115243c5e7d49722), CONST64(0x76e593a844de4dec), CONST64(0x2fedc25b0574b65e),
234 CONST64(0x357f4adeb4eba16a), CONST64(0xce73bdda5b14a981), CONST64(0x06898f8c808a050c), CONST64(0xb4992d7702c3ee75),
235 CONST64(0xca76bcd95013af89), CONST64(0x4ad69cb92df36f94), CONST64(0xb5df6abec90b6177), CONST64(0x1d5d40c0fadd9d3a),
236 CONST64(0x1bd4cf4c7a579836), CONST64(0xb210a2fb8249eb79), CONST64(0x3aba809de9a72774), CONST64(0x216e4fd193f0bf42),
237 CONST64(0x7c631f21d95d42f8), CONST64(0x0fc5ca435d4c861e), CONST64(0x9238aae3da71db39), CONST64(0x155742c6ecd3912a),
238 };
239
240 static const ulong64 T3[256] = {
241 CONST64(0x68d2d3ba016ab9bb), CONST64(0x194dfc54b1669ae5), CONST64(0x93bc712fcd1465e2), CONST64(0xb9cd9c74511b8725),
242 CONST64(0x0251f553a457a2f7), CONST64(0xb86b68d303bed6d0), CONST64(0xbd6f6bd204b5ded6), CONST64(0x6429d74dfe8552b3),
243 CONST64(0x0d5df050ad4abafd), CONST64(0x268ae9ac63e009cf), CONST64(0x830e8a8d84961c09), CONST64(0x79c6dcbf1a4d91a5),
244 CONST64(0xaddd90704d37a73d), CONST64(0x0755f652a35caaf1), CONST64(0xc852b39ae117a47b), CONST64(0x612dd44cf98e5ab5),
245 CONST64(0x658f23eaac200346), CONST64(0xa67362d51184e6c4), CONST64(0xf166a497c268cc55), CONST64(0xb2636ed10da8c6dc),
246 CONST64(0xffcc553399d085aa), CONST64(0x0859f351aa41b2fb), CONST64(0x2a71ed5b9c0fe2c7), CONST64(0x04a2f7a655ae59f3),
247 CONST64(0x815f7fde20c1befe), CONST64(0x753dd848e5a27aad), CONST64(0x329ae5a87fcc29d7), CONST64(0xc75eb699e80abc71),
248 CONST64(0x904b70db3be696e0), CONST64(0xfac856329edb8dac), CONST64(0x51e6c4b72215d195), CONST64(0x2bd719fcceaab332),
249 CONST64(0x48ab38e393734b70), CONST64(0xdc42bf9efd3b8463), CONST64(0xef7eae91d052fc41), CONST64(0xcd56b09be61cac7d),
250 CONST64(0x4daf3be294784376), CONST64(0x6dd6d0bb0661b1bd), CONST64(0x5819c341daf1329b), CONST64(0xcba5b26e17e55779),
251 CONST64(0x0baef2a55cb341f9), CONST64(0xc00b40cb4b561680), CONST64(0xdab1bd6b0cc27f67), CONST64(0xfb6ea295cc7edc59),
252 CONST64(0x1fbefea1409f61e1), CONST64(0x18eb08f3e3c3cb10), CONST64(0x4ffeceb1302fe181), CONST64(0x0a0806020e16100c),
253 CONST64(0xdb1749cc5e672e92), CONST64(0xf33751c4663f6ea2), CONST64(0x6974271d53cfe84e), CONST64(0x44503c146c9ca078),
254 CONST64(0xe82b58c3730e56b0), CONST64(0xf291a563349a3f57), CONST64(0x954f73da3ced9ee6), CONST64(0x3469e75d8e35d2d3),
255 CONST64(0x3e61e15f8023c2df), CONST64(0x8b5779dc2ed7aef2), CONST64(0x94e9877d6e48cf13), CONST64(0xde134acd596c2694),
256 CONST64(0x9ee1817f605edf1f), CONST64(0x2f75ee5a9b04eac1), CONST64(0xc1adb46c19f34775), CONST64(0x316de45c893edad5),
257 CONST64(0x0cfb04f7ffefeb08), CONST64(0xbe986a26f2472dd4), CONST64(0x24db1cffc7b7ab38), CONST64(0x7e932aedb9113b54),
258 CONST64(0x6f8725e8a236134a), CONST64(0xd34eba9df4269c69), CONST64(0xcea1b16f10ee5f7f), CONST64(0x8c028f8e8d8b0403),
259 CONST64(0x7d642b194fe3c856), CONST64(0x1abafda0479469e7), CONST64(0x17e70df0eaded31a), CONST64(0x971e868998ba3c11),
260 CONST64(0x333c110f2d697822), CONST64(0x1b1c090715313812), CONST64(0x2986ecaf6afd11c5), CONST64(0x30cb10fbdb9b8b20),
261 CONST64(0x2820180838584030), CONST64(0x41543f156b97a87e), CONST64(0x3934170d237f682e), CONST64(0x14100c041c2c2018),
262 CONST64(0x05040301070b0806), CONST64(0xe98dac6421ab0745), CONST64(0x845b7cdf27cab6f8), CONST64(0xb3c59a765f0d9729),
263 CONST64(0x80f98b797264ef0b), CONST64(0x8e537add29dca6f4), CONST64(0xc9f4473db3b2f58e), CONST64(0x4e583a16628ab074),
264 CONST64(0xc3fc413fbda4e582), CONST64(0xebdc593785fca5b2), CONST64(0xc4a9b76d1ef84f73), CONST64(0xd8e04838a895dd90),
265 CONST64(0x67ded6b90877a1b1), CONST64(0xa2d19573442abf37), CONST64(0x6a8326e9a53d1b4c), CONST64(0xe1d45f358beab5be),
266 CONST64(0x1c49ff55b66d92e3), CONST64(0xa8d993714a3caf3b), CONST64(0x8af18d7b7c72ff07), CONST64(0x860a898c839d140f),
267 CONST64(0xa7d596724321b731), CONST64(0x921a85889fb13417), CONST64(0x09ff07f6f8e4e30e), CONST64(0x82a87e2ad6334dfc),
268 CONST64(0xc6f8423ebaafed84), CONST64(0x3b65e25e8728cad9), CONST64(0xbb9c6927f54c25d2), CONST64(0x4305ca46cfc00a89),
269 CONST64(0x3c30140c24746028), CONST64(0xec89af6526a00f43), CONST64(0xd5bdb86805df676d), CONST64(0xf899a3613a8c2f5b),
270 CONST64(0x0f0c0503091d180a), CONST64(0xe2235ec17d1846bc), CONST64(0x1641f957b87b82ef), CONST64(0xa97f67d61899fece),
271 CONST64(0x9a4376d935f086ec), CONST64(0x257de8589512facd), CONST64(0x9f4775d832fb8eea), CONST64(0xe385aa662fbd1749),
272 CONST64(0xac7b64d71f92f6c8), CONST64(0xd2e84e3aa683cd9c), CONST64(0xcf0745c8424b0e8a), CONST64(0xccf0443cb4b9fd88),
273 CONST64(0x35cf13fadc908326), CONST64(0xf462a796c563c453), CONST64(0x01a6f4a752a551f5), CONST64(0xc25ab598ef01b477),
274 CONST64(0x7b9729ecbe1a3352), CONST64(0x62dad5b80f7ca9b7), CONST64(0xfc3b54c76f2276a8), CONST64(0x2c82efae6df619c3),
275 CONST64(0xd0b9bb6902d46f6b), CONST64(0x7a31dd4becbf62a7), CONST64(0x3d96e0ab76d131dd), CONST64(0x379ee6a978c721d1),
276 CONST64(0xe681a96728b61f4f), CONST64(0x22281e0a364e503c), CONST64(0x4601c947c8cb028f), CONST64(0x1def0bf2e4c8c316),
277 CONST64(0x5beec2b52c03c199), CONST64(0xaa886622ee6b0dcc), CONST64(0x56b332e581497b64), CONST64(0x719f2feeb00c235e),
278 CONST64(0x7cc2dfbe1d4699a3), CONST64(0x87ac7d2bd13845fa), CONST64(0xbf3e9e81a0e27c21), CONST64(0x5a4836127ea6906c),
279 CONST64(0xb5369883aef46c2d), CONST64(0x776c2d1b41f5d85a), CONST64(0x3638120e2a627024), CONST64(0xaf8c6523e96005ca),
280 CONST64(0x06f302f5f1f9fb04), CONST64(0x4c09cf45c6dd1283), CONST64(0xa5846321e77615c6), CONST64(0xd11f4fce50713e9e),
281 CONST64(0x7039db49e2a972ab), CONST64(0x9cb0742cc4097de8), CONST64(0x3ac316f9d58d9b2c), CONST64(0x59bf37e68854636e),
282 CONST64(0x54e2c7b6251ed993), CONST64(0x88a07828d8255df0), CONST64(0x4b5c39176581b872), CONST64(0xb0329b82a9ff642b),
283 CONST64(0x72682e1a46fed05c), CONST64(0x9d16808b96ac2c1d), CONST64(0x21df1ffec0bca33e), CONST64(0x9812838a91a7241b),
284 CONST64(0x2d241b093f534836), CONST64(0xca0346c94540068c), CONST64(0xa1269487b2d84c35), CONST64(0x6b25d24ef7984ab9),
285 CONST64(0x42a33ee19d655b7c), CONST64(0x96b8722eca1f6de4), CONST64(0x53b731e486427362), CONST64(0x47a73de09a6e537a),
286 CONST64(0x608b20ebab2b0b40), CONST64(0xea7aad90d759f447), CONST64(0x0eaaf1a45bb849ff), CONST64(0x6678221e5ad2f044),
287 CONST64(0xab2e9285bcce5c39), CONST64(0xfd9da0603d87275d), CONST64(0x0000000000000000), CONST64(0xb1946f25fb5a35de),
288 CONST64(0x03f701f4f6f2f302), CONST64(0x12e30ef1edd5db1c), CONST64(0xfe6aa194cb75d45f), CONST64(0x272c1d0b3145583a),
289 CONST64(0x5cbb34e78f5f6b68), CONST64(0xbcc99f7556108f23), CONST64(0x749b2cefb7072b58), CONST64(0xe4d05c348ce1bdb8),
290 CONST64(0xf5c4533197c695a6), CONST64(0xa37761d4168feec2), CONST64(0xb7676dd00aa3ceda), CONST64(0xa4229786b5d34433),
291 CONST64(0x9be5827e6755d719), CONST64(0x238eeaad64eb01c9), CONST64(0x2ed31afdc9a1bb34), CONST64(0x8da47b29df2e55f6),
292 CONST64(0xf0c0503090cd9da0), CONST64(0xd7ec4d3ba188c59a), CONST64(0xd946bc9ffa308c65), CONST64(0x3fc715f8d286932a),
293 CONST64(0xf93f57c668297eae), CONST64(0x5f4c351379ad986a), CONST64(0x1e180a06123a3014), CONST64(0x11140f051b27281e),
294 CONST64(0xf63352c5613466a4), CONST64(0x5544331177bb8866), CONST64(0xb6c1997758069f2f), CONST64(0x91ed847c6943c715),
295 CONST64(0x8ff58e7a7b79f701), CONST64(0x85fd8878756fe70d), CONST64(0xeed85a3682f7adb4), CONST64(0x6c70241c54c4e048),
296 CONST64(0xdde44b39af9ed596), CONST64(0x2079eb599219f2cb), CONST64(0x7860281848e8c050), CONST64(0x1345fa56bf708ae9),
297 CONST64(0x45f6c8b33e39f18d), CONST64(0x4afacdb03724e987), CONST64(0xb4906c24fc513dd8), CONST64(0xa0806020e07d1dc0),
298 CONST64(0x40f2cbb23932f98b), CONST64(0xe072ab92d94fe44b), CONST64(0x15b6f8a34e8971ed), CONST64(0xe7275dc07a134eba),
299 CONST64(0x490dcc44c1d61a85), CONST64(0xf795a66233913751), CONST64(0x5040301070b08060), CONST64(0x5eeac1b42b08c99f),
300 CONST64(0xae2a9184bbc5543f), CONST64(0x5211c543d4e72297), CONST64(0xe576a893de44ec4d), CONST64(0xed2f5bc274055eb6),
301 CONST64(0x7f35de4aebb46aa1), CONST64(0x73cedabd145b81a9), CONST64(0x89068c8f8a800c05), CONST64(0x99b4772dc30275ee),
302 CONST64(0x76cad9bc135089af), CONST64(0xd64ab99cf32d946f), CONST64(0xdfb5be6a0bc97761), CONST64(0x5d1dc040ddfa3a9d),
303 CONST64(0xd41b4ccf577a3698), CONST64(0x10b2fba2498279eb), CONST64(0xba3a9d80a7e97427), CONST64(0x6e21d14ff09342bf),
304 CONST64(0x637c211f5dd9f842), CONST64(0xc50f43ca4c5d1e86), CONST64(0x3892e3aa71da39db), CONST64(0x5715c642d3ec2a91),
305 };
306
307 static const ulong64 T4[256] = {
308 CONST64(0xbbb96a01bad3d268), CONST64(0xe59a66b154fc4d19), CONST64(0xe26514cd2f71bc93), CONST64(0x25871b51749ccdb9),
309 CONST64(0xf7a257a453f55102), CONST64(0xd0d6be03d3686bb8), CONST64(0xd6deb504d26b6fbd), CONST64(0xb35285fe4dd72964),
310 CONST64(0xfdba4aad50f05d0d), CONST64(0xcf09e063ace98a26), CONST64(0x091c96848d8a0e83), CONST64(0xa5914d1abfdcc679),
311 CONST64(0x3da7374d7090ddad), CONST64(0xf1aa5ca352f65507), CONST64(0x7ba417e19ab352c8), CONST64(0xb55a8ef94cd42d61),
312 CONST64(0x460320acea238f65), CONST64(0xc4e68411d56273a6), CONST64(0x55cc68c297a466f1), CONST64(0xdcc6a80dd16e63b2),
313 CONST64(0xaa85d0993355ccff), CONST64(0xfbb241aa51f35908), CONST64(0xc7e20f9c5bed712a), CONST64(0xf359ae55a6f7a204),
314 CONST64(0xfebec120de7f5f81), CONST64(0xad7aa2e548d83d75), CONST64(0xd729cc7fa8e59a32), CONST64(0x71bc0ae899b65ec7),
315 CONST64(0xe096e63bdb704b90), CONST64(0xac8ddb9e3256c8fa), CONST64(0x95d11522b7c4e651), CONST64(0x32b3aacefc19d72b),
316 CONST64(0x704b7393e338ab48), CONST64(0x63843bfd9ebf42dc), CONST64(0x41fc52d091ae7eef), CONST64(0x7dac1ce69bb056cd),
317 CONST64(0x76437894e23baf4d), CONST64(0xbdb16106bbd0d66d), CONST64(0x9b32f1da41c31958), CONST64(0x7957e5176eb2a5cb),
318 CONST64(0xf941b35ca5f2ae0b), CONST64(0x8016564bcb400bc0), CONST64(0x677fc20c6bbdb1da), CONST64(0x59dc7ecc95a26efb),
319 CONST64(0xe1619f40a1febe1f), CONST64(0x10cbc3e3f308eb18), CONST64(0x81e12f30b1cefe4f), CONST64(0x0c10160e0206080a),
320 CONST64(0x922e675ecc4917db), CONST64(0xa26e3f66c45137f3), CONST64(0x4ee8cf531d277469), CONST64(0x78a09c6c143c5044),
321 CONST64(0xb0560e73c3582be8), CONST64(0x573f9a3463a591f2), CONST64(0xe69eed3cda734f95), CONST64(0xd3d2358e5de76934),
322 CONST64(0xdfc223805fe1613e), CONST64(0xf2aed72edc79578b), CONST64(0x13cf486e7d87e994), CONST64(0x94266c59cd4a13de),
323 CONST64(0x1fdf5e607f81e19e), CONST64(0xc1ea049b5aee752f), CONST64(0x7547f3196cb4adc1), CONST64(0xd5da3e895ce46d31),
324 CONST64(0x08ebeffff704fb0c), CONST64(0xd42d47f2266a98be), CONST64(0x38abb7c7ff1cdb24), CONST64(0x543b11b9ed2a937e),
325 CONST64(0x4a1336a2e825876f), CONST64(0x699c26f49dba4ed3), CONST64(0x7f5fee106fb1a1ce), CONST64(0x03048b8d8e8f028c),
326 CONST64(0x56c8e34f192b647d), CONST64(0xe7699447a0fdba1a), CONST64(0x1ad3deeaf00de717), CONST64(0x113cba9889861e97),
327 CONST64(0x2278692d0f113c33), CONST64(0x1238311507091c1b), CONST64(0xc511fd6aafec8629), CONST64(0x208b9bdbfb10cb30),
328 CONST64(0x3040583808182028), CONST64(0x7ea8976b153f5441), CONST64(0x2e687f230d173439), CONST64(0x18202c1c040c1014),
329 CONST64(0x06080b0701030405), CONST64(0x4507ab2164ac8de9), CONST64(0xf8b6ca27df7c5b84), CONST64(0x29970d5f769ac5b3),
330 CONST64(0x0bef6472798bf980), CONST64(0xf4a6dc29dd7a538e), CONST64(0x8ef5b2b33d47f4c9), CONST64(0x74b08a62163a584e),
331 CONST64(0x82e5a4bd3f41fcc3), CONST64(0xb2a5fc853759dceb), CONST64(0x734ff81e6db7a9c4), CONST64(0x90dd95a83848e0d8),
332 CONST64(0xb1a17708b9d6de67), CONST64(0x37bf2a447395d1a2), CONST64(0x4c1b3da5e926836a), CONST64(0xbeb5ea8b355fd4e1),
333 CONST64(0xe3926db655ff491c), CONST64(0x3baf3c4a7193d9a8), CONST64(0x07ff727c7b8df18a), CONST64(0x0f149d838c890a86),
334 CONST64(0x31b721437296d5a7), CONST64(0x1734b19f88851a92), CONST64(0x0ee3e4f8f607ff09), CONST64(0xfc4d33d62a7ea882),
335 CONST64(0x84edafba3e42f8c6), CONST64(0xd9ca28875ee2653b), CONST64(0xd2254cf527699cbb), CONST64(0x890ac0cf46ca0543),
336 CONST64(0x286074240c14303c), CONST64(0x430fa02665af89ec), CONST64(0x6d67df0568b8bdd5), CONST64(0x5b2f8c3a61a399f8),
337 CONST64(0x0a181d0903050c0f), CONST64(0xbc46187dc15e23e2), CONST64(0xef827bb857f94116), CONST64(0xcefe9918d6677fa9),
338 CONST64(0xec86f035d976439a), CONST64(0xcdfa129558e87d25), CONST64(0xea8efb32d875479f), CONST64(0x4917bd2f66aa85e3),
339 CONST64(0xc8f6921fd7647bac), CONST64(0x9ccd83a63a4ee8d2), CONST64(0x8a0e4b42c84507cf), CONST64(0x88fdb9b43c44f0cc),
340 CONST64(0x268390dcfa13cf35), CONST64(0x53c463c596a762f4), CONST64(0xf551a552a7f4a601), CONST64(0x77b401ef98b55ac2),
341 CONST64(0x52331abeec29977b), CONST64(0xb7a97c0fb8d5da62), CONST64(0xa876226fc7543bfc), CONST64(0xc319f66daeef822c),
342 CONST64(0x6b6fd40269bbb9d0), CONST64(0xa762bfec4bdd317a), CONST64(0xdd31d176abe0963d), CONST64(0xd121c778a9e69e37),
343 CONST64(0x4f1fb62867a981e6), CONST64(0x3c504e360a1e2822), CONST64(0x8f02cbc847c90146), CONST64(0x16c3c8e4f20bef1d),
344 CONST64(0x99c1032cb5c2ee5b), CONST64(0xcc0d6bee226688aa), CONST64(0x647b4981e532b356), CONST64(0x5e230cb0ee2f9f71),
345 CONST64(0xa399461dbedfc27c), CONST64(0xfa4538d12b7dac87), CONST64(0x217ce2a0819e3ebf), CONST64(0x6c90a67e1236485a),
346 CONST64(0x2d6cf4ae839836b5), CONST64(0x5ad8f5411b2d6c77), CONST64(0x2470622a0e123836), CONST64(0xca0560e923658caf),
347 CONST64(0x04fbf9f1f502f306), CONST64(0x8312ddc645cf094c), CONST64(0xc61576e7216384a5), CONST64(0x9e3e7150ce4f1fd1),
348 CONST64(0xab72a9e249db3970), CONST64(0xe87d09c42c74b09c), CONST64(0x2c9b8dd5f916c33a), CONST64(0x6e635488e637bf59),
349 CONST64(0x93d91e25b6c7e254), CONST64(0xf05d25d82878a088), CONST64(0x72b8816517395c4b), CONST64(0x2b64ffa9829b32b0),
350 CONST64(0x5cd0fe461a2e6872), CONST64(0x1d2cac968b80169d), CONST64(0x3ea3bcc0fe1fdf21), CONST64(0x1b24a7918a831298),
351 CONST64(0x3648533f091b242d), CONST64(0x8c064045c94603ca), CONST64(0x354cd8b2879426a1), CONST64(0xb94a98f74ed2256b),
352 CONST64(0x7c5b659de13ea342), CONST64(0xe46d1fca2e72b896), CONST64(0x62734286e431b753), CONST64(0x7a536e9ae03da747),
353 CONST64(0x400b2babeb208b60), CONST64(0x47f459d790ad7aea), CONST64(0xff49b85ba4f1aa0e), CONST64(0x44f0d25a1e227866),
354 CONST64(0x395ccebc85922eab), CONST64(0x5d27873d60a09dfd), CONST64(0x0000000000000000), CONST64(0xde355afb256f94b1),
355 CONST64(0x02f3f2f6f401f703), CONST64(0x1cdbd5edf10ee312), CONST64(0x5fd475cb94a16afe), CONST64(0x3a5845310b1d2c27),
356 CONST64(0x686b5f8fe734bb5c), CONST64(0x238f1056759fc9bc), CONST64(0x582b07b7ef2c9b74), CONST64(0xb8bde18c345cd0e4),
357 CONST64(0xa695c6973153c4f5), CONST64(0xc2ee8f16d46177a3), CONST64(0xdacea30ad06d67b7), CONST64(0x3344d3b5869722a4),
358 CONST64(0x19d755677e82e59b), CONST64(0xc901eb64adea8e23), CONST64(0x34bba1c9fd1ad32e), CONST64(0xf6552edf297ba48d),
359 CONST64(0xa09dcd903050c0f0), CONST64(0x9ac588a13b4decd7), CONST64(0x658c30fa9fbc46d9), CONST64(0x2a9386d2f815c73f),
360 CONST64(0xae7e2968c6573ff9), CONST64(0x6a98ad7913354c5f), CONST64(0x14303a12060a181e), CONST64(0x1e28271b050f1411),
361 CONST64(0xa4663461c55233f6), CONST64(0x6688bb7711334455), CONST64(0x2f9f06587799c1b6), CONST64(0x15c743697c84ed91),
362 CONST64(0x01f7797b7a8ef58f), CONST64(0x0de76f757888fd85), CONST64(0xb4adf782365ad8ee), CONST64(0x48e0c4541c24706c),
363 CONST64(0x96d59eaf394be4dd), CONST64(0xcbf2199259eb7920), CONST64(0x50c0e84818286078), CONST64(0xe98a70bf56fa4513),
364 CONST64(0x8df1393eb3c8f645), CONST64(0x87e92437b0cdfa4a), CONST64(0xd83d51fc246c90b4), CONST64(0xc01d7de0206080a0),
365 CONST64(0x8bf93239b2cbf240), CONST64(0x4be44fd992ab72e0), CONST64(0xed71894ea3f8b615), CONST64(0xba4e137ac05d27e7),
366 CONST64(0x851ad6c144cc0d49), CONST64(0x5137913362a695f7), CONST64(0x6080b07010304050), CONST64(0x9fc9082bb4c1ea5e),
367 CONST64(0x3f54c5bb84912aae), CONST64(0x9722e7d443c51152), CONST64(0x4dec44de93a876e5), CONST64(0xb65e0574c25b2fed),
368 CONST64(0xa16ab4eb4ade357f), CONST64(0xa9815b14bddace73), CONST64(0x050c808a8f8c0689), CONST64(0xee7502c32d77b499),
369 CONST64(0xaf895013bcd9ca76), CONST64(0x6f942df39cb94ad6), CONST64(0x6177c90b6abeb5df), CONST64(0x9d3afadd40c01d5d),
370 CONST64(0x98367a57cf4c1bd4), CONST64(0xeb798249a2fbb210), CONST64(0x2774e9a7809d3aba), CONST64(0xbf4293f04fd1216e),
371 CONST64(0x42f8d95d1f217c63), CONST64(0x861e5d4cca430fc5), CONST64(0xdb39da71aae39238), CONST64(0x912aecd342c61557),
372 };
373
374 static const ulong64 T5[256] = {
375 CONST64(0xb9bb016ad3ba68d2), CONST64(0x9ae5b166fc54194d), CONST64(0x65e2cd14712f93bc), CONST64(0x8725511b9c74b9cd),
376 CONST64(0xa2f7a457f5530251), CONST64(0xd6d003be68d3b86b), CONST64(0xded604b56bd2bd6f), CONST64(0x52b3fe85d74d6429),
377 CONST64(0xbafdad4af0500d5d), CONST64(0x09cf63e0e9ac268a), CONST64(0x1c0984968a8d830e), CONST64(0x91a51a4ddcbf79c6),
378 CONST64(0xa73d4d379070addd), CONST64(0xaaf1a35cf6520755), CONST64(0xa47be117b39ac852), CONST64(0x5ab5f98ed44c612d),
379 CONST64(0x0346ac2023ea658f), CONST64(0xe6c4118462d5a673), CONST64(0xcc55c268a497f166), CONST64(0xc6dc0da86ed1b263),
380 CONST64(0x85aa99d05533ffcc), CONST64(0xb2fbaa41f3510859), CONST64(0xe2c79c0fed5b2a71), CONST64(0x59f355aef7a604a2),
381 CONST64(0xbefe20c17fde815f), CONST64(0x7aade5a2d848753d), CONST64(0x29d77fcce5a8329a), CONST64(0xbc71e80ab699c75e),
382 CONST64(0x96e03be670db904b), CONST64(0x8dac9edb5632fac8), CONST64(0xd1952215c4b751e6), CONST64(0xb332ceaa19fc2bd7),
383 CONST64(0x4b70937338e348ab), CONST64(0x8463fd3bbf9edc42), CONST64(0xfc41d052ae91ef7e), CONST64(0xac7de61cb09bcd56),
384 CONST64(0x437694783be24daf), CONST64(0xb1bd0661d0bb6dd6), CONST64(0x329bdaf1c3415819), CONST64(0x577917e5b26ecba5),
385 CONST64(0x41f95cb3f2a50bae), CONST64(0x16804b5640cbc00b), CONST64(0x7f670cc2bd6bdab1), CONST64(0xdc59cc7ea295fb6e),
386 CONST64(0x61e1409ffea11fbe), CONST64(0xcb10e3c308f318eb), CONST64(0xe181302fceb14ffe), CONST64(0x100c0e1606020a08),
387 CONST64(0x2e925e6749ccdb17), CONST64(0x6ea2663f51c4f337), CONST64(0xe84e53cf271d6974), CONST64(0xa0786c9c3c144450),
388 CONST64(0x56b0730e58c3e82b), CONST64(0x3f57349aa563f291), CONST64(0x9ee63ced73da954f), CONST64(0xd2d38e35e75d3469),
389 CONST64(0xc2df8023e15f3e61), CONST64(0xaef22ed779dc8b57), CONST64(0xcf136e48877d94e9), CONST64(0x2694596c4acdde13),
390 CONST64(0xdf1f605e817f9ee1), CONST64(0xeac19b04ee5a2f75), CONST64(0x477519f3b46cc1ad), CONST64(0xdad5893ee45c316d),
391 CONST64(0xeb08ffef04f70cfb), CONST64(0x2dd4f2476a26be98), CONST64(0xab38c7b71cff24db), CONST64(0x3b54b9112aed7e93),
392 CONST64(0x134aa23625e86f87), CONST64(0x9c69f426ba9dd34e), CONST64(0x5f7f10eeb16fcea1), CONST64(0x04038d8b8f8e8c02),
393 CONST64(0xc8564fe32b197d64), CONST64(0x69e74794fda01aba), CONST64(0xd31aeade0df017e7), CONST64(0x3c1198ba8689971e),
394 CONST64(0x78222d69110f333c), CONST64(0x3812153109071b1c), CONST64(0x11c56afdecaf2986), CONST64(0x8b20db9b10fb30cb),
395 CONST64(0x4030385818082820), CONST64(0xa87e6b973f154154), CONST64(0x682e237f170d3934), CONST64(0x20181c2c0c041410),
396 CONST64(0x0806070b03010504), CONST64(0x074521abac64e98d), CONST64(0xb6f827ca7cdf845b), CONST64(0x97295f0d9a76b3c5),
397 CONST64(0xef0b72648b7980f9), CONST64(0xa6f429dc7add8e53), CONST64(0xf58eb3b2473dc9f4), CONST64(0xb074628a3a164e58),
398 CONST64(0xe582bda4413fc3fc), CONST64(0xa5b285fc5937ebdc), CONST64(0x4f731ef8b76dc4a9), CONST64(0xdd90a8954838d8e0),
399 CONST64(0xa1b10877d6b967de), CONST64(0xbf37442a9573a2d1), CONST64(0x1b4ca53d26e96a83), CONST64(0xb5be8bea5f35e1d4),
400 CONST64(0x92e3b66dff551c49), CONST64(0xaf3b4a3c9371a8d9), CONST64(0xff077c728d7b8af1), CONST64(0x140f839d898c860a),
401 CONST64(0xb73143219672a7d5), CONST64(0x34179fb18588921a), CONST64(0xe30ef8e407f609ff), CONST64(0x4dfcd6337e2a82a8),
402 CONST64(0xed84baaf423ec6f8), CONST64(0xcad98728e25e3b65), CONST64(0x25d2f54c6927bb9c), CONST64(0x0a89cfc0ca464305),
403 CONST64(0x60282474140c3c30), CONST64(0x0f4326a0af65ec89), CONST64(0x676d05dfb868d5bd), CONST64(0x2f5b3a8ca361f899),
404 CONST64(0x180a091d05030f0c), CONST64(0x46bc7d185ec1e223), CONST64(0x82efb87bf9571641), CONST64(0xfece189967d6a97f),
405 CONST64(0x86ec35f076d99a43), CONST64(0xfacd9512e858257d), CONST64(0x8eea32fb75d89f47), CONST64(0x17492fbdaa66e385),
406 CONST64(0xf6c81f9264d7ac7b), CONST64(0xcd9ca6834e3ad2e8), CONST64(0x0e8a424b45c8cf07), CONST64(0xfd88b4b9443cccf0),
407 CONST64(0x8326dc9013fa35cf), CONST64(0xc453c563a796f462), CONST64(0x51f552a5f4a701a6), CONST64(0xb477ef01b598c25a),
408 CONST64(0x3352be1a29ec7b97), CONST64(0xa9b70f7cd5b862da), CONST64(0x76a86f2254c7fc3b), CONST64(0x19c36df6efae2c82),
409 CONST64(0x6f6b02d4bb69d0b9), CONST64(0x62a7ecbfdd4b7a31), CONST64(0x31dd76d1e0ab3d96), CONST64(0x21d178c7e6a9379e),
410 CONST64(0x1f4f28b6a967e681), CONST64(0x503c364e1e0a2228), CONST64(0x028fc8cbc9474601), CONST64(0xc316e4c80bf21def),
411 CONST64(0xc1992c03c2b55bee), CONST64(0x0dccee6b6622aa88), CONST64(0x7b64814932e556b3), CONST64(0x235eb00c2fee719f),
412 CONST64(0x99a31d46dfbe7cc2), CONST64(0x45fad1387d2b87ac), CONST64(0x7c21a0e29e81bf3e), CONST64(0x906c7ea636125a48),
413 CONST64(0x6c2daef49883b536), CONST64(0xd85a41f52d1b776c), CONST64(0x70242a62120e3638), CONST64(0x05cae9606523af8c),
414 CONST64(0xfb04f1f902f506f3), CONST64(0x1283c6ddcf454c09), CONST64(0x15c6e7766321a584), CONST64(0x3e9e50714fced11f),
415 CONST64(0x72abe2a9db497039), CONST64(0x7de8c409742c9cb0), CONST64(0x9b2cd58d16f93ac3), CONST64(0x636e885437e659bf),
416 CONST64(0xd993251ec7b654e2), CONST64(0x5df0d825782888a0), CONST64(0xb872658139174b5c), CONST64(0x642ba9ff9b82b032),
417 CONST64(0xd05c46fe2e1a7268), CONST64(0x2c1d96ac808b9d16), CONST64(0xa33ec0bc1ffe21df), CONST64(0x241b91a7838a9812),
418 CONST64(0x48363f531b092d24), CONST64(0x068c454046c9ca03), CONST64(0x4c35b2d89487a126), CONST64(0x4ab9f798d24e6b25),
419 CONST64(0x5b7c9d653ee142a3), CONST64(0x6de4ca1f722e96b8), CONST64(0x7362864231e453b7), CONST64(0x537a9a6e3de047a7),
420 CONST64(0x0b40ab2b20eb608b), CONST64(0xf447d759ad90ea7a), CONST64(0x49ff5bb8f1a40eaa), CONST64(0xf0445ad2221e6678),
421 CONST64(0x5c39bcce9285ab2e), CONST64(0x275d3d87a060fd9d), CONST64(0x0000000000000000), CONST64(0x35defb5a6f25b194),
422 CONST64(0xf302f6f201f403f7), CONST64(0xdb1cedd50ef112e3), CONST64(0xd45fcb75a194fe6a), CONST64(0x583a31451d0b272c),
423 CONST64(0x6b688f5f34e75cbb), CONST64(0x8f2356109f75bcc9), CONST64(0x2b58b7072cef749b), CONST64(0xbdb88ce15c34e4d0),
424 CONST64(0x95a697c65331f5c4), CONST64(0xeec2168f61d4a377), CONST64(0xceda0aa36dd0b767), CONST64(0x4433b5d39786a422),
425 CONST64(0xd7196755827e9be5), CONST64(0x01c964ebeaad238e), CONST64(0xbb34c9a11afd2ed3), CONST64(0x55f6df2e7b298da4),
426 CONST64(0x9da090cd5030f0c0), CONST64(0xc59aa1884d3bd7ec), CONST64(0x8c65fa30bc9fd946), CONST64(0x932ad28615f83fc7),
427 CONST64(0x7eae682957c6f93f), CONST64(0x986a79ad35135f4c), CONST64(0x3014123a0a061e18), CONST64(0x281e1b270f051114),
428 CONST64(0x66a4613452c5f633), CONST64(0x886677bb33115544), CONST64(0x9f2f58069977b6c1), CONST64(0xc7156943847c91ed),
429 CONST64(0xf7017b798e7a8ff5), CONST64(0xe70d756f887885fd), CONST64(0xadb482f75a36eed8), CONST64(0xe04854c4241c6c70),
430 CONST64(0xd596af9e4b39dde4), CONST64(0xf2cb9219eb592079), CONST64(0xc05048e828187860), CONST64(0x8ae9bf70fa561345),
431 CONST64(0xf18d3e39c8b345f6), CONST64(0xe9873724cdb04afa), CONST64(0x3dd8fc516c24b490), CONST64(0x1dc0e07d6020a080),
432 CONST64(0xf98b3932cbb240f2), CONST64(0xe44bd94fab92e072), CONST64(0x71ed4e89f8a315b6), CONST64(0x4eba7a135dc0e727),
433 CONST64(0x1a85c1d6cc44490d), CONST64(0x37513391a662f795), CONST64(0x806070b030105040), CONST64(0xc99f2b08c1b45eea),
434 CONST64(0x543fbbc59184ae2a), CONST64(0x2297d4e7c5435211), CONST64(0xec4dde44a893e576), CONST64(0x5eb674055bc2ed2f),
435 CONST64(0x6aa1ebb4de4a7f35), CONST64(0x81a9145bdabd73ce), CONST64(0x0c058a808c8f8906), CONST64(0x75eec302772d99b4),
436 CONST64(0x89af1350d9bc76ca), CONST64(0x946ff32db99cd64a), CONST64(0x77610bc9be6adfb5), CONST64(0x3a9dddfac0405d1d),
437 CONST64(0x3698577a4ccfd41b), CONST64(0x79eb4982fba210b2), CONST64(0x7427a7e99d80ba3a), CONST64(0x42bff093d14f6e21),
438 CONST64(0xf8425dd9211f637c), CONST64(0x1e864c5d43cac50f), CONST64(0x39db71dae3aa3892), CONST64(0x2a91d3ecc6425715),
439 };
440
441 static const ulong64 T6[256] = {
442 CONST64(0x6a01bbb9d268bad3), CONST64(0x66b1e59a4d1954fc), CONST64(0x14cde265bc932f71), CONST64(0x1b512587cdb9749c),
443 CONST64(0x57a4f7a2510253f5), CONST64(0xbe03d0d66bb8d368), CONST64(0xb504d6de6fbdd26b), CONST64(0x85feb35229644dd7),
444 CONST64(0x4aadfdba5d0d50f0), CONST64(0xe063cf098a26ace9), CONST64(0x9684091c0e838d8a), CONST64(0x4d1aa591c679bfdc),
445 CONST64(0x374d3da7ddad7090), CONST64(0x5ca3f1aa550752f6), CONST64(0x17e17ba452c89ab3), CONST64(0x8ef9b55a2d614cd4),
446 CONST64(0x20ac46038f65ea23), CONST64(0x8411c4e673a6d562), CONST64(0x68c255cc66f197a4), CONST64(0xa80ddcc663b2d16e),
447 CONST64(0xd099aa85ccff3355), CONST64(0x41aafbb2590851f3), CONST64(0x0f9cc7e2712a5bed), CONST64(0xae55f359a204a6f7),
448 CONST64(0xc120febe5f81de7f), CONST64(0xa2e5ad7a3d7548d8), CONST64(0xcc7fd7299a32a8e5), CONST64(0x0ae871bc5ec799b6),
449 CONST64(0xe63be0964b90db70), CONST64(0xdb9eac8dc8fa3256), CONST64(0x152295d1e651b7c4), CONST64(0xaace32b3d72bfc19),
450 CONST64(0x7393704bab48e338), CONST64(0x3bfd638442dc9ebf), CONST64(0x52d041fc7eef91ae), CONST64(0x1ce67dac56cd9bb0),
451 CONST64(0x78947643af4de23b), CONST64(0x6106bdb1d66dbbd0), CONST64(0xf1da9b32195841c3), CONST64(0xe5177957a5cb6eb2),
452 CONST64(0xb35cf941ae0ba5f2), CONST64(0x564b80160bc0cb40), CONST64(0xc20c677fb1da6bbd), CONST64(0x7ecc59dc6efb95a2),
453 CONST64(0x9f40e161be1fa1fe), CONST64(0xc3e310cbeb18f308), CONST64(0x2f3081e1fe4fb1ce), CONST64(0x160e0c10080a0206),
454 CONST64(0x675e922e17dbcc49), CONST64(0x3f66a26e37f3c451), CONST64(0xcf534ee874691d27), CONST64(0x9c6c78a05044143c),
455 CONST64(0x0e73b0562be8c358), CONST64(0x9a34573f91f263a5), CONST64(0xed3ce69e4f95da73), CONST64(0x358ed3d269345de7),
456 CONST64(0x2380dfc2613e5fe1), CONST64(0xd72ef2ae578bdc79), CONST64(0x486e13cfe9947d87), CONST64(0x6c59942613decd4a),
457 CONST64(0x5e601fdfe19e7f81), CONST64(0x049bc1ea752f5aee), CONST64(0xf3197547adc16cb4), CONST64(0x3e89d5da6d315ce4),
458 CONST64(0xefff08ebfb0cf704), CONST64(0x47f2d42d98be266a), CONST64(0xb7c738abdb24ff1c), CONST64(0x11b9543b937eed2a),
459 CONST64(0x36a24a13876fe825), CONST64(0x26f4699c4ed39dba), CONST64(0xee107f5fa1ce6fb1), CONST64(0x8b8d0304028c8e8f),
460 CONST64(0xe34f56c8647d192b), CONST64(0x9447e769ba1aa0fd), CONST64(0xdeea1ad3e717f00d), CONST64(0xba98113c1e978986),
461 CONST64(0x692d22783c330f11), CONST64(0x311512381c1b0709), CONST64(0xfd6ac5118629afec), CONST64(0x9bdb208bcb30fb10),
462 CONST64(0x5838304020280818), CONST64(0x976b7ea85441153f), CONST64(0x7f232e6834390d17), CONST64(0x2c1c18201014040c),
463 CONST64(0x0b07060804050103), CONST64(0xab2145078de964ac), CONST64(0xca27f8b65b84df7c), CONST64(0x0d5f2997c5b3769a),
464 CONST64(0x64720beff980798b), CONST64(0xdc29f4a6538edd7a), CONST64(0xb2b38ef5f4c93d47), CONST64(0x8a6274b0584e163a),
465 CONST64(0xa4bd82e5fcc33f41), CONST64(0xfc85b2a5dceb3759), CONST64(0xf81e734fa9c46db7), CONST64(0x95a890dde0d83848),
466 CONST64(0x7708b1a1de67b9d6), CONST64(0x2a4437bfd1a27395), CONST64(0x3da54c1b836ae926), CONST64(0xea8bbeb5d4e1355f),
467 CONST64(0x6db6e392491c55ff), CONST64(0x3c4a3bafd9a87193), CONST64(0x727c07fff18a7b8d), CONST64(0x9d830f140a868c89),
468 CONST64(0x214331b7d5a77296), CONST64(0xb19f17341a928885), CONST64(0xe4f80ee3ff09f607), CONST64(0x33d6fc4da8822a7e),
469 CONST64(0xafba84edf8c63e42), CONST64(0x2887d9ca653b5ee2), CONST64(0x4cf5d2259cbb2769), CONST64(0xc0cf890a054346ca),
470 CONST64(0x74242860303c0c14), CONST64(0xa026430f89ec65af), CONST64(0xdf056d67bdd568b8), CONST64(0x8c3a5b2f99f861a3),
471 CONST64(0x1d090a180c0f0305), CONST64(0x187dbc4623e2c15e), CONST64(0x7bb8ef82411657f9), CONST64(0x9918cefe7fa9d667),
472 CONST64(0xf035ec86439ad976), CONST64(0x1295cdfa7d2558e8), CONST64(0xfb32ea8e479fd875), CONST64(0xbd2f491785e366aa),
473 CONST64(0x921fc8f67bacd764), CONST64(0x83a69ccde8d23a4e), CONST64(0x4b428a0e07cfc845), CONST64(0xb9b488fdf0cc3c44),
474 CONST64(0x90dc2683cf35fa13), CONST64(0x63c553c462f496a7), CONST64(0xa552f551a601a7f4), CONST64(0x01ef77b45ac298b5),
475 CONST64(0x1abe5233977bec29), CONST64(0x7c0fb7a9da62b8d5), CONST64(0x226fa8763bfcc754), CONST64(0xf66dc319822caeef),
476 CONST64(0xd4026b6fb9d069bb), CONST64(0xbfeca762317a4bdd), CONST64(0xd176dd31963dabe0), CONST64(0xc778d1219e37a9e6),
477 CONST64(0xb6284f1f81e667a9), CONST64(0x4e363c5028220a1e), CONST64(0xcbc88f02014647c9), CONST64(0xc8e416c3ef1df20b),
478 CONST64(0x032c99c1ee5bb5c2), CONST64(0x6beecc0d88aa2266), CONST64(0x4981647bb356e532), CONST64(0x0cb05e239f71ee2f),
479 CONST64(0x461da399c27cbedf), CONST64(0x38d1fa45ac872b7d), CONST64(0xe2a0217c3ebf819e), CONST64(0xa67e6c90485a1236),
480 CONST64(0xf4ae2d6c36b58398), CONST64(0xf5415ad86c771b2d), CONST64(0x622a247038360e12), CONST64(0x60e9ca058caf2365),
481 CONST64(0xf9f104fbf306f502), CONST64(0xddc68312094c45cf), CONST64(0x76e7c61584a52163), CONST64(0x71509e3e1fd1ce4f),
482 CONST64(0xa9e2ab72397049db), CONST64(0x09c4e87db09c2c74), CONST64(0x8dd52c9bc33af916), CONST64(0x54886e63bf59e637),
483 CONST64(0x1e2593d9e254b6c7), CONST64(0x25d8f05da0882878), CONST64(0x816572b85c4b1739), CONST64(0xffa92b6432b0829b),
484 CONST64(0xfe465cd068721a2e), CONST64(0xac961d2c169d8b80), CONST64(0xbcc03ea3df21fe1f), CONST64(0xa7911b2412988a83),
485 CONST64(0x533f3648242d091b), CONST64(0x40458c0603cac946), CONST64(0xd8b2354c26a18794), CONST64(0x98f7b94a256b4ed2),
486 CONST64(0x659d7c5ba342e13e), CONST64(0x1fcae46db8962e72), CONST64(0x42866273b753e431), CONST64(0x6e9a7a53a747e03d),
487 CONST64(0x2bab400b8b60eb20), CONST64(0x59d747f47aea90ad), CONST64(0xb85bff49aa0ea4f1), CONST64(0xd25a44f078661e22),
488 CONST64(0xcebc395c2eab8592), CONST64(0x873d5d279dfd60a0), CONST64(0x0000000000000000), CONST64(0x5afbde3594b1256f),
489 CONST64(0xf2f602f3f703f401), CONST64(0xd5ed1cdbe312f10e), CONST64(0x75cb5fd46afe94a1), CONST64(0x45313a582c270b1d),
490 CONST64(0x5f8f686bbb5ce734), CONST64(0x1056238fc9bc759f), CONST64(0x07b7582b9b74ef2c), CONST64(0xe18cb8bdd0e4345c),
491 CONST64(0xc697a695c4f53153), CONST64(0x8f16c2ee77a3d461), CONST64(0xa30adace67b7d06d), CONST64(0xd3b5334422a48697),
492 CONST64(0x556719d7e59b7e82), CONST64(0xeb64c9018e23adea), CONST64(0xa1c934bbd32efd1a), CONST64(0x2edff655a48d297b),
493 CONST64(0xcd90a09dc0f03050), CONST64(0x88a19ac5ecd73b4d), CONST64(0x30fa658c46d99fbc), CONST64(0x86d22a93c73ff815),
494 CONST64(0x2968ae7e3ff9c657), CONST64(0xad796a984c5f1335), CONST64(0x3a121430181e060a), CONST64(0x271b1e281411050f),
495 CONST64(0x3461a46633f6c552), CONST64(0xbb77668844551133), CONST64(0x06582f9fc1b67799), CONST64(0x436915c7ed917c84),
496 CONST64(0x797b01f7f58f7a8e), CONST64(0x6f750de7fd857888), CONST64(0xf782b4add8ee365a), CONST64(0xc45448e0706c1c24),
497 CONST64(0x9eaf96d5e4dd394b), CONST64(0x1992cbf2792059eb), CONST64(0xe84850c060781828), CONST64(0x70bfe98a451356fa),
498 CONST64(0x393e8df1f645b3c8), CONST64(0x243787e9fa4ab0cd), CONST64(0x51fcd83d90b4246c), CONST64(0x7de0c01d80a02060),
499 CONST64(0x32398bf9f240b2cb), CONST64(0x4fd94be472e092ab), CONST64(0x894eed71b615a3f8), CONST64(0x137aba4e27e7c05d),
500 CONST64(0xd6c1851a0d4944cc), CONST64(0x9133513795f762a6), CONST64(0xb070608040501030), CONST64(0x082b9fc9ea5eb4c1),
501 CONST64(0xc5bb3f542aae8491), CONST64(0xe7d49722115243c5), CONST64(0x44de4dec76e593a8), CONST64(0x0574b65e2fedc25b),
502 CONST64(0xb4eba16a357f4ade), CONST64(0x5b14a981ce73bdda), CONST64(0x808a050c06898f8c), CONST64(0x02c3ee75b4992d77),
503 CONST64(0x5013af89ca76bcd9), CONST64(0x2df36f944ad69cb9), CONST64(0xc90b6177b5df6abe), CONST64(0xfadd9d3a1d5d40c0),
504 CONST64(0x7a5798361bd4cf4c), CONST64(0x8249eb79b210a2fb), CONST64(0xe9a727743aba809d), CONST64(0x93f0bf42216e4fd1),
505 CONST64(0xd95d42f87c631f21), CONST64(0x5d4c861e0fc5ca43), CONST64(0xda71db399238aae3), CONST64(0xecd3912a155742c6),
506 };
507
508 static const ulong64 T7[256] = {
509 CONST64(0x016ab9bb68d2d3ba), CONST64(0xb1669ae5194dfc54), CONST64(0xcd1465e293bc712f), CONST64(0x511b8725b9cd9c74),
510 CONST64(0xa457a2f70251f553), CONST64(0x03bed6d0b86b68d3), CONST64(0x04b5ded6bd6f6bd2), CONST64(0xfe8552b36429d74d),
511 CONST64(0xad4abafd0d5df050), CONST64(0x63e009cf268ae9ac), CONST64(0x84961c09830e8a8d), CONST64(0x1a4d91a579c6dcbf),
512 CONST64(0x4d37a73daddd9070), CONST64(0xa35caaf10755f652), CONST64(0xe117a47bc852b39a), CONST64(0xf98e5ab5612dd44c),
513 CONST64(0xac200346658f23ea), CONST64(0x1184e6c4a67362d5), CONST64(0xc268cc55f166a497), CONST64(0x0da8c6dcb2636ed1),
514 CONST64(0x99d085aaffcc5533), CONST64(0xaa41b2fb0859f351), CONST64(0x9c0fe2c72a71ed5b), CONST64(0x55ae59f304a2f7a6),
515 CONST64(0x20c1befe815f7fde), CONST64(0xe5a27aad753dd848), CONST64(0x7fcc29d7329ae5a8), CONST64(0xe80abc71c75eb699),
516 CONST64(0x3be696e0904b70db), CONST64(0x9edb8dacfac85632), CONST64(0x2215d19551e6c4b7), CONST64(0xceaab3322bd719fc),
517 CONST64(0x93734b7048ab38e3), CONST64(0xfd3b8463dc42bf9e), CONST64(0xd052fc41ef7eae91), CONST64(0xe61cac7dcd56b09b),
518 CONST64(0x947843764daf3be2), CONST64(0x0661b1bd6dd6d0bb), CONST64(0xdaf1329b5819c341), CONST64(0x17e55779cba5b26e),
519 CONST64(0x5cb341f90baef2a5), CONST64(0x4b561680c00b40cb), CONST64(0x0cc27f67dab1bd6b), CONST64(0xcc7edc59fb6ea295),
520 CONST64(0x409f61e11fbefea1), CONST64(0xe3c3cb1018eb08f3), CONST64(0x302fe1814ffeceb1), CONST64(0x0e16100c0a080602),
521 CONST64(0x5e672e92db1749cc), CONST64(0x663f6ea2f33751c4), CONST64(0x53cfe84e6974271d), CONST64(0x6c9ca07844503c14),
522 CONST64(0x730e56b0e82b58c3), CONST64(0x349a3f57f291a563), CONST64(0x3ced9ee6954f73da), CONST64(0x8e35d2d33469e75d),
523 CONST64(0x8023c2df3e61e15f), CONST64(0x2ed7aef28b5779dc), CONST64(0x6e48cf1394e9877d), CONST64(0x596c2694de134acd),
524 CONST64(0x605edf1f9ee1817f), CONST64(0x9b04eac12f75ee5a), CONST64(0x19f34775c1adb46c), CONST64(0x893edad5316de45c),
525 CONST64(0xffefeb080cfb04f7), CONST64(0xf2472dd4be986a26), CONST64(0xc7b7ab3824db1cff), CONST64(0xb9113b547e932aed),
526 CONST64(0xa236134a6f8725e8), CONST64(0xf4269c69d34eba9d), CONST64(0x10ee5f7fcea1b16f), CONST64(0x8d8b04038c028f8e),
527 CONST64(0x4fe3c8567d642b19), CONST64(0x479469e71abafda0), CONST64(0xeaded31a17e70df0), CONST64(0x98ba3c11971e8689),
528 CONST64(0x2d697822333c110f), CONST64(0x153138121b1c0907), CONST64(0x6afd11c52986ecaf), CONST64(0xdb9b8b2030cb10fb),
529 CONST64(0x3858403028201808), CONST64(0x6b97a87e41543f15), CONST64(0x237f682e3934170d), CONST64(0x1c2c201814100c04),
530 CONST64(0x070b080605040301), CONST64(0x21ab0745e98dac64), CONST64(0x27cab6f8845b7cdf), CONST64(0x5f0d9729b3c59a76),
531 CONST64(0x7264ef0b80f98b79), CONST64(0x29dca6f48e537add), CONST64(0xb3b2f58ec9f4473d), CONST64(0x628ab0744e583a16),
532 CONST64(0xbda4e582c3fc413f), CONST64(0x85fca5b2ebdc5937), CONST64(0x1ef84f73c4a9b76d), CONST64(0xa895dd90d8e04838),
533 CONST64(0x0877a1b167ded6b9), CONST64(0x442abf37a2d19573), CONST64(0xa53d1b4c6a8326e9), CONST64(0x8beab5bee1d45f35),
534 CONST64(0xb66d92e31c49ff55), CONST64(0x4a3caf3ba8d99371), CONST64(0x7c72ff078af18d7b), CONST64(0x839d140f860a898c),
535 CONST64(0x4321b731a7d59672), CONST64(0x9fb13417921a8588), CONST64(0xf8e4e30e09ff07f6), CONST64(0xd6334dfc82a87e2a),
536 CONST64(0xbaafed84c6f8423e), CONST64(0x8728cad93b65e25e), CONST64(0xf54c25d2bb9c6927), CONST64(0xcfc00a894305ca46),
537 CONST64(0x247460283c30140c), CONST64(0x26a00f43ec89af65), CONST64(0x05df676dd5bdb868), CONST64(0x3a8c2f5bf899a361),
538 CONST64(0x091d180a0f0c0503), CONST64(0x7d1846bce2235ec1), CONST64(0xb87b82ef1641f957), CONST64(0x1899fecea97f67d6),
539 CONST64(0x35f086ec9a4376d9), CONST64(0x9512facd257de858), CONST64(0x32fb8eea9f4775d8), CONST64(0x2fbd1749e385aa66),
540 CONST64(0x1f92f6c8ac7b64d7), CONST64(0xa683cd9cd2e84e3a), CONST64(0x424b0e8acf0745c8), CONST64(0xb4b9fd88ccf0443c),
541 CONST64(0xdc90832635cf13fa), CONST64(0xc563c453f462a796), CONST64(0x52a551f501a6f4a7), CONST64(0xef01b477c25ab598),
542 CONST64(0xbe1a33527b9729ec), CONST64(0x0f7ca9b762dad5b8), CONST64(0x6f2276a8fc3b54c7), CONST64(0x6df619c32c82efae),
543 CONST64(0x02d46f6bd0b9bb69), CONST64(0xecbf62a77a31dd4b), CONST64(0x76d131dd3d96e0ab), CONST64(0x78c721d1379ee6a9),
544 CONST64(0x28b61f4fe681a967), CONST64(0x364e503c22281e0a), CONST64(0xc8cb028f4601c947), CONST64(0xe4c8c3161def0bf2),
545 CONST64(0x2c03c1995beec2b5), CONST64(0xee6b0dccaa886622), CONST64(0x81497b6456b332e5), CONST64(0xb00c235e719f2fee),
546 CONST64(0x1d4699a37cc2dfbe), CONST64(0xd13845fa87ac7d2b), CONST64(0xa0e27c21bf3e9e81), CONST64(0x7ea6906c5a483612),
547 CONST64(0xaef46c2db5369883), CONST64(0x41f5d85a776c2d1b), CONST64(0x2a6270243638120e), CONST64(0xe96005caaf8c6523),
548 CONST64(0xf1f9fb0406f302f5), CONST64(0xc6dd12834c09cf45), CONST64(0xe77615c6a5846321), CONST64(0x50713e9ed11f4fce),
549 CONST64(0xe2a972ab7039db49), CONST64(0xc4097de89cb0742c), CONST64(0xd58d9b2c3ac316f9), CONST64(0x8854636e59bf37e6),
550 CONST64(0x251ed99354e2c7b6), CONST64(0xd8255df088a07828), CONST64(0x6581b8724b5c3917), CONST64(0xa9ff642bb0329b82),
551 CONST64(0x46fed05c72682e1a), CONST64(0x96ac2c1d9d16808b), CONST64(0xc0bca33e21df1ffe), CONST64(0x91a7241b9812838a),
552 CONST64(0x3f5348362d241b09), CONST64(0x4540068cca0346c9), CONST64(0xb2d84c35a1269487), CONST64(0xf7984ab96b25d24e),
553 CONST64(0x9d655b7c42a33ee1), CONST64(0xca1f6de496b8722e), CONST64(0x8642736253b731e4), CONST64(0x9a6e537a47a73de0),
554 CONST64(0xab2b0b40608b20eb), CONST64(0xd759f447ea7aad90), CONST64(0x5bb849ff0eaaf1a4), CONST64(0x5ad2f0446678221e),
555 CONST64(0xbcce5c39ab2e9285), CONST64(0x3d87275dfd9da060), CONST64(0x0000000000000000), CONST64(0xfb5a35deb1946f25),
556 CONST64(0xf6f2f30203f701f4), CONST64(0xedd5db1c12e30ef1), CONST64(0xcb75d45ffe6aa194), CONST64(0x3145583a272c1d0b),
557 CONST64(0x8f5f6b685cbb34e7), CONST64(0x56108f23bcc99f75), CONST64(0xb7072b58749b2cef), CONST64(0x8ce1bdb8e4d05c34),
558 CONST64(0x97c695a6f5c45331), CONST64(0x168feec2a37761d4), CONST64(0x0aa3cedab7676dd0), CONST64(0xb5d34433a4229786),
559 CONST64(0x6755d7199be5827e), CONST64(0x64eb01c9238eeaad), CONST64(0xc9a1bb342ed31afd), CONST64(0xdf2e55f68da47b29),
560 CONST64(0x90cd9da0f0c05030), CONST64(0xa188c59ad7ec4d3b), CONST64(0xfa308c65d946bc9f), CONST64(0xd286932a3fc715f8),
561 CONST64(0x68297eaef93f57c6), CONST64(0x79ad986a5f4c3513), CONST64(0x123a30141e180a06), CONST64(0x1b27281e11140f05),
562 CONST64(0x613466a4f63352c5), CONST64(0x77bb886655443311), CONST64(0x58069f2fb6c19977), CONST64(0x6943c71591ed847c),
563 CONST64(0x7b79f7018ff58e7a), CONST64(0x756fe70d85fd8878), CONST64(0x82f7adb4eed85a36), CONST64(0x54c4e0486c70241c),
564 CONST64(0xaf9ed596dde44b39), CONST64(0x9219f2cb2079eb59), CONST64(0x48e8c05078602818), CONST64(0xbf708ae91345fa56),
565 CONST64(0x3e39f18d45f6c8b3), CONST64(0x3724e9874afacdb0), CONST64(0xfc513dd8b4906c24), CONST64(0xe07d1dc0a0806020),
566 CONST64(0x3932f98b40f2cbb2), CONST64(0xd94fe44be072ab92), CONST64(0x4e8971ed15b6f8a3), CONST64(0x7a134ebae7275dc0),
567 CONST64(0xc1d61a85490dcc44), CONST64(0x33913751f795a662), CONST64(0x70b0806050403010), CONST64(0x2b08c99f5eeac1b4),
568 CONST64(0xbbc5543fae2a9184), CONST64(0xd4e722975211c543), CONST64(0xde44ec4de576a893), CONST64(0x74055eb6ed2f5bc2),
569 CONST64(0xebb46aa17f35de4a), CONST64(0x145b81a973cedabd), CONST64(0x8a800c0589068c8f), CONST64(0xc30275ee99b4772d),
570 CONST64(0x135089af76cad9bc), CONST64(0xf32d946fd64ab99c), CONST64(0x0bc97761dfb5be6a), CONST64(0xddfa3a9d5d1dc040),
571 CONST64(0x577a3698d41b4ccf), CONST64(0x498279eb10b2fba2), CONST64(0xa7e97427ba3a9d80), CONST64(0xf09342bf6e21d14f),
572 CONST64(0x5dd9f842637c211f), CONST64(0x4c5d1e86c50f43ca), CONST64(0x71da39db3892e3aa), CONST64(0xd3ec2a915715c642),
573 };
574
575 static const ulong64 c[R + 1] = {
576 CONST64(0xba542f7453d3d24d),
577 CONST64(0x50ac8dbf70529a4c),
578 CONST64(0xead597d133515ba6),
579 CONST64(0xde48a899db32b7fc),
580 CONST64(0xe39e919be2bb416e),
581 CONST64(0xa5cb6b95a1f3b102),
582 CONST64(0xccc41d14c363da5d),
583 CONST64(0x5fdc7dcd7f5a6c5c),
584 CONST64(0xf726ffede89d6f8e),
585 };
586
587 /**
588 Initialize the Khazad block cipher
589 @param key The symmetric key you wish to pass
590 @param keylen The key length in bytes
591 @param num_rounds The number of rounds desired (0 for default)
592 @param skey The key in as scheduled by this function.
593 @return CRYPT_OK if successful
594 */
595 int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
596 {
597 int r;
598 const ulong64 *S;
599 ulong64 K2, K1;
600
601 LTC_ARGCHK(key != NULL);
602 LTC_ARGCHK(skey != NULL);
603 if (keylen != 16) {
604 return CRYPT_INVALID_KEYSIZE;
605 }
606 if (num_rounds != 8 && num_rounds != 0) {
607 return CRYPT_INVALID_ROUNDS;
608 }
609
610 /* use 7th table */
611 S = T7;
612
613 /*
614 * map unsigned char array cipher key to initial key state (mu):
615 */
616 K2 =
617 ((ulong64)key[ 0] << 56) ^
618 ((ulong64)key[ 1] << 48) ^
619 ((ulong64)key[ 2] << 40) ^
620 ((ulong64)key[ 3] << 32) ^
621 ((ulong64)key[ 4] << 24) ^
622 ((ulong64)key[ 5] << 16) ^
623 ((ulong64)key[ 6] << 8) ^
624 ((ulong64)key[ 7] );
625 K1 =
626 ((ulong64)key[ 8] << 56) ^
627 ((ulong64)key[ 9] << 48) ^
628 ((ulong64)key[10] << 40) ^
629 ((ulong64)key[11] << 32) ^
630 ((ulong64)key[12] << 24) ^
631 ((ulong64)key[13] << 16) ^
632 ((ulong64)key[14] << 8) ^
633 ((ulong64)key[15] );
634
635 /*
636 * compute the round keys:
637 */
638 for (r = 0; r <= R; r++) {
639 /*
640 * K[r] = rho(c[r], K1) ^ K2;
641 */
642 skey->khazad.roundKeyEnc[r] =
643 T0[(int)(K1 >> 56) ] ^
644 T1[(int)(K1 >> 48) & 0xff] ^
645 T2[(int)(K1 >> 40) & 0xff] ^
646 T3[(int)(K1 >> 32) & 0xff] ^
647 T4[(int)(K1 >> 24) & 0xff] ^
648 T5[(int)(K1 >> 16) & 0xff] ^
649 T6[(int)(K1 >> 8) & 0xff] ^
650 T7[(int)(K1 ) & 0xff] ^
651 c[r] ^ K2;
652 K2 = K1; K1 = skey->khazad.roundKeyEnc[r];
653 }
654 /*
655 * compute the inverse key schedule:
656 * K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r})
657 */
658 skey->khazad.roundKeyDec[0] = skey->khazad.roundKeyEnc[R];
659 for (r = 1; r < R; r++) {
660 K1 = skey->khazad.roundKeyEnc[R - r];
661 skey->khazad.roundKeyDec[r] =
662 T0[(int)S[(int)(K1 >> 56) ] & 0xff] ^
663 T1[(int)S[(int)(K1 >> 48) & 0xff] & 0xff] ^
664 T2[(int)S[(int)(K1 >> 40) & 0xff] & 0xff] ^
665 T3[(int)S[(int)(K1 >> 32) & 0xff] & 0xff] ^
666 T4[(int)S[(int)(K1 >> 24) & 0xff] & 0xff] ^
667 T5[(int)S[(int)(K1 >> 16) & 0xff] & 0xff] ^
668 T6[(int)S[(int)(K1 >> 8) & 0xff] & 0xff] ^
669 T7[(int)S[(int)(K1 ) & 0xff] & 0xff];
670 }
671 skey->khazad.roundKeyDec[R] = skey->khazad.roundKeyEnc[0];
672
673 return CRYPT_OK;
674 }
675
676 static void khazad_crypt(const unsigned char *plaintext, unsigned char *ciphertext,
677 const ulong64 *roundKey) {
678 int r;
679 ulong64 state;
680 /*
681 * map plaintext block to cipher state (mu)
682 * and add initial round key (sigma[K^0]):
683 */
684 state =
685 ((ulong64)plaintext[0] << 56) ^
686 ((ulong64)plaintext[1] << 48) ^
687 ((ulong64)plaintext[2] << 40) ^
688 ((ulong64)plaintext[3] << 32) ^
689 ((ulong64)plaintext[4] << 24) ^
690 ((ulong64)plaintext[5] << 16) ^
691 ((ulong64)plaintext[6] << 8) ^
692 ((ulong64)plaintext[7] ) ^
693 roundKey[0];
694
695 /*
696 * R - 1 full rounds:
697 */
698 for (r = 1; r < R; r++) {
699 state =
700 T0[(int)(state >> 56) ] ^
701 T1[(int)(state >> 48) & 0xff] ^
702 T2[(int)(state >> 40) & 0xff] ^
703 T3[(int)(state >> 32) & 0xff] ^
704 T4[(int)(state >> 24) & 0xff] ^
705 T5[(int)(state >> 16) & 0xff] ^
706 T6[(int)(state >> 8) & 0xff] ^
707 T7[(int)(state ) & 0xff] ^
708 roundKey[r];
709 }
710
711 /*
712 * last round:
713 */
714 state =
715 (T0[(int)(state >> 56) ] & CONST64(0xff00000000000000)) ^
716 (T1[(int)(state >> 48) & 0xff] & CONST64(0x00ff000000000000)) ^
717 (T2[(int)(state >> 40) & 0xff] & CONST64(0x0000ff0000000000)) ^
718 (T3[(int)(state >> 32) & 0xff] & CONST64(0x000000ff00000000)) ^
719 (T4[(int)(state >> 24) & 0xff] & CONST64(0x00000000ff000000)) ^
720 (T5[(int)(state >> 16) & 0xff] & CONST64(0x0000000000ff0000)) ^
721 (T6[(int)(state >> 8) & 0xff] & CONST64(0x000000000000ff00)) ^
722 (T7[(int)(state ) & 0xff] & CONST64(0x00000000000000ff)) ^
723 roundKey[R];
724
725 /*
726 * map cipher state to ciphertext block (mu^{-1}):
727 */
728 ciphertext[0] = (unsigned char)(state >> 56);
729 ciphertext[1] = (unsigned char)(state >> 48);
730 ciphertext[2] = (unsigned char)(state >> 40);
731 ciphertext[3] = (unsigned char)(state >> 32);
732 ciphertext[4] = (unsigned char)(state >> 24);
733 ciphertext[5] = (unsigned char)(state >> 16);
734 ciphertext[6] = (unsigned char)(state >> 8);
735 ciphertext[7] = (unsigned char)(state );
736 }
737
738 /**
739 Encrypts a block of text with Khazad
740 @param pt The input plaintext (8 bytes)
741 @param ct The output ciphertext (8 bytes)
742 @param skey The key as scheduled
743 @return CRYPT_OK if successful
744 */
745 int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
746 {
747 LTC_ARGCHK(pt != NULL);
748 LTC_ARGCHK(ct != NULL);
749 LTC_ARGCHK(skey != NULL);
750 khazad_crypt(pt, ct, skey->khazad.roundKeyEnc);
751 return CRYPT_OK;
752 }
753
754 /**
755 Decrypts a block of text with Khazad
756 @param ct The input ciphertext (8 bytes)
757 @param pt The output plaintext (8 bytes)
758 @param skey The key as scheduled
759 @return CRYPT_OK if successful
760 */
761 int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
762 {
763 LTC_ARGCHK(pt != NULL);
764 LTC_ARGCHK(ct != NULL);
765 LTC_ARGCHK(skey != NULL);
766 khazad_crypt(ct, pt, skey->khazad.roundKeyDec);
767 return CRYPT_OK;
768 }
769
770 /**
771 Performs a self-test of the Khazad block cipher
772 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
773 */
774 int khazad_test(void)
775 {
776 #ifndef LTC_TEST
777 return CRYPT_NOP;
778 #else
779 static const struct test {
780 unsigned char pt[8], ct[8], key[16];
781 } tests[] = {
782 {
783 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
784 { 0x49, 0xA4, 0xCE, 0x32, 0xAC, 0x19, 0x0E, 0x3F },
785 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
787 }, {
788 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
789 { 0x64, 0x5D, 0x77, 0x3E, 0x40, 0xAB, 0xDD, 0x53 },
790 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
792 }, {
793 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
794 { 0x9E, 0x39, 0x98, 0x64, 0xF7, 0x8E, 0xCA, 0x02 },
795 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
797 }, {
798 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
799 { 0xA9, 0xDF, 0x3D, 0x2C, 0x64, 0xD3, 0xEA, 0x28 },
800 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
802 }
803 };
804 int x, y;
805 unsigned char buf[2][8];
806 symmetric_key skey;
807
808 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
809 khazad_setup(tests[x].key, 16, 0, &skey);
810 khazad_ecb_encrypt(tests[x].pt, buf[0], &skey);
811 khazad_ecb_decrypt(buf[0], buf[1], &skey);
812 if (XMEMCMP(buf[0], tests[x].ct, 8) || XMEMCMP(buf[1], tests[x].pt, 8)) {
813 return CRYPT_FAIL_TESTVECTOR;
814 }
815
816 for (y = 0; y < 1000; y++) khazad_ecb_encrypt(buf[0], buf[0], &skey);
817 for (y = 0; y < 1000; y++) khazad_ecb_decrypt(buf[0], buf[0], &skey);
818 if (XMEMCMP(buf[0], tests[x].ct, 8)) {
819 return CRYPT_FAIL_TESTVECTOR;
820 }
821
822 }
823 return CRYPT_OK;
824 #endif
825 }
826
827 /** Terminate the context
828 @param skey The scheduled key
829 */
830 void khazad_done(symmetric_key *skey)
831 {
832 }
833
834 /**
835 Gets suitable key size
836 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
837 @return CRYPT_OK if the input key size is acceptable.
838 */
839 int khazad_keysize(int *keysize)
840 {
841 LTC_ARGCHK(keysize != NULL);
842 if (*keysize >= 16) {
843 *keysize = 16;
844 return CRYPT_OK;
845 } else {
846 return CRYPT_INVALID_KEYSIZE;
847 }
848 }
849
850 #endif
851
852 /* $Source$ */
853 /* $Revision$ */
854 /* $Date$ */
+0
-391
libtom-src/ciphers/kseed.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file kseed.c
13 seed implementation of SEED derived from RFC4269
14 Tom St Denis
15 */
16
17 #include "tomcrypt.h"
18
19 #ifdef LTC_KSEED
20
21 const struct ltc_cipher_descriptor kseed_desc = {
22 "seed",
23 20,
24 16, 16, 16, 16,
25 &kseed_setup,
26 &kseed_ecb_encrypt,
27 &kseed_ecb_decrypt,
28 &kseed_test,
29 &kseed_done,
30 &kseed_keysize,
31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
32 };
33
34 static const ulong32 SS0[256] = {
35 0x2989A1A8UL,0x05858184UL,0x16C6D2D4UL,0x13C3D3D0UL,0x14445054UL,0x1D0D111CUL,0x2C8CA0ACUL,0x25052124UL,
36 0x1D4D515CUL,0x03434340UL,0x18081018UL,0x1E0E121CUL,0x11415150UL,0x3CCCF0FCUL,0x0ACAC2C8UL,0x23436360UL,
37 0x28082028UL,0x04444044UL,0x20002020UL,0x1D8D919CUL,0x20C0E0E0UL,0x22C2E2E0UL,0x08C8C0C8UL,0x17071314UL,
38 0x2585A1A4UL,0x0F8F838CUL,0x03030300UL,0x3B4B7378UL,0x3B8BB3B8UL,0x13031310UL,0x12C2D2D0UL,0x2ECEE2ECUL,
39 0x30407070UL,0x0C8C808CUL,0x3F0F333CUL,0x2888A0A8UL,0x32023230UL,0x1DCDD1DCUL,0x36C6F2F4UL,0x34447074UL,
40 0x2CCCE0ECUL,0x15859194UL,0x0B0B0308UL,0x17475354UL,0x1C4C505CUL,0x1B4B5358UL,0x3D8DB1BCUL,0x01010100UL,
41 0x24042024UL,0x1C0C101CUL,0x33437370UL,0x18889098UL,0x10001010UL,0x0CCCC0CCUL,0x32C2F2F0UL,0x19C9D1D8UL,
42 0x2C0C202CUL,0x27C7E3E4UL,0x32427270UL,0x03838380UL,0x1B8B9398UL,0x11C1D1D0UL,0x06868284UL,0x09C9C1C8UL,
43 0x20406060UL,0x10405050UL,0x2383A3A0UL,0x2BCBE3E8UL,0x0D0D010CUL,0x3686B2B4UL,0x1E8E929CUL,0x0F4F434CUL,
44 0x3787B3B4UL,0x1A4A5258UL,0x06C6C2C4UL,0x38487078UL,0x2686A2A4UL,0x12021210UL,0x2F8FA3ACUL,0x15C5D1D4UL,
45 0x21416160UL,0x03C3C3C0UL,0x3484B0B4UL,0x01414140UL,0x12425250UL,0x3D4D717CUL,0x0D8D818CUL,0x08080008UL,
46 0x1F0F131CUL,0x19899198UL,0x00000000UL,0x19091118UL,0x04040004UL,0x13435350UL,0x37C7F3F4UL,0x21C1E1E0UL,
47 0x3DCDF1FCUL,0x36467274UL,0x2F0F232CUL,0x27072324UL,0x3080B0B0UL,0x0B8B8388UL,0x0E0E020CUL,0x2B8BA3A8UL,
48 0x2282A2A0UL,0x2E4E626CUL,0x13839390UL,0x0D4D414CUL,0x29496168UL,0x3C4C707CUL,0x09090108UL,0x0A0A0208UL,
49 0x3F8FB3BCUL,0x2FCFE3ECUL,0x33C3F3F0UL,0x05C5C1C4UL,0x07878384UL,0x14041014UL,0x3ECEF2FCUL,0x24446064UL,
50 0x1ECED2DCUL,0x2E0E222CUL,0x0B4B4348UL,0x1A0A1218UL,0x06060204UL,0x21012120UL,0x2B4B6368UL,0x26466264UL,
51 0x02020200UL,0x35C5F1F4UL,0x12829290UL,0x0A8A8288UL,0x0C0C000CUL,0x3383B3B0UL,0x3E4E727CUL,0x10C0D0D0UL,
52 0x3A4A7278UL,0x07474344UL,0x16869294UL,0x25C5E1E4UL,0x26062224UL,0x00808080UL,0x2D8DA1ACUL,0x1FCFD3DCUL,
53 0x2181A1A0UL,0x30003030UL,0x37073334UL,0x2E8EA2ACUL,0x36063234UL,0x15051114UL,0x22022220UL,0x38083038UL,
54 0x34C4F0F4UL,0x2787A3A4UL,0x05454144UL,0x0C4C404CUL,0x01818180UL,0x29C9E1E8UL,0x04848084UL,0x17879394UL,
55 0x35053134UL,0x0BCBC3C8UL,0x0ECEC2CCUL,0x3C0C303CUL,0x31417170UL,0x11011110UL,0x07C7C3C4UL,0x09898188UL,
56 0x35457174UL,0x3BCBF3F8UL,0x1ACAD2D8UL,0x38C8F0F8UL,0x14849094UL,0x19495158UL,0x02828280UL,0x04C4C0C4UL,
57 0x3FCFF3FCUL,0x09494148UL,0x39093138UL,0x27476364UL,0x00C0C0C0UL,0x0FCFC3CCUL,0x17C7D3D4UL,0x3888B0B8UL,
58 0x0F0F030CUL,0x0E8E828CUL,0x02424240UL,0x23032320UL,0x11819190UL,0x2C4C606CUL,0x1BCBD3D8UL,0x2484A0A4UL,
59 0x34043034UL,0x31C1F1F0UL,0x08484048UL,0x02C2C2C0UL,0x2F4F636CUL,0x3D0D313CUL,0x2D0D212CUL,0x00404040UL,
60 0x3E8EB2BCUL,0x3E0E323CUL,0x3C8CB0BCUL,0x01C1C1C0UL,0x2A8AA2A8UL,0x3A8AB2B8UL,0x0E4E424CUL,0x15455154UL,
61 0x3B0B3338UL,0x1CCCD0DCUL,0x28486068UL,0x3F4F737CUL,0x1C8C909CUL,0x18C8D0D8UL,0x0A4A4248UL,0x16465254UL,
62 0x37477374UL,0x2080A0A0UL,0x2DCDE1ECUL,0x06464244UL,0x3585B1B4UL,0x2B0B2328UL,0x25456164UL,0x3ACAF2F8UL,
63 0x23C3E3E0UL,0x3989B1B8UL,0x3181B1B0UL,0x1F8F939CUL,0x1E4E525CUL,0x39C9F1F8UL,0x26C6E2E4UL,0x3282B2B0UL,
64 0x31013130UL,0x2ACAE2E8UL,0x2D4D616CUL,0x1F4F535CUL,0x24C4E0E4UL,0x30C0F0F0UL,0x0DCDC1CCUL,0x08888088UL,
65 0x16061214UL,0x3A0A3238UL,0x18485058UL,0x14C4D0D4UL,0x22426260UL,0x29092128UL,0x07070304UL,0x33033330UL,
66 0x28C8E0E8UL,0x1B0B1318UL,0x05050104UL,0x39497178UL,0x10809090UL,0x2A4A6268UL,0x2A0A2228UL,0x1A8A9298UL
67 };
68
69 static const ulong32 SS1[256] = {
70 0x38380830UL,0xE828C8E0UL,0x2C2D0D21UL,0xA42686A2UL,0xCC0FCFC3UL,0xDC1ECED2UL,0xB03383B3UL,0xB83888B0UL,
71 0xAC2F8FA3UL,0x60204060UL,0x54154551UL,0xC407C7C3UL,0x44044440UL,0x6C2F4F63UL,0x682B4B63UL,0x581B4B53UL,
72 0xC003C3C3UL,0x60224262UL,0x30330333UL,0xB43585B1UL,0x28290921UL,0xA02080A0UL,0xE022C2E2UL,0xA42787A3UL,
73 0xD013C3D3UL,0x90118191UL,0x10110111UL,0x04060602UL,0x1C1C0C10UL,0xBC3C8CB0UL,0x34360632UL,0x480B4B43UL,
74 0xEC2FCFE3UL,0x88088880UL,0x6C2C4C60UL,0xA82888A0UL,0x14170713UL,0xC404C4C0UL,0x14160612UL,0xF434C4F0UL,
75 0xC002C2C2UL,0x44054541UL,0xE021C1E1UL,0xD416C6D2UL,0x3C3F0F33UL,0x3C3D0D31UL,0x8C0E8E82UL,0x98188890UL,
76 0x28280820UL,0x4C0E4E42UL,0xF436C6F2UL,0x3C3E0E32UL,0xA42585A1UL,0xF839C9F1UL,0x0C0D0D01UL,0xDC1FCFD3UL,
77 0xD818C8D0UL,0x282B0B23UL,0x64264662UL,0x783A4A72UL,0x24270723UL,0x2C2F0F23UL,0xF031C1F1UL,0x70324272UL,
78 0x40024242UL,0xD414C4D0UL,0x40014141UL,0xC000C0C0UL,0x70334373UL,0x64274763UL,0xAC2C8CA0UL,0x880B8B83UL,
79 0xF437C7F3UL,0xAC2D8DA1UL,0x80008080UL,0x1C1F0F13UL,0xC80ACAC2UL,0x2C2C0C20UL,0xA82A8AA2UL,0x34340430UL,
80 0xD012C2D2UL,0x080B0B03UL,0xEC2ECEE2UL,0xE829C9E1UL,0x5C1D4D51UL,0x94148490UL,0x18180810UL,0xF838C8F0UL,
81 0x54174753UL,0xAC2E8EA2UL,0x08080800UL,0xC405C5C1UL,0x10130313UL,0xCC0DCDC1UL,0x84068682UL,0xB83989B1UL,
82 0xFC3FCFF3UL,0x7C3D4D71UL,0xC001C1C1UL,0x30310131UL,0xF435C5F1UL,0x880A8A82UL,0x682A4A62UL,0xB03181B1UL,
83 0xD011C1D1UL,0x20200020UL,0xD417C7D3UL,0x00020202UL,0x20220222UL,0x04040400UL,0x68284860UL,0x70314171UL,
84 0x04070703UL,0xD81BCBD3UL,0x9C1D8D91UL,0x98198991UL,0x60214161UL,0xBC3E8EB2UL,0xE426C6E2UL,0x58194951UL,
85 0xDC1DCDD1UL,0x50114151UL,0x90108090UL,0xDC1CCCD0UL,0x981A8A92UL,0xA02383A3UL,0xA82B8BA3UL,0xD010C0D0UL,
86 0x80018181UL,0x0C0F0F03UL,0x44074743UL,0x181A0A12UL,0xE023C3E3UL,0xEC2CCCE0UL,0x8C0D8D81UL,0xBC3F8FB3UL,
87 0x94168692UL,0x783B4B73UL,0x5C1C4C50UL,0xA02282A2UL,0xA02181A1UL,0x60234363UL,0x20230323UL,0x4C0D4D41UL,
88 0xC808C8C0UL,0x9C1E8E92UL,0x9C1C8C90UL,0x383A0A32UL,0x0C0C0C00UL,0x2C2E0E22UL,0xB83A8AB2UL,0x6C2E4E62UL,
89 0x9C1F8F93UL,0x581A4A52UL,0xF032C2F2UL,0x90128292UL,0xF033C3F3UL,0x48094941UL,0x78384870UL,0xCC0CCCC0UL,
90 0x14150511UL,0xF83BCBF3UL,0x70304070UL,0x74354571UL,0x7C3F4F73UL,0x34350531UL,0x10100010UL,0x00030303UL,
91 0x64244460UL,0x6C2D4D61UL,0xC406C6C2UL,0x74344470UL,0xD415C5D1UL,0xB43484B0UL,0xE82ACAE2UL,0x08090901UL,
92 0x74364672UL,0x18190911UL,0xFC3ECEF2UL,0x40004040UL,0x10120212UL,0xE020C0E0UL,0xBC3D8DB1UL,0x04050501UL,
93 0xF83ACAF2UL,0x00010101UL,0xF030C0F0UL,0x282A0A22UL,0x5C1E4E52UL,0xA82989A1UL,0x54164652UL,0x40034343UL,
94 0x84058581UL,0x14140410UL,0x88098981UL,0x981B8B93UL,0xB03080B0UL,0xE425C5E1UL,0x48084840UL,0x78394971UL,
95 0x94178793UL,0xFC3CCCF0UL,0x1C1E0E12UL,0x80028282UL,0x20210121UL,0x8C0C8C80UL,0x181B0B13UL,0x5C1F4F53UL,
96 0x74374773UL,0x54144450UL,0xB03282B2UL,0x1C1D0D11UL,0x24250521UL,0x4C0F4F43UL,0x00000000UL,0x44064642UL,
97 0xEC2DCDE1UL,0x58184850UL,0x50124252UL,0xE82BCBE3UL,0x7C3E4E72UL,0xD81ACAD2UL,0xC809C9C1UL,0xFC3DCDF1UL,
98 0x30300030UL,0x94158591UL,0x64254561UL,0x3C3C0C30UL,0xB43686B2UL,0xE424C4E0UL,0xB83B8BB3UL,0x7C3C4C70UL,
99 0x0C0E0E02UL,0x50104050UL,0x38390931UL,0x24260622UL,0x30320232UL,0x84048480UL,0x68294961UL,0x90138393UL,
100 0x34370733UL,0xE427C7E3UL,0x24240420UL,0xA42484A0UL,0xC80BCBC3UL,0x50134353UL,0x080A0A02UL,0x84078783UL,
101 0xD819C9D1UL,0x4C0C4C40UL,0x80038383UL,0x8C0F8F83UL,0xCC0ECEC2UL,0x383B0B33UL,0x480A4A42UL,0xB43787B3UL
102 };
103
104 static const ulong32 SS2[256] = {
105 0xA1A82989UL,0x81840585UL,0xD2D416C6UL,0xD3D013C3UL,0x50541444UL,0x111C1D0DUL,0xA0AC2C8CUL,0x21242505UL,
106 0x515C1D4DUL,0x43400343UL,0x10181808UL,0x121C1E0EUL,0x51501141UL,0xF0FC3CCCUL,0xC2C80ACAUL,0x63602343UL,
107 0x20282808UL,0x40440444UL,0x20202000UL,0x919C1D8DUL,0xE0E020C0UL,0xE2E022C2UL,0xC0C808C8UL,0x13141707UL,
108 0xA1A42585UL,0x838C0F8FUL,0x03000303UL,0x73783B4BUL,0xB3B83B8BUL,0x13101303UL,0xD2D012C2UL,0xE2EC2ECEUL,
109 0x70703040UL,0x808C0C8CUL,0x333C3F0FUL,0xA0A82888UL,0x32303202UL,0xD1DC1DCDUL,0xF2F436C6UL,0x70743444UL,
110 0xE0EC2CCCUL,0x91941585UL,0x03080B0BUL,0x53541747UL,0x505C1C4CUL,0x53581B4BUL,0xB1BC3D8DUL,0x01000101UL,
111 0x20242404UL,0x101C1C0CUL,0x73703343UL,0x90981888UL,0x10101000UL,0xC0CC0CCCUL,0xF2F032C2UL,0xD1D819C9UL,
112 0x202C2C0CUL,0xE3E427C7UL,0x72703242UL,0x83800383UL,0x93981B8BUL,0xD1D011C1UL,0x82840686UL,0xC1C809C9UL,
113 0x60602040UL,0x50501040UL,0xA3A02383UL,0xE3E82BCBUL,0x010C0D0DUL,0xB2B43686UL,0x929C1E8EUL,0x434C0F4FUL,
114 0xB3B43787UL,0x52581A4AUL,0xC2C406C6UL,0x70783848UL,0xA2A42686UL,0x12101202UL,0xA3AC2F8FUL,0xD1D415C5UL,
115 0x61602141UL,0xC3C003C3UL,0xB0B43484UL,0x41400141UL,0x52501242UL,0x717C3D4DUL,0x818C0D8DUL,0x00080808UL,
116 0x131C1F0FUL,0x91981989UL,0x00000000UL,0x11181909UL,0x00040404UL,0x53501343UL,0xF3F437C7UL,0xE1E021C1UL,
117 0xF1FC3DCDUL,0x72743646UL,0x232C2F0FUL,0x23242707UL,0xB0B03080UL,0x83880B8BUL,0x020C0E0EUL,0xA3A82B8BUL,
118 0xA2A02282UL,0x626C2E4EUL,0x93901383UL,0x414C0D4DUL,0x61682949UL,0x707C3C4CUL,0x01080909UL,0x02080A0AUL,
119 0xB3BC3F8FUL,0xE3EC2FCFUL,0xF3F033C3UL,0xC1C405C5UL,0x83840787UL,0x10141404UL,0xF2FC3ECEUL,0x60642444UL,
120 0xD2DC1ECEUL,0x222C2E0EUL,0x43480B4BUL,0x12181A0AUL,0x02040606UL,0x21202101UL,0x63682B4BUL,0x62642646UL,
121 0x02000202UL,0xF1F435C5UL,0x92901282UL,0x82880A8AUL,0x000C0C0CUL,0xB3B03383UL,0x727C3E4EUL,0xD0D010C0UL,
122 0x72783A4AUL,0x43440747UL,0x92941686UL,0xE1E425C5UL,0x22242606UL,0x80800080UL,0xA1AC2D8DUL,0xD3DC1FCFUL,
123 0xA1A02181UL,0x30303000UL,0x33343707UL,0xA2AC2E8EUL,0x32343606UL,0x11141505UL,0x22202202UL,0x30383808UL,
124 0xF0F434C4UL,0xA3A42787UL,0x41440545UL,0x404C0C4CUL,0x81800181UL,0xE1E829C9UL,0x80840484UL,0x93941787UL,
125 0x31343505UL,0xC3C80BCBUL,0xC2CC0ECEUL,0x303C3C0CUL,0x71703141UL,0x11101101UL,0xC3C407C7UL,0x81880989UL,
126 0x71743545UL,0xF3F83BCBUL,0xD2D81ACAUL,0xF0F838C8UL,0x90941484UL,0x51581949UL,0x82800282UL,0xC0C404C4UL,
127 0xF3FC3FCFUL,0x41480949UL,0x31383909UL,0x63642747UL,0xC0C000C0UL,0xC3CC0FCFUL,0xD3D417C7UL,0xB0B83888UL,
128 0x030C0F0FUL,0x828C0E8EUL,0x42400242UL,0x23202303UL,0x91901181UL,0x606C2C4CUL,0xD3D81BCBUL,0xA0A42484UL,
129 0x30343404UL,0xF1F031C1UL,0x40480848UL,0xC2C002C2UL,0x636C2F4FUL,0x313C3D0DUL,0x212C2D0DUL,0x40400040UL,
130 0xB2BC3E8EUL,0x323C3E0EUL,0xB0BC3C8CUL,0xC1C001C1UL,0xA2A82A8AUL,0xB2B83A8AUL,0x424C0E4EUL,0x51541545UL,
131 0x33383B0BUL,0xD0DC1CCCUL,0x60682848UL,0x737C3F4FUL,0x909C1C8CUL,0xD0D818C8UL,0x42480A4AUL,0x52541646UL,
132 0x73743747UL,0xA0A02080UL,0xE1EC2DCDUL,0x42440646UL,0xB1B43585UL,0x23282B0BUL,0x61642545UL,0xF2F83ACAUL,
133 0xE3E023C3UL,0xB1B83989UL,0xB1B03181UL,0x939C1F8FUL,0x525C1E4EUL,0xF1F839C9UL,0xE2E426C6UL,0xB2B03282UL,
134 0x31303101UL,0xE2E82ACAUL,0x616C2D4DUL,0x535C1F4FUL,0xE0E424C4UL,0xF0F030C0UL,0xC1CC0DCDUL,0x80880888UL,
135 0x12141606UL,0x32383A0AUL,0x50581848UL,0xD0D414C4UL,0x62602242UL,0x21282909UL,0x03040707UL,0x33303303UL,
136 0xE0E828C8UL,0x13181B0BUL,0x01040505UL,0x71783949UL,0x90901080UL,0x62682A4AUL,0x22282A0AUL,0x92981A8AUL
137 };
138
139 static const ulong32 SS3[256] = {
140 0x08303838UL,0xC8E0E828UL,0x0D212C2DUL,0x86A2A426UL,0xCFC3CC0FUL,0xCED2DC1EUL,0x83B3B033UL,0x88B0B838UL,
141 0x8FA3AC2FUL,0x40606020UL,0x45515415UL,0xC7C3C407UL,0x44404404UL,0x4F636C2FUL,0x4B63682BUL,0x4B53581BUL,
142 0xC3C3C003UL,0x42626022UL,0x03333033UL,0x85B1B435UL,0x09212829UL,0x80A0A020UL,0xC2E2E022UL,0x87A3A427UL,
143 0xC3D3D013UL,0x81919011UL,0x01111011UL,0x06020406UL,0x0C101C1CUL,0x8CB0BC3CUL,0x06323436UL,0x4B43480BUL,
144 0xCFE3EC2FUL,0x88808808UL,0x4C606C2CUL,0x88A0A828UL,0x07131417UL,0xC4C0C404UL,0x06121416UL,0xC4F0F434UL,
145 0xC2C2C002UL,0x45414405UL,0xC1E1E021UL,0xC6D2D416UL,0x0F333C3FUL,0x0D313C3DUL,0x8E828C0EUL,0x88909818UL,
146 0x08202828UL,0x4E424C0EUL,0xC6F2F436UL,0x0E323C3EUL,0x85A1A425UL,0xC9F1F839UL,0x0D010C0DUL,0xCFD3DC1FUL,
147 0xC8D0D818UL,0x0B23282BUL,0x46626426UL,0x4A72783AUL,0x07232427UL,0x0F232C2FUL,0xC1F1F031UL,0x42727032UL,
148 0x42424002UL,0xC4D0D414UL,0x41414001UL,0xC0C0C000UL,0x43737033UL,0x47636427UL,0x8CA0AC2CUL,0x8B83880BUL,
149 0xC7F3F437UL,0x8DA1AC2DUL,0x80808000UL,0x0F131C1FUL,0xCAC2C80AUL,0x0C202C2CUL,0x8AA2A82AUL,0x04303434UL,
150 0xC2D2D012UL,0x0B03080BUL,0xCEE2EC2EUL,0xC9E1E829UL,0x4D515C1DUL,0x84909414UL,0x08101818UL,0xC8F0F838UL,
151 0x47535417UL,0x8EA2AC2EUL,0x08000808UL,0xC5C1C405UL,0x03131013UL,0xCDC1CC0DUL,0x86828406UL,0x89B1B839UL,
152 0xCFF3FC3FUL,0x4D717C3DUL,0xC1C1C001UL,0x01313031UL,0xC5F1F435UL,0x8A82880AUL,0x4A62682AUL,0x81B1B031UL,
153 0xC1D1D011UL,0x00202020UL,0xC7D3D417UL,0x02020002UL,0x02222022UL,0x04000404UL,0x48606828UL,0x41717031UL,
154 0x07030407UL,0xCBD3D81BUL,0x8D919C1DUL,0x89919819UL,0x41616021UL,0x8EB2BC3EUL,0xC6E2E426UL,0x49515819UL,
155 0xCDD1DC1DUL,0x41515011UL,0x80909010UL,0xCCD0DC1CUL,0x8A92981AUL,0x83A3A023UL,0x8BA3A82BUL,0xC0D0D010UL,
156 0x81818001UL,0x0F030C0FUL,0x47434407UL,0x0A12181AUL,0xC3E3E023UL,0xCCE0EC2CUL,0x8D818C0DUL,0x8FB3BC3FUL,
157 0x86929416UL,0x4B73783BUL,0x4C505C1CUL,0x82A2A022UL,0x81A1A021UL,0x43636023UL,0x03232023UL,0x4D414C0DUL,
158 0xC8C0C808UL,0x8E929C1EUL,0x8C909C1CUL,0x0A32383AUL,0x0C000C0CUL,0x0E222C2EUL,0x8AB2B83AUL,0x4E626C2EUL,
159 0x8F939C1FUL,0x4A52581AUL,0xC2F2F032UL,0x82929012UL,0xC3F3F033UL,0x49414809UL,0x48707838UL,0xCCC0CC0CUL,
160 0x05111415UL,0xCBF3F83BUL,0x40707030UL,0x45717435UL,0x4F737C3FUL,0x05313435UL,0x00101010UL,0x03030003UL,
161 0x44606424UL,0x4D616C2DUL,0xC6C2C406UL,0x44707434UL,0xC5D1D415UL,0x84B0B434UL,0xCAE2E82AUL,0x09010809UL,
162 0x46727436UL,0x09111819UL,0xCEF2FC3EUL,0x40404000UL,0x02121012UL,0xC0E0E020UL,0x8DB1BC3DUL,0x05010405UL,
163 0xCAF2F83AUL,0x01010001UL,0xC0F0F030UL,0x0A22282AUL,0x4E525C1EUL,0x89A1A829UL,0x46525416UL,0x43434003UL,
164 0x85818405UL,0x04101414UL,0x89818809UL,0x8B93981BUL,0x80B0B030UL,0xC5E1E425UL,0x48404808UL,0x49717839UL,
165 0x87939417UL,0xCCF0FC3CUL,0x0E121C1EUL,0x82828002UL,0x01212021UL,0x8C808C0CUL,0x0B13181BUL,0x4F535C1FUL,
166 0x47737437UL,0x44505414UL,0x82B2B032UL,0x0D111C1DUL,0x05212425UL,0x4F434C0FUL,0x00000000UL,0x46424406UL,
167 0xCDE1EC2DUL,0x48505818UL,0x42525012UL,0xCBE3E82BUL,0x4E727C3EUL,0xCAD2D81AUL,0xC9C1C809UL,0xCDF1FC3DUL,
168 0x00303030UL,0x85919415UL,0x45616425UL,0x0C303C3CUL,0x86B2B436UL,0xC4E0E424UL,0x8BB3B83BUL,0x4C707C3CUL,
169 0x0E020C0EUL,0x40505010UL,0x09313839UL,0x06222426UL,0x02323032UL,0x84808404UL,0x49616829UL,0x83939013UL,
170 0x07333437UL,0xC7E3E427UL,0x04202424UL,0x84A0A424UL,0xCBC3C80BUL,0x43535013UL,0x0A02080AUL,0x87838407UL,
171 0xC9D1D819UL,0x4C404C0CUL,0x83838003UL,0x8F838C0FUL,0xCEC2CC0EUL,0x0B33383BUL,0x4A42480AUL,0x87B3B437UL
172 };
173
174 static const ulong32 KCi[16] = {
175 0x9E3779B9,0x3C6EF373,
176 0x78DDE6E6,0xF1BBCDCC,
177 0xE3779B99,0xC6EF3733,
178 0x8DDE6E67,0x1BBCDCCF,
179 0x3779B99E,0x6EF3733C,
180 0xDDE6E678,0xBBCDCCF1,
181 0x779B99E3,0xEF3733C6,
182 0xDE6E678D,0xBCDCCF1B
183 };
184
185 #define G(x) (SS3[((x)>>24)&255] ^ SS2[((x)>>16)&255] ^ SS1[((x)>>8)&255] ^ SS0[(x)&255])
186
187 #define F(L1, L2, R1, R2, K1, K2) \
188 T2 = G((R1 ^ K1) ^ (R2 ^ K2)); \
189 T = G( G(T2 + (R1 ^ K1)) + T2); \
190 L2 ^= T; \
191 L1 ^= (T + G(T2 + (R1 ^ K1))); \
192
193 /**
194 Initialize the SEED block cipher
195 @param key The symmetric key you wish to pass
196 @param keylen The key length in bytes
197 @param num_rounds The number of rounds desired (0 for default)
198 @param skey The key in as scheduled by this function.
199 @return CRYPT_OK if successful
200 */
201 int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
202 {
203 int i;
204 ulong32 tmp, k1, k2, k3, k4;
205
206 if (keylen != 16) {
207 return CRYPT_INVALID_KEYSIZE;
208 }
209
210 if (num_rounds != 16 && num_rounds != 0) {
211 return CRYPT_INVALID_ROUNDS;
212 }
213
214 /* load key */
215 LOAD32H(k1, key);
216 LOAD32H(k2, key+4);
217 LOAD32H(k3, key+8);
218 LOAD32H(k4, key+12);
219
220 for (i = 0; i < 16; i++) {
221 skey->kseed.K[2*i+0] = G(k1 + k3 - KCi[i]);
222 skey->kseed.K[2*i+1] = G(k2 - k4 + KCi[i]);
223 if (i&1) {
224 tmp = k3;
225 k3 = ((k3 << 8) | (k4 >> 24)) & 0xFFFFFFFF;
226 k4 = ((k4 << 8) | (tmp >> 24)) & 0xFFFFFFFF;
227 } else {
228 tmp = k1;
229 k1 = ((k1 >> 8) | (k2 << 24)) & 0xFFFFFFFF;
230 k2 = ((k2 >> 8) | (tmp << 24)) & 0xFFFFFFFF;
231 }
232 /* reverse keys for decrypt */
233 skey->kseed.dK[2*(15-i)+0] = skey->kseed.K[2*i+0];
234 skey->kseed.dK[2*(15-i)+1] = skey->kseed.K[2*i+1];
235 }
236
237 return CRYPT_OK;
238 }
239
240 static void rounds(ulong32 *P, ulong32 *K)
241 {
242 ulong32 T, T2;
243 int i;
244 for (i = 0; i < 16; i += 2) {
245 F(P[0], P[1], P[2], P[3], K[0], K[1]);
246 F(P[2], P[3], P[0], P[1], K[2], K[3]);
247 K += 4;
248 }
249 }
250
251 /**
252 Encrypts a block of text with SEED
253 @param pt The input plaintext (16 bytes)
254 @param ct The output ciphertext (16 bytes)
255 @param skey The key as scheduled
256 @return CRYPT_OK if successful
257 */
258 int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
259 {
260 ulong32 P[4];
261 LOAD32H(P[0], pt);
262 LOAD32H(P[1], pt+4);
263 LOAD32H(P[2], pt+8);
264 LOAD32H(P[3], pt+12);
265 rounds(P, skey->kseed.K);
266 STORE32H(P[2], ct);
267 STORE32H(P[3], ct+4);
268 STORE32H(P[0], ct+8);
269 STORE32H(P[1], ct+12);
270 return CRYPT_OK;
271 }
272
273 /**
274 Decrypts a block of text with SEED
275 @param ct The input ciphertext (16 bytes)
276 @param pt The output plaintext (16 bytes)
277 @param skey The key as scheduled
278 @return CRYPT_OK if successful
279 */
280 int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
281 {
282 ulong32 P[4];
283 LOAD32H(P[0], ct);
284 LOAD32H(P[1], ct+4);
285 LOAD32H(P[2], ct+8);
286 LOAD32H(P[3], ct+12);
287 rounds(P, skey->kseed.dK);
288 STORE32H(P[2], pt);
289 STORE32H(P[3], pt+4);
290 STORE32H(P[0], pt+8);
291 STORE32H(P[1], pt+12);
292 return CRYPT_OK;
293 }
294
295 /** Terminate the context
296 @param skey The scheduled key
297 */
298 void kseed_done(symmetric_key *skey)
299 {
300 }
301
302 /**
303 Performs a self-test of the SEED block cipher
304 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
305 */
306 int kseed_test(void)
307 {
308 #if !defined(LTC_TEST)
309 return CRYPT_NOP;
310 #else
311 static const struct test {
312 unsigned char pt[16], ct[16], key[16];
313 } tests[] = {
314
315 {
316 { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
317 { 0x5E,0xBA,0xC6,0xE0,0x05,0x4E,0x16,0x68,0x19,0xAF,0xF1,0xCC,0x6D,0x34,0x6C,0xDB },
318 { 0 },
319 },
320
321 {
322 { 0 },
323 { 0xC1,0x1F,0x22,0xF2,0x01,0x40,0x50,0x50,0x84,0x48,0x35,0x97,0xE4,0x37,0x0F,0x43 },
324 { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
325 },
326
327 {
328 { 0x83,0xA2,0xF8,0xA2,0x88,0x64,0x1F,0xB9,0xA4,0xE9,0xA5,0xCC,0x2F,0x13,0x1C,0x7D },
329 { 0xEE,0x54,0xD1,0x3E,0xBC,0xAE,0x70,0x6D,0x22,0x6B,0xC3,0x14,0x2C,0xD4,0x0D,0x4A },
330 { 0x47,0x06,0x48,0x08,0x51,0xE6,0x1B,0xE8,0x5D,0x74,0xBF,0xB3,0xFD,0x95,0x61,0x85 },
331 },
332
333 {
334 { 0xB4,0x1E,0x6B,0xE2,0xEB,0xA8,0x4A,0x14,0x8E,0x2E,0xED,0x84,0x59,0x3C,0x5E,0xC7 },
335 { 0x9B,0x9B,0x7B,0xFC,0xD1,0x81,0x3C,0xB9,0x5D,0x0B,0x36,0x18,0xF4,0x0F,0x51,0x22 },
336 { 0x28,0xDB,0xC3,0xBC,0x49,0xFF,0xD8,0x7D,0xCF,0xA5,0x09,0xB1,0x1D,0x42,0x2B,0xE7 },
337 }
338 };
339 int x;
340 unsigned char buf[2][16];
341 symmetric_key skey;
342
343 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
344 kseed_setup(tests[x].key, 16, 0, &skey);
345 kseed_ecb_encrypt(tests[x].pt, buf[0], &skey);
346 kseed_ecb_decrypt(buf[0], buf[1], &skey);
347 if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) {
348 #if 0
349 int i, j;
350 printf ("\n\nLTC_KSEED failed for x=%d, I got:\n", x);
351 for (i = 0; i < 2; i++) {
352 const unsigned char *expected, *actual;
353 expected = (i ? tests[x].pt : tests[x].ct);
354 actual = buf[i];
355 printf ("expected actual (%s)\n", (i ? "plaintext" : "ciphertext"));
356 for (j = 0; j < 16; j++) {
357 const char *eq = (expected[j] == actual[j] ? "==" : "!=");
358 printf (" %02x %s %02x\n", expected[j], eq, actual[j]);
359 }
360 printf ("\n");
361 }
362 #endif
363 return CRYPT_FAIL_TESTVECTOR;
364 }
365 }
366 return CRYPT_OK;
367 #endif
368 }
369
370 /**
371 Gets suitable key size
372 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
373 @return CRYPT_OK if the input key size is acceptable.
374 */
375 int kseed_keysize(int *keysize)
376 {
377 LTC_ARGCHK(keysize != NULL);
378 if (*keysize >= 16) {
379 *keysize = 16;
380 } else {
381 return CRYPT_INVALID_KEYSIZE;
382 }
383 return CRYPT_OK;
384 }
385
386 #endif
387
388 /* $Source$ */
389 /* $Revision$ */
390 /* $Date$ */
+0
-320
libtom-src/ciphers/multi2.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file multi2.c
13 Multi-2 implementation (not public domain, hence the default disable)
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_MULTI2
18
19 static void pi1(ulong32 *p)
20 {
21 p[1] ^= p[0];
22 }
23
24 static void pi2(ulong32 *p, ulong32 *k)
25 {
26 ulong32 t;
27 t = (p[1] + k[0]) & 0xFFFFFFFFUL;
28 t = (ROL(t, 1) + t - 1) & 0xFFFFFFFFUL;
29 t = (ROL(t, 4) ^ t) & 0xFFFFFFFFUL;
30 p[0] ^= t;
31 }
32
33 static void pi3(ulong32 *p, ulong32 *k)
34 {
35 ulong32 t;
36 t = p[0] + k[1];
37 t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL;
38 t = (ROL(t, 8) ^ t) & 0xFFFFFFFFUL;
39 t = (t + k[2]) & 0xFFFFFFFFUL;
40 t = (ROL(t, 1) - t) & 0xFFFFFFFFUL;
41 t = ROL(t, 16) ^ (p[0] | t);
42 p[1] ^= t;
43 }
44
45 static void pi4(ulong32 *p, ulong32 *k)
46 {
47 ulong32 t;
48 t = (p[1] + k[3]) & 0xFFFFFFFFUL;
49 t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL;
50 p[0] ^= t;
51 }
52
53 static void setup(ulong32 *dk, ulong32 *k, ulong32 *uk)
54 {
55 int n, t;
56 ulong32 p[2];
57
58 p[0] = dk[0]; p[1] = dk[1];
59
60 t = 4;
61 n = 0;
62 pi1(p);
63 pi2(p, k);
64 uk[n++] = p[0];
65 pi3(p, k);
66 uk[n++] = p[1];
67 pi4(p, k);
68 uk[n++] = p[0];
69 pi1(p);
70 uk[n++] = p[1];
71 pi2(p, k+t);
72 uk[n++] = p[0];
73 pi3(p, k+t);
74 uk[n++] = p[1];
75 pi4(p, k+t);
76 uk[n++] = p[0];
77 pi1(p);
78 uk[n++] = p[1];
79 }
80
81 static void encrypt(ulong32 *p, int N, ulong32 *uk)
82 {
83 int n, t;
84 for (t = n = 0; ; ) {
85 pi1(p); if (++n == N) break;
86 pi2(p, uk+t); if (++n == N) break;
87 pi3(p, uk+t); if (++n == N) break;
88 pi4(p, uk+t); if (++n == N) break;
89 t ^= 4;
90 }
91 }
92
93 static void decrypt(ulong32 *p, int N, ulong32 *uk)
94 {
95 int n, t;
96 for (t = 4*(((N-1)>>2)&1), n = N; ; ) {
97 switch (n<=4 ? n : ((n-1)%4)+1) {
98 case 4: pi4(p, uk+t); --n;
99 case 3: pi3(p, uk+t); --n;
100 case 2: pi2(p, uk+t); --n;
101 case 1: pi1(p); --n; break;
102 case 0: return;
103 }
104 t ^= 4;
105 }
106 }
107
108 const struct ltc_cipher_descriptor multi2_desc = {
109 "multi2",
110 22,
111 40, 40, 8, 128,
112 &multi2_setup,
113 &multi2_ecb_encrypt,
114 &multi2_ecb_decrypt,
115 &multi2_test,
116 &multi2_done,
117 &multi2_keysize,
118 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
119 };
120
121 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
122 {
123 ulong32 sk[8], dk[2];
124 int x;
125
126 LTC_ARGCHK(key != NULL);
127 LTC_ARGCHK(skey != NULL);
128
129 if (keylen != 40) return CRYPT_INVALID_KEYSIZE;
130 if (num_rounds == 0) num_rounds = 128;
131
132 skey->multi2.N = num_rounds;
133 for (x = 0; x < 8; x++) {
134 LOAD32H(sk[x], key + x*4);
135 }
136 LOAD32H(dk[0], key + 32);
137 LOAD32H(dk[1], key + 36);
138 setup(dk, sk, skey->multi2.uk);
139
140 zeromem(sk, sizeof(sk));
141 zeromem(dk, sizeof(dk));
142 return CRYPT_OK;
143 }
144
145 /**
146 Encrypts a block of text with multi2
147 @param pt The input plaintext (8 bytes)
148 @param ct The output ciphertext (8 bytes)
149 @param skey The key as scheduled
150 @return CRYPT_OK if successful
151 */
152 int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
153 {
154 ulong32 p[2];
155 LTC_ARGCHK(pt != NULL);
156 LTC_ARGCHK(ct != NULL);
157 LTC_ARGCHK(skey != NULL);
158 LOAD32H(p[0], pt);
159 LOAD32H(p[1], pt+4);
160 encrypt(p, skey->multi2.N, skey->multi2.uk);
161 STORE32H(p[0], ct);
162 STORE32H(p[1], ct+4);
163 return CRYPT_OK;
164 }
165
166 /**
167 Decrypts a block of text with multi2
168 @param ct The input ciphertext (8 bytes)
169 @param pt The output plaintext (8 bytes)
170 @param skey The key as scheduled
171 @return CRYPT_OK if successful
172 */
173 int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
174 {
175 ulong32 p[2];
176 LTC_ARGCHK(pt != NULL);
177 LTC_ARGCHK(ct != NULL);
178 LTC_ARGCHK(skey != NULL);
179 LOAD32H(p[0], ct);
180 LOAD32H(p[1], ct+4);
181 decrypt(p, skey->multi2.N, skey->multi2.uk);
182 STORE32H(p[0], pt);
183 STORE32H(p[1], pt+4);
184 return CRYPT_OK;
185 }
186
187 /**
188 Performs a self-test of the multi2 block cipher
189 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
190 */
191 int multi2_test(void)
192 {
193 static const struct {
194 unsigned char key[40];
195 unsigned char pt[8], ct[8];
196 int rounds;
197 } tests[] = {
198 {
199 {
200 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00,
204
205 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00,
209
210 0x01, 0x23, 0x45, 0x67,
211 0x89, 0xAB, 0xCD, 0xEF
212 },
213 {
214 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x01,
216 },
217 {
218 0xf8, 0x94, 0x40, 0x84,
219 0x5e, 0x11, 0xcf, 0x89
220 },
221 128,
222 },
223 {
224 {
225 0x35, 0x91, 0x9d, 0x96,
226 0x07, 0x02, 0xe2, 0xce,
227 0x8d, 0x0b, 0x58, 0x3c,
228 0xc9, 0xc8, 0x9d, 0x59,
229 0xa2, 0xae, 0x96, 0x4e,
230 0x87, 0x82, 0x45, 0xed,
231 0x3f, 0x2e, 0x62, 0xd6,
232 0x36, 0x35, 0xd0, 0x67,
233
234 0xb1, 0x27, 0xb9, 0x06,
235 0xe7, 0x56, 0x22, 0x38,
236 },
237 {
238 0x1f, 0xb4, 0x60, 0x60,
239 0xd0, 0xb3, 0x4f, 0xa5
240 },
241 {
242 0xca, 0x84, 0xa9, 0x34,
243 0x75, 0xc8, 0x60, 0xe5
244 },
245 216,
246 }
247 };
248 unsigned char buf[8];
249 symmetric_key skey;
250 int err, x;
251
252 for (x = 1; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
253 if ((err = multi2_setup(tests[x].key, 40, tests[x].rounds, &skey)) != CRYPT_OK) {
254 return err;
255 }
256 if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) {
257 return err;
258 }
259
260 if (XMEMCMP(buf, tests[x].ct, 8)) {
261 return CRYPT_FAIL_TESTVECTOR;
262 }
263
264 if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) {
265 return err;
266 }
267 if (XMEMCMP(buf, tests[x].pt, 8)) {
268 return CRYPT_FAIL_TESTVECTOR;
269 }
270 }
271
272 for (x = 128; x < 256; ++x) {
273 unsigned char ct[8];
274
275 if ((err = multi2_setup(tests[0].key, 40, x, &skey)) != CRYPT_OK) {
276 return err;
277 }
278 if ((err = multi2_ecb_encrypt(tests[0].pt, ct, &skey)) != CRYPT_OK) {
279 return err;
280 }
281 if ((err = multi2_ecb_decrypt(ct, buf, &skey)) != CRYPT_OK) {
282 return err;
283 }
284 if (XMEMCMP(buf, tests[0].pt, 8)) {
285 return CRYPT_FAIL_TESTVECTOR;
286 }
287 }
288
289 return CRYPT_OK;
290 }
291
292 /** Terminate the context
293 @param skey The scheduled key
294 */
295 void multi2_done(symmetric_key *skey)
296 {
297 }
298
299 /**
300 Gets suitable key size
301 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
302 @return CRYPT_OK if the input key size is acceptable.
303 */
304 int multi2_keysize(int *keysize)
305 {
306 LTC_ARGCHK(keysize != NULL);
307 if (*keysize >= 40) {
308 *keysize = 40;
309 } else {
310 return CRYPT_INVALID_KEYSIZE;
311 }
312 return CRYPT_OK;
313 }
314
315 #endif
316
317 /* $Source$ */
318 /* $Revision$ */
319 /* $Date$ */
+0
-344
libtom-src/ciphers/noekeon.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @file noekeon.c
12 Implementation of the Noekeon block cipher by Tom St Denis
13 */
14 #include "tomcrypt.h"
15
16 #ifdef LTC_NOEKEON
17
18 const struct ltc_cipher_descriptor noekeon_desc =
19 {
20 "noekeon",
21 16,
22 16, 16, 16, 16,
23 &noekeon_setup,
24 &noekeon_ecb_encrypt,
25 &noekeon_ecb_decrypt,
26 &noekeon_test,
27 &noekeon_done,
28 &noekeon_keysize,
29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
30 };
31
32 static const ulong32 RC[] = {
33 0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL,
34 0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL,
35 0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL,
36 0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL,
37 0x000000d4UL
38 };
39
40 #define kTHETA(a, b, c, d) \
41 temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
42 b ^= temp; d ^= temp; \
43 temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
44 a ^= temp; c ^= temp;
45
46 #define THETA(k, a, b, c, d) \
47 temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
48 b ^= temp ^ k[1]; d ^= temp ^ k[3]; \
49 temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
50 a ^= temp ^ k[0]; c ^= temp ^ k[2];
51
52 #define GAMMA(a, b, c, d) \
53 b ^= ~(d|c); \
54 a ^= c&b; \
55 temp = d; d = a; a = temp;\
56 c ^= a ^ b ^ d; \
57 b ^= ~(d|c); \
58 a ^= c&b;
59
60 #define PI1(a, b, c, d) \
61 b = ROLc(b, 1); c = ROLc(c, 5); d = ROLc(d, 2);
62
63 #define PI2(a, b, c, d) \
64 b = RORc(b, 1); c = RORc(c, 5); d = RORc(d, 2);
65
66 /**
67 Initialize the Noekeon block cipher
68 @param key The symmetric key you wish to pass
69 @param keylen The key length in bytes
70 @param num_rounds The number of rounds desired (0 for default)
71 @param skey The key in as scheduled by this function.
72 @return CRYPT_OK if successful
73 */
74 int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
75 {
76 ulong32 temp;
77
78 LTC_ARGCHK(key != NULL);
79 LTC_ARGCHK(skey != NULL);
80
81 if (keylen != 16) {
82 return CRYPT_INVALID_KEYSIZE;
83 }
84
85 if (num_rounds != 16 && num_rounds != 0) {
86 return CRYPT_INVALID_ROUNDS;
87 }
88
89 LOAD32H(skey->noekeon.K[0],&key[0]);
90 LOAD32H(skey->noekeon.K[1],&key[4]);
91 LOAD32H(skey->noekeon.K[2],&key[8]);
92 LOAD32H(skey->noekeon.K[3],&key[12]);
93
94 LOAD32H(skey->noekeon.dK[0],&key[0]);
95 LOAD32H(skey->noekeon.dK[1],&key[4]);
96 LOAD32H(skey->noekeon.dK[2],&key[8]);
97 LOAD32H(skey->noekeon.dK[3],&key[12]);
98
99 kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]);
100
101 return CRYPT_OK;
102 }
103
104 /**
105 Encrypts a block of text with Noekeon
106 @param pt The input plaintext (16 bytes)
107 @param ct The output ciphertext (16 bytes)
108 @param skey The key as scheduled
109 @return CRYPT_OK if successful
110 */
111 #ifdef LTC_CLEAN_STACK
112 static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
113 #else
114 int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
115 #endif
116 {
117 ulong32 a,b,c,d,temp;
118 int r;
119
120 LTC_ARGCHK(skey != NULL);
121 LTC_ARGCHK(pt != NULL);
122 LTC_ARGCHK(ct != NULL);
123
124 LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]);
125 LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]);
126
127 #define ROUND(i) \
128 a ^= RC[i]; \
129 THETA(skey->noekeon.K, a,b,c,d); \
130 PI1(a,b,c,d); \
131 GAMMA(a,b,c,d); \
132 PI2(a,b,c,d);
133
134 for (r = 0; r < 16; ++r) {
135 ROUND(r);
136 }
137
138 #undef ROUND
139
140 a ^= RC[16];
141 THETA(skey->noekeon.K, a, b, c, d);
142
143 STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
144 STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
145
146 return CRYPT_OK;
147 }
148
149 #ifdef LTC_CLEAN_STACK
150 int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
151 {
152 int err = _noekeon_ecb_encrypt(pt, ct, skey);
153 burn_stack(sizeof(ulong32) * 5 + sizeof(int));
154 return err;
155 }
156 #endif
157
158 /**
159 Decrypts a block of text with Noekeon
160 @param ct The input ciphertext (16 bytes)
161 @param pt The output plaintext (16 bytes)
162 @param skey The key as scheduled
163 @return CRYPT_OK if successful
164 */
165 #ifdef LTC_CLEAN_STACK
166 static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
167 #else
168 int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
169 #endif
170 {
171 ulong32 a,b,c,d, temp;
172 int r;
173
174 LTC_ARGCHK(skey != NULL);
175 LTC_ARGCHK(pt != NULL);
176 LTC_ARGCHK(ct != NULL);
177
178 LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]);
179 LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]);
180
181
182 #define ROUND(i) \
183 THETA(skey->noekeon.dK, a,b,c,d); \
184 a ^= RC[i]; \
185 PI1(a,b,c,d); \
186 GAMMA(a,b,c,d); \
187 PI2(a,b,c,d);
188
189 for (r = 16; r > 0; --r) {
190 ROUND(r);
191 }
192
193 #undef ROUND
194
195 THETA(skey->noekeon.dK, a,b,c,d);
196 a ^= RC[0];
197 STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
198 STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
199 return CRYPT_OK;
200 }
201
202 #ifdef LTC_CLEAN_STACK
203 int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
204 {
205 int err = _noekeon_ecb_decrypt(ct, pt, skey);
206 burn_stack(sizeof(ulong32) * 5 + sizeof(int));
207 return err;
208 }
209 #endif
210
211 /**
212 Performs a self-test of the Noekeon block cipher
213 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
214 */
215 int noekeon_test(void)
216 {
217 #ifndef LTC_TEST
218 return CRYPT_NOP;
219 #else
220 static const struct {
221 int keylen;
222 unsigned char key[16], pt[16], ct[16];
223 } tests[] = {
224 {
225 16,
226 { 0xAA, 0x3C, 0x8C, 0x86, 0xD9, 0x8B, 0xF8, 0xBE, 0x21, 0xE0, 0x36, 0x09, 0x78, 0xFB, 0xE4, 0x90 },
227 { 0xE4, 0x96, 0x6C, 0xD3, 0x13, 0xA0, 0x6C, 0xAF, 0xD0, 0x23, 0xC9, 0xFD, 0x45, 0x32, 0x23, 0x16 },
228 { 0xA6, 0xEC, 0xB8, 0xA8, 0x61, 0xFD, 0x62, 0xD9, 0x13, 0x02, 0xFE, 0x9E, 0x47, 0x01, 0x3F, 0xC3 }
229 },
230 {
231 16,
232 { 0xED, 0x43, 0xD1, 0x87, 0x21, 0x7E, 0xE0, 0x97, 0x3D, 0x76, 0xC3, 0x37, 0x2E, 0x7D, 0xAE, 0xD3 },
233 { 0xE3, 0x38, 0x32, 0xCC, 0xF2, 0x2F, 0x2F, 0x0A, 0x4A, 0x8B, 0x8F, 0x18, 0x12, 0x20, 0x17, 0xD3 },
234 { 0x94, 0xA5, 0xDF, 0xF5, 0xAE, 0x1C, 0xBB, 0x22, 0xAD, 0xEB, 0xA7, 0x0D, 0xB7, 0x82, 0x90, 0xA0 }
235 },
236 {
237 16,
238 { 0x6F, 0xDC, 0x23, 0x38, 0xF2, 0x10, 0xFB, 0xD3, 0xC1, 0x8C, 0x02, 0xF6, 0xB4, 0x6A, 0xD5, 0xA8 },
239 { 0xDB, 0x29, 0xED, 0xB5, 0x5F, 0xB3, 0x60, 0x3A, 0x92, 0xA8, 0xEB, 0x9C, 0x6D, 0x9D, 0x3E, 0x8F },
240 { 0x78, 0xF3, 0x6F, 0xF8, 0x9E, 0xBB, 0x8C, 0x6A, 0xE8, 0x10, 0xF7, 0x00, 0x22, 0x15, 0x30, 0x3D }
241 },
242 {
243 16,
244 { 0x2C, 0x0C, 0x02, 0xEF, 0x6B, 0xC4, 0xF2, 0x0B, 0x2E, 0xB9, 0xE0, 0xBF, 0xD9, 0x36, 0xC2, 0x4E },
245 { 0x84, 0xE2, 0xFE, 0x64, 0xB1, 0xB9, 0xFE, 0x76, 0xA8, 0x3F, 0x45, 0xC7, 0x40, 0x7A, 0xAF, 0xEE },
246 { 0x2A, 0x08, 0xD6, 0xA2, 0x1C, 0x63, 0x08, 0xB0, 0xF8, 0xBC, 0xB3, 0xA1, 0x66, 0xF7, 0xAE, 0xCF }
247 },
248 {
249 16,
250 { 0x6F, 0x30, 0xF8, 0x9F, 0xDA, 0x6E, 0xA0, 0x91, 0x04, 0x0F, 0x6C, 0x8B, 0x7D, 0xF7, 0x2A, 0x4B },
251 { 0x65, 0xB6, 0xA6, 0xD0, 0x42, 0x14, 0x08, 0x60, 0x34, 0x8D, 0x37, 0x2F, 0x01, 0xF0, 0x46, 0xBE },
252 { 0x66, 0xAC, 0x0B, 0x62, 0x1D, 0x68, 0x11, 0xF5, 0x27, 0xB1, 0x13, 0x5D, 0xF3, 0x2A, 0xE9, 0x18 }
253 },
254 {
255 16,
256 { 0xCA, 0xA4, 0x16, 0xB7, 0x1C, 0x92, 0x2E, 0xAD, 0xEB, 0xA7, 0xDB, 0x69, 0x92, 0xCB, 0x35, 0xEF },
257 { 0x81, 0x6F, 0x8E, 0x4D, 0x96, 0xC6, 0xB3, 0x67, 0x83, 0xF5, 0x63, 0xC7, 0x20, 0x6D, 0x40, 0x23 },
258 { 0x44, 0xF7, 0x63, 0x62, 0xF0, 0x43, 0xBB, 0x67, 0x4A, 0x75, 0x12, 0x42, 0x46, 0x29, 0x28, 0x19 }
259 },
260 {
261 16,
262 { 0x6B, 0xCF, 0x22, 0x2F, 0xE0, 0x1B, 0xB0, 0xAA, 0xD8, 0x3C, 0x91, 0x99, 0x18, 0xB2, 0x28, 0xE8 },
263 { 0x7C, 0x37, 0xC7, 0xD0, 0xAC, 0x92, 0x29, 0xF1, 0x60, 0x82, 0x93, 0x89, 0xAA, 0x61, 0xAA, 0xA9 },
264 { 0xE5, 0x89, 0x1B, 0xB3, 0xFE, 0x8B, 0x0C, 0xA1, 0xA6, 0xC7, 0xBE, 0x12, 0x73, 0x0F, 0xC1, 0x19 }
265 },
266 {
267 16,
268 { 0xE6, 0xD0, 0xF1, 0x03, 0x2E, 0xDE, 0x70, 0x8D, 0xD8, 0x9E, 0x36, 0x5C, 0x05, 0x52, 0xE7, 0x0D },
269 { 0xE2, 0x42, 0xE7, 0x92, 0x0E, 0xF7, 0x82, 0xA2, 0xB8, 0x21, 0x8D, 0x26, 0xBA, 0x2D, 0xE6, 0x32 },
270 { 0x1E, 0xDD, 0x75, 0x22, 0xB9, 0x36, 0x8A, 0x0F, 0x32, 0xFD, 0xD4, 0x48, 0x65, 0x12, 0x5A, 0x2F }
271 }
272 };
273 symmetric_key key;
274 unsigned char tmp[2][16];
275 int err, i, y;
276
277 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
278 zeromem(&key, sizeof(key));
279 if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
280 return err;
281 }
282
283 noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key);
284 noekeon_ecb_decrypt(tmp[0], tmp[1], &key);
285 if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
286 #if 0
287 printf("\n\nTest %d failed\n", i);
288 if (XMEMCMP(tmp[0], tests[i].ct, 16)) {
289 printf("CT: ");
290 for (i = 0; i < 16; i++) {
291 printf("%02x ", tmp[0][i]);
292 }
293 printf("\n");
294 } else {
295 printf("PT: ");
296 for (i = 0; i < 16; i++) {
297 printf("%02x ", tmp[1][i]);
298 }
299 printf("\n");
300 }
301 #endif
302 return CRYPT_FAIL_TESTVECTOR;
303 }
304
305 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
306 for (y = 0; y < 16; y++) tmp[0][y] = 0;
307 for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key);
308 for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key);
309 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
310 }
311 return CRYPT_OK;
312 #endif
313 }
314
315 /** Terminate the context
316 @param skey The scheduled key
317 */
318 void noekeon_done(symmetric_key *skey)
319 {
320 }
321
322 /**
323 Gets suitable key size
324 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
325 @return CRYPT_OK if the input key size is acceptable.
326 */
327 int noekeon_keysize(int *keysize)
328 {
329 LTC_ARGCHK(keysize != NULL);
330 if (*keysize < 16) {
331 return CRYPT_INVALID_KEYSIZE;
332 } else {
333 *keysize = 16;
334 return CRYPT_OK;
335 }
336 }
337
338 #endif
339
340
341 /* $Source$ */
342 /* $Revision$ */
343 /* $Date$ */
+0
-362
libtom-src/ciphers/rc2.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**********************************************************************\
11 * To commemorate the 1996 RSA Data Security Conference, the following *
12 * code is released into the public domain by its author. Prost! *
13 * *
14 * This cipher uses 16-bit words and little-endian byte ordering. *
15 * I wonder which processor it was optimized for? *
16 * *
17 * Thanks to CodeView, SoftIce, and D86 for helping bring this code to *
18 * the public. *
19 \**********************************************************************/
20 #include <tomcrypt.h>
21
22 /**
23 @file rc2.c
24 Implementation of LTC_RC2
25 */
26
27 #ifdef LTC_RC2
28
29 const struct ltc_cipher_descriptor rc2_desc = {
30 "rc2",
31 12, 8, 128, 8, 16,
32 &rc2_setup,
33 &rc2_ecb_encrypt,
34 &rc2_ecb_decrypt,
35 &rc2_test,
36 &rc2_done,
37 &rc2_keysize,
38 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
39 };
40
41 /* 256-entry permutation table, probably derived somehow from pi */
42 static const unsigned char permute[256] = {
43 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
44 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
45 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
46 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
47 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
48 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
49 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
50 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
51 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
52 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
53 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
54 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
55 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
56 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
57 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
58 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
59 };
60
61 /**
62 Initialize the LTC_RC2 block cipher
63 @param key The symmetric key you wish to pass
64 @param keylen The key length in bytes
65 @param num_rounds The number of rounds desired (0 for default)
66 @param skey The key in as scheduled by this function.
67 @return CRYPT_OK if successful
68 */
69 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
70 {
71 unsigned *xkey = skey->rc2.xkey;
72 unsigned char tmp[128];
73 unsigned T8, TM;
74 int i, bits;
75
76 LTC_ARGCHK(key != NULL);
77 LTC_ARGCHK(skey != NULL);
78
79 if (keylen < 8 || keylen > 128) {
80 return CRYPT_INVALID_KEYSIZE;
81 }
82
83 if (num_rounds != 0 && num_rounds != 16) {
84 return CRYPT_INVALID_ROUNDS;
85 }
86
87 for (i = 0; i < keylen; i++) {
88 tmp[i] = key[i] & 255;
89 }
90
91 /* Phase 1: Expand input key to 128 bytes */
92 if (keylen < 128) {
93 for (i = keylen; i < 128; i++) {
94 tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255];
95 }
96 }
97
98 /* Phase 2 - reduce effective key size to "bits" */
99 bits = keylen<<3;
100 T8 = (unsigned)(bits+7)>>3;
101 TM = (255 >> (unsigned)(7 & -bits));
102 tmp[128 - T8] = permute[tmp[128 - T8] & TM];
103 for (i = 127 - T8; i >= 0; i--) {
104 tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]];
105 }
106
107 /* Phase 3 - copy to xkey in little-endian order */
108 for (i = 0; i < 64; i++) {
109 xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8);
110 }
111
112 #ifdef LTC_CLEAN_STACK
113 zeromem(tmp, sizeof(tmp));
114 #endif
115
116 return CRYPT_OK;
117 }
118
119 /**********************************************************************\
120 * Encrypt an 8-byte block of plaintext using the given key. *
121 \**********************************************************************/
122 /**
123 Encrypts a block of text with LTC_RC2
124 @param pt The input plaintext (8 bytes)
125 @param ct The output ciphertext (8 bytes)
126 @param skey The key as scheduled
127 @return CRYPT_OK if successful
128 */
129 #ifdef LTC_CLEAN_STACK
130 static int _rc2_ecb_encrypt( const unsigned char *pt,
131 unsigned char *ct,
132 symmetric_key *skey)
133 #else
134 int rc2_ecb_encrypt( const unsigned char *pt,
135 unsigned char *ct,
136 symmetric_key *skey)
137 #endif
138 {
139 unsigned *xkey;
140 unsigned x76, x54, x32, x10, i;
141
142 LTC_ARGCHK(pt != NULL);
143 LTC_ARGCHK(ct != NULL);
144 LTC_ARGCHK(skey != NULL);
145
146 xkey = skey->rc2.xkey;
147
148 x76 = ((unsigned)pt[7] << 8) + (unsigned)pt[6];
149 x54 = ((unsigned)pt[5] << 8) + (unsigned)pt[4];
150 x32 = ((unsigned)pt[3] << 8) + (unsigned)pt[2];
151 x10 = ((unsigned)pt[1] << 8) + (unsigned)pt[0];
152
153 for (i = 0; i < 16; i++) {
154 x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF;
155 x10 = ((x10 << 1) | (x10 >> 15));
156
157 x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF;
158 x32 = ((x32 << 2) | (x32 >> 14));
159
160 x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF;
161 x54 = ((x54 << 3) | (x54 >> 13));
162
163 x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF;
164 x76 = ((x76 << 5) | (x76 >> 11));
165
166 if (i == 4 || i == 10) {
167 x10 = (x10 + xkey[x76 & 63]) & 0xFFFF;
168 x32 = (x32 + xkey[x10 & 63]) & 0xFFFF;
169 x54 = (x54 + xkey[x32 & 63]) & 0xFFFF;
170 x76 = (x76 + xkey[x54 & 63]) & 0xFFFF;
171 }
172 }
173
174 ct[0] = (unsigned char)x10;
175 ct[1] = (unsigned char)(x10 >> 8);
176 ct[2] = (unsigned char)x32;
177 ct[3] = (unsigned char)(x32 >> 8);
178 ct[4] = (unsigned char)x54;
179 ct[5] = (unsigned char)(x54 >> 8);
180 ct[6] = (unsigned char)x76;
181 ct[7] = (unsigned char)(x76 >> 8);
182
183 return CRYPT_OK;
184 }
185
186 #ifdef LTC_CLEAN_STACK
187 int rc2_ecb_encrypt( const unsigned char *pt,
188 unsigned char *ct,
189 symmetric_key *skey)
190 {
191 int err = _rc2_ecb_encrypt(pt, ct, skey);
192 burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
193 return err;
194 }
195 #endif
196
197 /**********************************************************************\
198 * Decrypt an 8-byte block of ciphertext using the given key. *
199 \**********************************************************************/
200 /**
201 Decrypts a block of text with LTC_RC2
202 @param ct The input ciphertext (8 bytes)
203 @param pt The output plaintext (8 bytes)
204 @param skey The key as scheduled
205 @return CRYPT_OK if successful
206 */
207 #ifdef LTC_CLEAN_STACK
208 static int _rc2_ecb_decrypt( const unsigned char *ct,
209 unsigned char *pt,
210 symmetric_key *skey)
211 #else
212 int rc2_ecb_decrypt( const unsigned char *ct,
213 unsigned char *pt,
214 symmetric_key *skey)
215 #endif
216 {
217 unsigned x76, x54, x32, x10;
218 unsigned *xkey;
219 int i;
220
221 LTC_ARGCHK(pt != NULL);
222 LTC_ARGCHK(ct != NULL);
223 LTC_ARGCHK(skey != NULL);
224
225 xkey = skey->rc2.xkey;
226
227 x76 = ((unsigned)ct[7] << 8) + (unsigned)ct[6];
228 x54 = ((unsigned)ct[5] << 8) + (unsigned)ct[4];
229 x32 = ((unsigned)ct[3] << 8) + (unsigned)ct[2];
230 x10 = ((unsigned)ct[1] << 8) + (unsigned)ct[0];
231
232 for (i = 15; i >= 0; i--) {
233 if (i == 4 || i == 10) {
234 x76 = (x76 - xkey[x54 & 63]) & 0xFFFF;
235 x54 = (x54 - xkey[x32 & 63]) & 0xFFFF;
236 x32 = (x32 - xkey[x10 & 63]) & 0xFFFF;
237 x10 = (x10 - xkey[x76 & 63]) & 0xFFFF;
238 }
239
240 x76 = ((x76 << 11) | (x76 >> 5));
241 x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF;
242
243 x54 = ((x54 << 13) | (x54 >> 3));
244 x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF;
245
246 x32 = ((x32 << 14) | (x32 >> 2));
247 x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF;
248
249 x10 = ((x10 << 15) | (x10 >> 1));
250 x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF;
251 }
252
253 pt[0] = (unsigned char)x10;
254 pt[1] = (unsigned char)(x10 >> 8);
255 pt[2] = (unsigned char)x32;
256 pt[3] = (unsigned char)(x32 >> 8);
257 pt[4] = (unsigned char)x54;
258 pt[5] = (unsigned char)(x54 >> 8);
259 pt[6] = (unsigned char)x76;
260 pt[7] = (unsigned char)(x76 >> 8);
261
262 return CRYPT_OK;
263 }
264
265 #ifdef LTC_CLEAN_STACK
266 int rc2_ecb_decrypt( const unsigned char *ct,
267 unsigned char *pt,
268 symmetric_key *skey)
269 {
270 int err = _rc2_ecb_decrypt(ct, pt, skey);
271 burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
272 return err;
273 }
274 #endif
275
276 /**
277 Performs a self-test of the LTC_RC2 block cipher
278 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
279 */
280 int rc2_test(void)
281 {
282 #ifndef LTC_TEST
283 return CRYPT_NOP;
284 #else
285 static const struct {
286 int keylen;
287 unsigned char key[16], pt[8], ct[8];
288 } tests[] = {
289
290 { 8,
291 { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
293 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
294 { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 }
295
296 },
297 { 16,
298 { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
299 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 },
300 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
301 { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 }
302 }
303 };
304 int x, y, err;
305 symmetric_key skey;
306 unsigned char tmp[2][8];
307
308 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
309 zeromem(tmp, sizeof(tmp));
310 if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
311 return err;
312 }
313
314 rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey);
315 rc2_ecb_decrypt(tmp[0], tmp[1], &skey);
316
317 if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) {
318 return CRYPT_FAIL_TESTVECTOR;
319 }
320
321 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
322 for (y = 0; y < 8; y++) tmp[0][y] = 0;
323 for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey);
324 for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey);
325 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
326 }
327 return CRYPT_OK;
328 #endif
329 }
330
331 /** Terminate the context
332 @param skey The scheduled key
333 */
334 void rc2_done(symmetric_key *skey)
335 {
336 }
337
338 /**
339 Gets suitable key size
340 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
341 @return CRYPT_OK if the input key size is acceptable.
342 */
343 int rc2_keysize(int *keysize)
344 {
345 LTC_ARGCHK(keysize != NULL);
346 if (*keysize < 8) {
347 return CRYPT_INVALID_KEYSIZE;
348 } else if (*keysize > 128) {
349 *keysize = 128;
350 }
351 return CRYPT_OK;
352 }
353
354 #endif
355
356
357
358
359 /* $Source$ */
360 /* $Revision$ */
361 /* $Date$ */
+0
-322
libtom-src/ciphers/rc5.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file rc5.c
13 LTC_RC5 code by Tom St Denis
14 */
15
16 #include "tomcrypt.h"
17
18 #ifdef LTC_RC5
19
20 const struct ltc_cipher_descriptor rc5_desc =
21 {
22 "rc5",
23 2,
24 8, 128, 8, 12,
25 &rc5_setup,
26 &rc5_ecb_encrypt,
27 &rc5_ecb_decrypt,
28 &rc5_test,
29 &rc5_done,
30 &rc5_keysize,
31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
32 };
33
34 static const ulong32 stab[50] = {
35 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL,
36 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL,
37 0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL,
38 0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL,
39 0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL,
40 0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL, 0xe96a3d2fUL, 0x87a1b6e8UL, 0x25d930a1UL, 0xc410aa5aUL,
41 0x62482413UL, 0x007f9dccUL
42 };
43
44 /**
45 Initialize the LTC_RC5 block cipher
46 @param key The symmetric key you wish to pass
47 @param keylen The key length in bytes
48 @param num_rounds The number of rounds desired (0 for default)
49 @param skey The key in as scheduled by this function.
50 @return CRYPT_OK if successful
51 */
52 #ifdef LTC_CLEAN_STACK
53 static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
54 #else
55 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
56 #endif
57 {
58 ulong32 L[64], *S, A, B, i, j, v, s, t, l;
59
60 LTC_ARGCHK(skey != NULL);
61 LTC_ARGCHK(key != NULL);
62
63 /* test parameters */
64 if (num_rounds == 0) {
65 num_rounds = rc5_desc.default_rounds;
66 }
67
68 if (num_rounds < 12 || num_rounds > 24) {
69 return CRYPT_INVALID_ROUNDS;
70 }
71
72 /* key must be between 64 and 1024 bits */
73 if (keylen < 8 || keylen > 128) {
74 return CRYPT_INVALID_KEYSIZE;
75 }
76
77 skey->rc5.rounds = num_rounds;
78 S = skey->rc5.K;
79
80 /* copy the key into the L array */
81 for (A = i = j = 0; i < (ulong32)keylen; ) {
82 A = (A << 8) | ((ulong32)(key[i++] & 255));
83 if ((i & 3) == 0) {
84 L[j++] = BSWAP(A);
85 A = 0;
86 }
87 }
88
89 if ((keylen & 3) != 0) {
90 A <<= (ulong32)((8 * (4 - (keylen&3))));
91 L[j++] = BSWAP(A);
92 }
93
94 /* setup the S array */
95 t = (ulong32)(2 * (num_rounds + 1));
96 XMEMCPY(S, stab, t * sizeof(*S));
97
98 /* mix buffer */
99 s = 3 * MAX(t, j);
100 l = j;
101 for (A = B = i = j = v = 0; v < s; v++) {
102 A = S[i] = ROLc(S[i] + A + B, 3);
103 B = L[j] = ROL(L[j] + A + B, (A+B));
104 if (++i == t) { i = 0; }
105 if (++j == l) { j = 0; }
106 }
107 return CRYPT_OK;
108 }
109
110 #ifdef LTC_CLEAN_STACK
111 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
112 {
113 int x;
114 x = _rc5_setup(key, keylen, num_rounds, skey);
115 burn_stack(sizeof(ulong32) * 122 + sizeof(int));
116 return x;
117 }
118 #endif
119
120 /**
121 Encrypts a block of text with LTC_RC5
122 @param pt The input plaintext (8 bytes)
123 @param ct The output ciphertext (8 bytes)
124 @param skey The key as scheduled
125 @return CRYPT_OK if successful
126 */
127 #ifdef LTC_CLEAN_STACK
128 static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
129 #else
130 int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
131 #endif
132 {
133 ulong32 A, B, *K;
134 int r;
135 LTC_ARGCHK(skey != NULL);
136 LTC_ARGCHK(pt != NULL);
137 LTC_ARGCHK(ct != NULL);
138
139 LOAD32L(A, &pt[0]);
140 LOAD32L(B, &pt[4]);
141 A += skey->rc5.K[0];
142 B += skey->rc5.K[1];
143 K = skey->rc5.K + 2;
144
145 if ((skey->rc5.rounds & 1) == 0) {
146 for (r = 0; r < skey->rc5.rounds; r += 2) {
147 A = ROL(A ^ B, B) + K[0];
148 B = ROL(B ^ A, A) + K[1];
149 A = ROL(A ^ B, B) + K[2];
150 B = ROL(B ^ A, A) + K[3];
151 K += 4;
152 }
153 } else {
154 for (r = 0; r < skey->rc5.rounds; r++) {
155 A = ROL(A ^ B, B) + K[0];
156 B = ROL(B ^ A, A) + K[1];
157 K += 2;
158 }
159 }
160 STORE32L(A, &ct[0]);
161 STORE32L(B, &ct[4]);
162
163 return CRYPT_OK;
164 }
165
166 #ifdef LTC_CLEAN_STACK
167 int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
168 {
169 int err = _rc5_ecb_encrypt(pt, ct, skey);
170 burn_stack(sizeof(ulong32) * 2 + sizeof(int));
171 return err;
172 }
173 #endif
174
175 /**
176 Decrypts a block of text with LTC_RC5
177 @param ct The input ciphertext (8 bytes)
178 @param pt The output plaintext (8 bytes)
179 @param skey The key as scheduled
180 @return CRYPT_OK if successful
181 */
182 #ifdef LTC_CLEAN_STACK
183 static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
184 #else
185 int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
186 #endif
187 {
188 ulong32 A, B, *K;
189 int r;
190 LTC_ARGCHK(skey != NULL);
191 LTC_ARGCHK(pt != NULL);
192 LTC_ARGCHK(ct != NULL);
193
194 LOAD32L(A, &ct[0]);
195 LOAD32L(B, &ct[4]);
196 K = skey->rc5.K + (skey->rc5.rounds << 1);
197
198 if ((skey->rc5.rounds & 1) == 0) {
199 K -= 2;
200 for (r = skey->rc5.rounds - 1; r >= 0; r -= 2) {
201 B = ROR(B - K[3], A) ^ A;
202 A = ROR(A - K[2], B) ^ B;
203 B = ROR(B - K[1], A) ^ A;
204 A = ROR(A - K[0], B) ^ B;
205 K -= 4;
206 }
207 } else {
208 for (r = skey->rc5.rounds - 1; r >= 0; r--) {
209 B = ROR(B - K[1], A) ^ A;
210 A = ROR(A - K[0], B) ^ B;
211 K -= 2;
212 }
213 }
214 A -= skey->rc5.K[0];
215 B -= skey->rc5.K[1];
216 STORE32L(A, &pt[0]);
217 STORE32L(B, &pt[4]);
218
219 return CRYPT_OK;
220 }
221
222 #ifdef LTC_CLEAN_STACK
223 int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
224 {
225 int err = _rc5_ecb_decrypt(ct, pt, skey);
226 burn_stack(sizeof(ulong32) * 2 + sizeof(int));
227 return err;
228 }
229 #endif
230
231 /**
232 Performs a self-test of the LTC_RC5 block cipher
233 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
234 */
235 int rc5_test(void)
236 {
237 #ifndef LTC_TEST
238 return CRYPT_NOP;
239 #else
240 static const struct {
241 unsigned char key[16], pt[8], ct[8];
242 } tests[] = {
243 {
244 { 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51,
245 0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 },
246 { 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d },
247 { 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 }
248 },
249 {
250 { 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f,
251 0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 },
252 { 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 },
253 { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }
254 },
255 {
256 { 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f,
257 0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf },
258 { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 },
259 { 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc }
260 }
261 };
262 unsigned char tmp[2][8];
263 int x, y, err;
264 symmetric_key key;
265
266 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
267 /* setup key */
268 if ((err = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) {
269 return err;
270 }
271
272 /* encrypt and decrypt */
273 rc5_ecb_encrypt(tests[x].pt, tmp[0], &key);
274 rc5_ecb_decrypt(tmp[0], tmp[1], &key);
275
276 /* compare */
277 if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) {
278 return CRYPT_FAIL_TESTVECTOR;
279 }
280
281 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
282 for (y = 0; y < 8; y++) tmp[0][y] = 0;
283 for (y = 0; y < 1000; y++) rc5_ecb_encrypt(tmp[0], tmp[0], &key);
284 for (y = 0; y < 1000; y++) rc5_ecb_decrypt(tmp[0], tmp[0], &key);
285 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
286 }
287 return CRYPT_OK;
288 #endif
289 }
290
291 /** Terminate the context
292 @param skey The scheduled key
293 */
294 void rc5_done(symmetric_key *skey)
295 {
296 }
297
298 /**
299 Gets suitable key size
300 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
301 @return CRYPT_OK if the input key size is acceptable.
302 */
303 int rc5_keysize(int *keysize)
304 {
305 LTC_ARGCHK(keysize != NULL);
306 if (*keysize < 8) {
307 return CRYPT_INVALID_KEYSIZE;
308 } else if (*keysize > 128) {
309 *keysize = 128;
310 }
311 return CRYPT_OK;
312 }
313
314 #endif
315
316
317
318
319 /* $Source$ */
320 /* $Revision$ */
321 /* $Date$ */
+0
-348
libtom-src/ciphers/rc6.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file rc6.c
13 LTC_RC6 code by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_RC6
18
19 const struct ltc_cipher_descriptor rc6_desc =
20 {
21 "rc6",
22 3,
23 8, 128, 16, 20,
24 &rc6_setup,
25 &rc6_ecb_encrypt,
26 &rc6_ecb_decrypt,
27 &rc6_test,
28 &rc6_done,
29 &rc6_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 static const ulong32 stab[44] = {
34 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL,
35 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL,
36 0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL,
37 0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL,
38 0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL,
39 0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL };
40
41 /**
42 Initialize the LTC_RC6 block cipher
43 @param key The symmetric key you wish to pass
44 @param keylen The key length in bytes
45 @param num_rounds The number of rounds desired (0 for default)
46 @param skey The key in as scheduled by this function.
47 @return CRYPT_OK if successful
48 */
49 #ifdef LTC_CLEAN_STACK
50 static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
51 #else
52 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
53 #endif
54 {
55 ulong32 L[64], S[50], A, B, i, j, v, s, l;
56
57 LTC_ARGCHK(key != NULL);
58 LTC_ARGCHK(skey != NULL);
59
60 /* test parameters */
61 if (num_rounds != 0 && num_rounds != 20) {
62 return CRYPT_INVALID_ROUNDS;
63 }
64
65 /* key must be between 64 and 1024 bits */
66 if (keylen < 8 || keylen > 128) {
67 return CRYPT_INVALID_KEYSIZE;
68 }
69
70 /* copy the key into the L array */
71 for (A = i = j = 0; i < (ulong32)keylen; ) {
72 A = (A << 8) | ((ulong32)(key[i++] & 255));
73 if (!(i & 3)) {
74 L[j++] = BSWAP(A);
75 A = 0;
76 }
77 }
78
79 /* handle odd sized keys */
80 if (keylen & 3) {
81 A <<= (8 * (4 - (keylen&3)));
82 L[j++] = BSWAP(A);
83 }
84
85 /* setup the S array */
86 XMEMCPY(S, stab, 44 * sizeof(stab[0]));
87
88 /* mix buffer */
89 s = 3 * MAX(44, j);
90 l = j;
91 for (A = B = i = j = v = 0; v < s; v++) {
92 A = S[i] = ROLc(S[i] + A + B, 3);
93 B = L[j] = ROL(L[j] + A + B, (A+B));
94 if (++i == 44) { i = 0; }
95 if (++j == l) { j = 0; }
96 }
97
98 /* copy to key */
99 for (i = 0; i < 44; i++) {
100 skey->rc6.K[i] = S[i];
101 }
102 return CRYPT_OK;
103 }
104
105 #ifdef LTC_CLEAN_STACK
106 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
107 {
108 int x;
109 x = _rc6_setup(key, keylen, num_rounds, skey);
110 burn_stack(sizeof(ulong32) * 122);
111 return x;
112 }
113 #endif
114
115 /**
116 Encrypts a block of text with LTC_RC6
117 @param pt The input plaintext (16 bytes)
118 @param ct The output ciphertext (16 bytes)
119 @param skey The key as scheduled
120 */
121 #ifdef LTC_CLEAN_STACK
122 static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
123 #else
124 int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
125 #endif
126 {
127 ulong32 a,b,c,d,t,u, *K;
128 int r;
129
130 LTC_ARGCHK(skey != NULL);
131 LTC_ARGCHK(pt != NULL);
132 LTC_ARGCHK(ct != NULL);
133 LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]);
134
135 b += skey->rc6.K[0];
136 d += skey->rc6.K[1];
137
138 #define RND(a,b,c,d) \
139 t = (b * (b + b + 1)); t = ROLc(t, 5); \
140 u = (d * (d + d + 1)); u = ROLc(u, 5); \
141 a = ROL(a^t,u) + K[0]; \
142 c = ROL(c^u,t) + K[1]; K += 2;
143
144 K = skey->rc6.K + 2;
145 for (r = 0; r < 20; r += 4) {
146 RND(a,b,c,d);
147 RND(b,c,d,a);
148 RND(c,d,a,b);
149 RND(d,a,b,c);
150 }
151
152 #undef RND
153
154 a += skey->rc6.K[42];
155 c += skey->rc6.K[43];
156 STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
157 return CRYPT_OK;
158 }
159
160 #ifdef LTC_CLEAN_STACK
161 int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
162 {
163 int err = _rc6_ecb_encrypt(pt, ct, skey);
164 burn_stack(sizeof(ulong32) * 6 + sizeof(int));
165 return err;
166 }
167 #endif
168
169 /**
170 Decrypts a block of text with LTC_RC6
171 @param ct The input ciphertext (16 bytes)
172 @param pt The output plaintext (16 bytes)
173 @param skey The key as scheduled
174 */
175 #ifdef LTC_CLEAN_STACK
176 static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
177 #else
178 int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
179 #endif
180 {
181 ulong32 a,b,c,d,t,u, *K;
182 int r;
183
184 LTC_ARGCHK(skey != NULL);
185 LTC_ARGCHK(pt != NULL);
186 LTC_ARGCHK(ct != NULL);
187
188 LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]);
189 a -= skey->rc6.K[42];
190 c -= skey->rc6.K[43];
191
192 #define RND(a,b,c,d) \
193 t = (b * (b + b + 1)); t = ROLc(t, 5); \
194 u = (d * (d + d + 1)); u = ROLc(u, 5); \
195 c = ROR(c - K[1], t) ^ u; \
196 a = ROR(a - K[0], u) ^ t; K -= 2;
197
198 K = skey->rc6.K + 40;
199
200 for (r = 0; r < 20; r += 4) {
201 RND(d,a,b,c);
202 RND(c,d,a,b);
203 RND(b,c,d,a);
204 RND(a,b,c,d);
205 }
206
207 #undef RND
208
209 b -= skey->rc6.K[0];
210 d -= skey->rc6.K[1];
211 STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
212
213 return CRYPT_OK;
214 }
215
216 #ifdef LTC_CLEAN_STACK
217 int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
218 {
219 int err = _rc6_ecb_decrypt(ct, pt, skey);
220 burn_stack(sizeof(ulong32) * 6 + sizeof(int));
221 return err;
222 }
223 #endif
224
225 /**
226 Performs a self-test of the LTC_RC6 block cipher
227 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
228 */
229 int rc6_test(void)
230 {
231 #ifndef LTC_TEST
232 return CRYPT_NOP;
233 #else
234 static const struct {
235 int keylen;
236 unsigned char key[32], pt[16], ct[16];
237 } tests[] = {
238 {
239 16,
240 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
241 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
244 { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
245 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
246 { 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23,
247 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 }
248 },
249 {
250 24,
251 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
252 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
253 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
255 { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
256 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
257 { 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04,
258 0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 }
259 },
260 {
261 32,
262 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
263 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
264 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
265 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe },
266 { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
267 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
268 { 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89,
269 0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 }
270 }
271 };
272 unsigned char tmp[2][16];
273 int x, y, err;
274 symmetric_key key;
275
276 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
277 /* setup key */
278 if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
279 return err;
280 }
281
282 /* encrypt and decrypt */
283 rc6_ecb_encrypt(tests[x].pt, tmp[0], &key);
284 rc6_ecb_decrypt(tmp[0], tmp[1], &key);
285
286 /* compare */
287 if (XMEMCMP(tmp[0], tests[x].ct, 16) || XMEMCMP(tmp[1], tests[x].pt, 16)) {
288 #if 0
289 printf("\n\nFailed test %d\n", x);
290 if (XMEMCMP(tmp[0], tests[x].ct, 16)) {
291 printf("Ciphertext: ");
292 for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]);
293 printf("\nExpected : ");
294 for (y = 0; y < 16; y++) printf("%02x ", tests[x].ct[y]);
295 printf("\n");
296 }
297 if (XMEMCMP(tmp[1], tests[x].pt, 16)) {
298 printf("Plaintext: ");
299 for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]);
300 printf("\nExpected : ");
301 for (y = 0; y < 16; y++) printf("%02x ", tests[x].pt[y]);
302 printf("\n");
303 }
304 #endif
305 return CRYPT_FAIL_TESTVECTOR;
306 }
307
308 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
309 for (y = 0; y < 16; y++) tmp[0][y] = 0;
310 for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key);
311 for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key);
312 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
313 }
314 return CRYPT_OK;
315 #endif
316 }
317
318 /** Terminate the context
319 @param skey The scheduled key
320 */
321 void rc6_done(symmetric_key *skey)
322 {
323 }
324
325 /**
326 Gets suitable key size
327 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
328 @return CRYPT_OK if the input key size is acceptable.
329 */
330 int rc6_keysize(int *keysize)
331 {
332 LTC_ARGCHK(keysize != NULL);
333 if (*keysize < 8) {
334 return CRYPT_INVALID_KEYSIZE;
335 } else if (*keysize > 128) {
336 *keysize = 128;
337 }
338 return CRYPT_OK;
339 }
340
341 #endif /*LTC_RC6*/
342
343
344
345 /* $Source$ */
346 /* $Revision$ */
347 /* $Date$ */
+0
-491
libtom-src/ciphers/safer/safer.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /*******************************************************************************
12 *
13 * FILE: safer.c
14 *
15 * LTC_DESCRIPTION: block-cipher algorithm LTC_SAFER (Secure And Fast Encryption
16 * Routine) in its four versions: LTC_SAFER K-64, LTC_SAFER K-128,
17 * LTC_SAFER SK-64 and LTC_SAFER SK-128.
18 *
19 * AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
20 * Signal and Information Processing Laboratory
21 * Swiss Federal Institute of Technology
22 * CH-8092 Zuerich, Switzerland
23 *
24 * DATE: September 9, 1995
25 *
26 * CHANGE HISTORY:
27 *
28 *******************************************************************************/
29
30 #include <tomcrypt.h>
31
32 #ifdef LTC_SAFER
33
34 const struct ltc_cipher_descriptor
35 safer_k64_desc = {
36 "safer-k64",
37 8, 8, 8, 8, LTC_SAFER_K64_DEFAULT_NOF_ROUNDS,
38 &safer_k64_setup,
39 &safer_ecb_encrypt,
40 &safer_ecb_decrypt,
41 &safer_k64_test,
42 &safer_done,
43 &safer_64_keysize,
44 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
45 },
46
47 safer_sk64_desc = {
48 "safer-sk64",
49 9, 8, 8, 8, LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS,
50 &safer_sk64_setup,
51 &safer_ecb_encrypt,
52 &safer_ecb_decrypt,
53 &safer_sk64_test,
54 &safer_done,
55 &safer_64_keysize,
56 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
57 },
58
59 safer_k128_desc = {
60 "safer-k128",
61 10, 16, 16, 8, LTC_SAFER_K128_DEFAULT_NOF_ROUNDS,
62 &safer_k128_setup,
63 &safer_ecb_encrypt,
64 &safer_ecb_decrypt,
65 &safer_sk128_test,
66 &safer_done,
67 &safer_128_keysize,
68 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
69 },
70
71 safer_sk128_desc = {
72 "safer-sk128",
73 11, 16, 16, 8, LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS,
74 &safer_sk128_setup,
75 &safer_ecb_encrypt,
76 &safer_ecb_decrypt,
77 &safer_sk128_test,
78 &safer_done,
79 &safer_128_keysize,
80 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
81 };
82
83 /******************* Constants ************************************************/
84 /* #define TAB_LEN 256 */
85
86 /******************* Assertions ***********************************************/
87
88 /******************* Macros ***************************************************/
89 #define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\
90 |(unsigned int)((x) & 0xFF) >> (8 - (n))))
91 #define EXP(x) safer_ebox[(x) & 0xFF]
92 #define LOG(x) safer_lbox[(x) & 0xFF]
93 #define PHT(x, y) { y += x; x += y; }
94 #define IPHT(x, y) { x -= y; y -= x; }
95
96 /******************* Types ****************************************************/
97 extern const unsigned char safer_ebox[], safer_lbox[];
98
99 #ifdef LTC_CLEAN_STACK
100 static void _Safer_Expand_Userkey(const unsigned char *userkey_1,
101 const unsigned char *userkey_2,
102 unsigned int nof_rounds,
103 int strengthened,
104 safer_key_t key)
105 #else
106 static void Safer_Expand_Userkey(const unsigned char *userkey_1,
107 const unsigned char *userkey_2,
108 unsigned int nof_rounds,
109 int strengthened,
110 safer_key_t key)
111 #endif
112 { unsigned int i, j, k;
113 unsigned char ka[LTC_SAFER_BLOCK_LEN + 1];
114 unsigned char kb[LTC_SAFER_BLOCK_LEN + 1];
115
116 if (LTC_SAFER_MAX_NOF_ROUNDS < nof_rounds)
117 nof_rounds = LTC_SAFER_MAX_NOF_ROUNDS;
118 *key++ = (unsigned char)nof_rounds;
119 ka[LTC_SAFER_BLOCK_LEN] = (unsigned char)0;
120 kb[LTC_SAFER_BLOCK_LEN] = (unsigned char)0;
121 k = 0;
122 for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
123 ka[j] = ROL8(userkey_1[j], 5);
124 ka[LTC_SAFER_BLOCK_LEN] ^= ka[j];
125 kb[j] = *key++ = userkey_2[j];
126 kb[LTC_SAFER_BLOCK_LEN] ^= kb[j];
127 }
128 for (i = 1; i <= nof_rounds; i++) {
129 for (j = 0; j < LTC_SAFER_BLOCK_LEN + 1; j++) {
130 ka[j] = ROL8(ka[j], 6);
131 kb[j] = ROL8(kb[j], 6);
132 }
133 if (strengthened) {
134 k = 2 * i - 1;
135 while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; }
136 }
137 for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
138 if (strengthened) {
139 *key++ = (ka[k]
140 + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF;
141 if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; }
142 } else {
143 *key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF;
144 }
145 }
146 if (strengthened) {
147 k = 2 * i;
148 while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; }
149 }
150 for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
151 if (strengthened) {
152 *key++ = (kb[k]
153 + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF;
154 if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; }
155 } else {
156 *key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF;
157 }
158 }
159 }
160
161 #ifdef LTC_CLEAN_STACK
162 zeromem(ka, sizeof(ka));
163 zeromem(kb, sizeof(kb));
164 #endif
165 }
166
167 #ifdef LTC_CLEAN_STACK
168 static void Safer_Expand_Userkey(const unsigned char *userkey_1,
169 const unsigned char *userkey_2,
170 unsigned int nof_rounds,
171 int strengthened,
172 safer_key_t key)
173 {
174 _Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key);
175 burn_stack(sizeof(unsigned char) * (2 * (LTC_SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2);
176 }
177 #endif
178
179 int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
180 {
181 LTC_ARGCHK(key != NULL);
182 LTC_ARGCHK(skey != NULL);
183
184 if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
185 return CRYPT_INVALID_ROUNDS;
186 }
187
188 if (keylen != 8) {
189 return CRYPT_INVALID_KEYSIZE;
190 }
191
192 Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key);
193 return CRYPT_OK;
194 }
195
196 int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
197 {
198 LTC_ARGCHK(key != NULL);
199 LTC_ARGCHK(skey != NULL);
200
201 if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
202 return CRYPT_INVALID_ROUNDS;
203 }
204
205 if (keylen != 8) {
206 return CRYPT_INVALID_KEYSIZE;
207 }
208
209 Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key);
210 return CRYPT_OK;
211 }
212
213 int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
214 {
215 LTC_ARGCHK(key != NULL);
216 LTC_ARGCHK(skey != NULL);
217
218 if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
219 return CRYPT_INVALID_ROUNDS;
220 }
221
222 if (keylen != 16) {
223 return CRYPT_INVALID_KEYSIZE;
224 }
225
226 Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key);
227 return CRYPT_OK;
228 }
229
230 int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
231 {
232 LTC_ARGCHK(key != NULL);
233 LTC_ARGCHK(skey != NULL);
234
235 if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
236 return CRYPT_INVALID_ROUNDS;
237 }
238
239 if (keylen != 16) {
240 return CRYPT_INVALID_KEYSIZE;
241 }
242
243 Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key);
244 return CRYPT_OK;
245 }
246
247 #ifdef LTC_CLEAN_STACK
248 static int _safer_ecb_encrypt(const unsigned char *block_in,
249 unsigned char *block_out,
250 symmetric_key *skey)
251 #else
252 int safer_ecb_encrypt(const unsigned char *block_in,
253 unsigned char *block_out,
254 symmetric_key *skey)
255 #endif
256 { unsigned char a, b, c, d, e, f, g, h, t;
257 unsigned int round;
258 unsigned char *key;
259
260 LTC_ARGCHK(block_in != NULL);
261 LTC_ARGCHK(block_out != NULL);
262 LTC_ARGCHK(skey != NULL);
263
264 key = skey->safer.key;
265 a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
266 e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
267 if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS;
268 while(round-- > 0)
269 {
270 a ^= *++key; b += *++key; c += *++key; d ^= *++key;
271 e ^= *++key; f += *++key; g += *++key; h ^= *++key;
272 a = EXP(a) + *++key; b = LOG(b) ^ *++key;
273 c = LOG(c) ^ *++key; d = EXP(d) + *++key;
274 e = EXP(e) + *++key; f = LOG(f) ^ *++key;
275 g = LOG(g) ^ *++key; h = EXP(h) + *++key;
276 PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h);
277 PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h);
278 PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h);
279 t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t;
280 }
281 a ^= *++key; b += *++key; c += *++key; d ^= *++key;
282 e ^= *++key; f += *++key; g += *++key; h ^= *++key;
283 block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
284 block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
285 block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
286 block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
287 return CRYPT_OK;
288 }
289
290 #ifdef LTC_CLEAN_STACK
291 int safer_ecb_encrypt(const unsigned char *block_in,
292 unsigned char *block_out,
293 symmetric_key *skey)
294 {
295 int err = _safer_ecb_encrypt(block_in, block_out, skey);
296 burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
297 return err;
298 }
299 #endif
300
301 #ifdef LTC_CLEAN_STACK
302 static int _safer_ecb_decrypt(const unsigned char *block_in,
303 unsigned char *block_out,
304 symmetric_key *skey)
305 #else
306 int safer_ecb_decrypt(const unsigned char *block_in,
307 unsigned char *block_out,
308 symmetric_key *skey)
309 #endif
310 { unsigned char a, b, c, d, e, f, g, h, t;
311 unsigned int round;
312 unsigned char *key;
313
314 LTC_ARGCHK(block_in != NULL);
315 LTC_ARGCHK(block_out != NULL);
316 LTC_ARGCHK(skey != NULL);
317
318 key = skey->safer.key;
319 a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
320 e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
321 if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS;
322 key += LTC_SAFER_BLOCK_LEN * (1 + 2 * round);
323 h ^= *key; g -= *--key; f -= *--key; e ^= *--key;
324 d ^= *--key; c -= *--key; b -= *--key; a ^= *--key;
325 while (round--)
326 {
327 t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t;
328 IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h);
329 IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h);
330 IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h);
331 h -= *--key; g ^= *--key; f ^= *--key; e -= *--key;
332 d -= *--key; c ^= *--key; b ^= *--key; a -= *--key;
333 h = LOG(h) ^ *--key; g = EXP(g) - *--key;
334 f = EXP(f) - *--key; e = LOG(e) ^ *--key;
335 d = LOG(d) ^ *--key; c = EXP(c) - *--key;
336 b = EXP(b) - *--key; a = LOG(a) ^ *--key;
337 }
338 block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
339 block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
340 block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
341 block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
342 return CRYPT_OK;
343 }
344
345 #ifdef LTC_CLEAN_STACK
346 int safer_ecb_decrypt(const unsigned char *block_in,
347 unsigned char *block_out,
348 symmetric_key *skey)
349 {
350 int err = _safer_ecb_decrypt(block_in, block_out, skey);
351 burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
352 return err;
353 }
354 #endif
355
356 int safer_64_keysize(int *keysize)
357 {
358 LTC_ARGCHK(keysize != NULL);
359 if (*keysize < 8) {
360 return CRYPT_INVALID_KEYSIZE;
361 } else {
362 *keysize = 8;
363 return CRYPT_OK;
364 }
365 }
366
367 int safer_128_keysize(int *keysize)
368 {
369 LTC_ARGCHK(keysize != NULL);
370 if (*keysize < 16) {
371 return CRYPT_INVALID_KEYSIZE;
372 } else {
373 *keysize = 16;
374 return CRYPT_OK;
375 }
376 }
377
378 int safer_k64_test(void)
379 {
380 #ifndef LTC_TEST
381 return CRYPT_NOP;
382 #else
383 static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
384 k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 },
385 k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 };
386
387 symmetric_key skey;
388 unsigned char buf[2][8];
389 int err;
390
391 /* test K64 */
392 if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) {
393 return err;
394 }
395 safer_ecb_encrypt(k64_pt, buf[0], &skey);
396 safer_ecb_decrypt(buf[0], buf[1], &skey);
397
398 if (XMEMCMP(buf[0], k64_ct, 8) != 0 || XMEMCMP(buf[1], k64_pt, 8) != 0) {
399 return CRYPT_FAIL_TESTVECTOR;
400 }
401
402 return CRYPT_OK;
403 #endif
404 }
405
406
407 int safer_sk64_test(void)
408 {
409 #ifndef LTC_TEST
410 return CRYPT_NOP;
411 #else
412 static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
413 sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
414 sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 };
415
416 symmetric_key skey;
417 unsigned char buf[2][8];
418 int err, y;
419
420 /* test SK64 */
421 if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) {
422 return err;
423 }
424
425 safer_ecb_encrypt(sk64_pt, buf[0], &skey);
426 safer_ecb_decrypt(buf[0], buf[1], &skey);
427
428 if (XMEMCMP(buf[0], sk64_ct, 8) != 0 || XMEMCMP(buf[1], sk64_pt, 8) != 0) {
429 return CRYPT_FAIL_TESTVECTOR;
430 }
431
432 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
433 for (y = 0; y < 8; y++) buf[0][y] = 0;
434 for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey);
435 for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey);
436 for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
437
438 return CRYPT_OK;
439 #endif
440 }
441
442 /** Terminate the context
443 @param skey The scheduled key
444 */
445 void safer_done(symmetric_key *skey)
446 {
447 }
448
449 int safer_sk128_test(void)
450 {
451 #ifndef LTC_TEST
452 return CRYPT_NOP;
453 #else
454 static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
455 sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8,
456 0, 0, 0, 0, 0, 0, 0, 0 },
457 sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 };
458
459 symmetric_key skey;
460 unsigned char buf[2][8];
461 int err, y;
462
463 /* test SK128 */
464 if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) {
465 return err;
466 }
467 safer_ecb_encrypt(sk128_pt, buf[0], &skey);
468 safer_ecb_decrypt(buf[0], buf[1], &skey);
469
470 if (XMEMCMP(buf[0], sk128_ct, 8) != 0 || XMEMCMP(buf[1], sk128_pt, 8) != 0) {
471 return CRYPT_FAIL_TESTVECTOR;
472 }
473
474 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
475 for (y = 0; y < 8; y++) buf[0][y] = 0;
476 for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey);
477 for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey);
478 for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
479 return CRYPT_OK;
480 #endif
481 }
482
483 #endif
484
485
486
487
488 /* $Source$ */
489 /* $Revision$ */
490 /* $Date$ */
+0
-68
libtom-src/ciphers/safer/safer_tab.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file safer_tab.c
13 Tables for LTC_SAFER block ciphers
14 */
15
16 #include "tomcrypt.h"
17
18 #if defined(LTC_SAFERP) || defined(LTC_SAFER)
19
20 /* This is the box defined by ebox[x] = 45^x mod 257.
21 * Its assumed that the value "256" corresponds to zero. */
22 const unsigned char safer_ebox[256] = {
23 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63,
24 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247,
25 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177,
26 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131,
27 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20,
28 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160,
29 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252,
30 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217,
31 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194,
32 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10,
33 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80,
34 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126,
35 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237,
36 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97,
37 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5,
38 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40
39 };
40
41 /* This is the inverse of ebox or the base 45 logarithm */
42 const unsigned char safer_lbox[256] = {
43 128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248,
44 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130,
45 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37,
46 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15,
47 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198,
48 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84,
49 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188,
50 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217,
51 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158,
52 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42,
53 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219,
54 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29,
55 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14,
56 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104,
57 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66,
58 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48
59 };
60
61 #endif
62
63
64
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
+0
-559
libtom-src/ciphers/safer/saferp.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file saferp.c
13 LTC_SAFER+ Implementation by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_SAFERP
18
19 const struct ltc_cipher_descriptor saferp_desc =
20 {
21 "safer+",
22 4,
23 16, 32, 16, 8,
24 &saferp_setup,
25 &saferp_ecb_encrypt,
26 &saferp_ecb_decrypt,
27 &saferp_test,
28 &saferp_done,
29 &saferp_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 /* ROUND(b,i)
34 *
35 * This is one forward key application. Note the basic form is
36 * key addition, substitution, key addition. The safer_ebox and safer_lbox
37 * are the exponentiation box and logarithm boxes respectively.
38 * The value of 'i' is the current round number which allows this
39 * function to be unrolled massively. Most of LTC_SAFER+'s speed
40 * comes from not having to compute indirect accesses into the
41 * array of 16 bytes b[0..15] which is the block of data
42 */
43
44 extern const unsigned char safer_ebox[], safer_lbox[];
45
46 #define ROUND(b, i) \
47 b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \
48 b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \
49 b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \
50 b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \
51 b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \
52 b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \
53 b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \
54 b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \
55 b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \
56 b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \
57 b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \
58 b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \
59 b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \
60 b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \
61 b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \
62 b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255;
63
64 /* This is one inverse key application */
65 #define iROUND(b, i) \
66 b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \
67 b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \
68 b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \
69 b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \
70 b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \
71 b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \
72 b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \
73 b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \
74 b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \
75 b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \
76 b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \
77 b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \
78 b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \
79 b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \
80 b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \
81 b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15];
82
83 /* This is a forward single layer PHT transform. */
84 #define PHT(b) \
85 b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \
86 b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \
87 b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \
88 b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \
89 b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \
90 b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \
91 b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \
92 b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255;
93
94 /* This is an inverse single layer PHT transform */
95 #define iPHT(b) \
96 b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \
97 b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \
98 b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \
99 b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \
100 b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \
101 b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \
102 b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \
103 b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \
104
105 /* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */
106 #define SHUF(b, b2) \
107 b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \
108 b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \
109 b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \
110 b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3];
111
112 /* This is the inverse shuffle. It takes from b and gives to b2 */
113 #define iSHUF(b, b2) \
114 b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \
115 b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \
116 b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \
117 b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3];
118
119 /* The complete forward Linear Transform layer.
120 * Note that alternating usage of b and b2.
121 * Each round of LT starts in 'b' and ends in 'b2'.
122 */
123 #define LT(b, b2) \
124 PHT(b); SHUF(b, b2); \
125 PHT(b2); SHUF(b2, b); \
126 PHT(b); SHUF(b, b2); \
127 PHT(b2);
128
129 /* This is the inverse linear transform layer. */
130 #define iLT(b, b2) \
131 iPHT(b); \
132 iSHUF(b, b2); iPHT(b2); \
133 iSHUF(b2, b); iPHT(b); \
134 iSHUF(b, b2); iPHT(b2);
135
136 #ifdef LTC_SMALL_CODE
137
138 static void _round(unsigned char *b, int i, symmetric_key *skey)
139 {
140 ROUND(b, i);
141 }
142
143 static void _iround(unsigned char *b, int i, symmetric_key *skey)
144 {
145 iROUND(b, i);
146 }
147
148 static void _lt(unsigned char *b, unsigned char *b2)
149 {
150 LT(b, b2);
151 }
152
153 static void _ilt(unsigned char *b, unsigned char *b2)
154 {
155 iLT(b, b2);
156 }
157
158 #undef ROUND
159 #define ROUND(b, i) _round(b, i, skey)
160
161 #undef iROUND
162 #define iROUND(b, i) _iround(b, i, skey)
163
164 #undef LT
165 #define LT(b, b2) _lt(b, b2)
166
167 #undef iLT
168 #define iLT(b, b2) _ilt(b, b2)
169
170 #endif
171
172 /* These are the 33, 128-bit bias words for the key schedule */
173 static const unsigned char safer_bias[33][16] = {
174 { 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100},
175 { 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61},
176 { 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160},
177 { 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148},
178 { 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143},
179 { 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202},
180 { 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44},
181 { 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51},
182 { 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56},
183 { 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215},
184 { 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210},
185 { 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53},
186 { 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244},
187 { 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131},
188 { 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241},
189 { 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172},
190 { 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239},
191 { 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202},
192 { 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246},
193 { 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152},
194 { 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236},
195 { 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150},
196 { 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30},
197 { 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6},
198 { 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104},
199 { 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175},
200 { 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35},
201 { 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7},
202 { 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207},
203 { 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247},
204 { 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255},
205 { 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}};
206
207 /**
208 Initialize the LTC_SAFER+ block cipher
209 @param key The symmetric key you wish to pass
210 @param keylen The key length in bytes
211 @param num_rounds The number of rounds desired (0 for default)
212 @param skey The key in as scheduled by this function.
213 @return CRYPT_OK if successful
214 */
215 int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
216 {
217 unsigned x, y, z;
218 unsigned char t[33];
219 static const int rounds[3] = { 8, 12, 16 };
220
221 LTC_ARGCHK(key != NULL);
222 LTC_ARGCHK(skey != NULL);
223
224 /* check arguments */
225 if (keylen != 16 && keylen != 24 && keylen != 32) {
226 return CRYPT_INVALID_KEYSIZE;
227 }
228
229 /* Is the number of rounds valid? Either use zero for default or
230 * 8,12,16 rounds for 16,24,32 byte keys
231 */
232 if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) {
233 return CRYPT_INVALID_ROUNDS;
234 }
235
236 /* 128 bit key version */
237 if (keylen == 16) {
238 /* copy key into t */
239 for (x = y = 0; x < 16; x++) {
240 t[x] = key[x];
241 y ^= key[x];
242 }
243 t[16] = y;
244
245 /* make round keys */
246 for (x = 0; x < 16; x++) {
247 skey->saferp.K[0][x] = t[x];
248 }
249
250 /* make the 16 other keys as a transformation of the first key */
251 for (x = 1; x < 17; x++) {
252 /* rotate 3 bits each */
253 for (y = 0; y < 17; y++) {
254 t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
255 }
256
257 /* select and add */
258 z = x;
259 for (y = 0; y < 16; y++) {
260 skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
261 if (++z == 17) { z = 0; }
262 }
263 }
264 skey->saferp.rounds = 8;
265 } else if (keylen == 24) {
266 /* copy key into t */
267 for (x = y = 0; x < 24; x++) {
268 t[x] = key[x];
269 y ^= key[x];
270 }
271 t[24] = y;
272
273 /* make round keys */
274 for (x = 0; x < 16; x++) {
275 skey->saferp.K[0][x] = t[x];
276 }
277
278 for (x = 1; x < 25; x++) {
279 /* rotate 3 bits each */
280 for (y = 0; y < 25; y++) {
281 t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
282 }
283
284 /* select and add */
285 z = x;
286 for (y = 0; y < 16; y++) {
287 skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
288 if (++z == 25) { z = 0; }
289 }
290 }
291 skey->saferp.rounds = 12;
292 } else {
293 /* copy key into t */
294 for (x = y = 0; x < 32; x++) {
295 t[x] = key[x];
296 y ^= key[x];
297 }
298 t[32] = y;
299
300 /* make round keys */
301 for (x = 0; x < 16; x++) {
302 skey->saferp.K[0][x] = t[x];
303 }
304
305 for (x = 1; x < 33; x++) {
306 /* rotate 3 bits each */
307 for (y = 0; y < 33; y++) {
308 t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
309 }
310
311 /* select and add */
312 z = x;
313 for (y = 0; y < 16; y++) {
314 skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
315 if (++z == 33) { z = 0; }
316 }
317 }
318 skey->saferp.rounds = 16;
319 }
320 #ifdef LTC_CLEAN_STACK
321 zeromem(t, sizeof(t));
322 #endif
323 return CRYPT_OK;
324 }
325
326 /**
327 Encrypts a block of text with LTC_SAFER+
328 @param pt The input plaintext (16 bytes)
329 @param ct The output ciphertext (16 bytes)
330 @param skey The key as scheduled
331 @return CRYPT_OK if successful
332 */
333 int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
334 {
335 unsigned char b[16];
336 int x;
337
338 LTC_ARGCHK(pt != NULL);
339 LTC_ARGCHK(ct != NULL);
340 LTC_ARGCHK(skey != NULL);
341
342 /* do eight rounds */
343 for (x = 0; x < 16; x++) {
344 b[x] = pt[x];
345 }
346 ROUND(b, 0); LT(b, ct);
347 ROUND(ct, 2); LT(ct, b);
348 ROUND(b, 4); LT(b, ct);
349 ROUND(ct, 6); LT(ct, b);
350 ROUND(b, 8); LT(b, ct);
351 ROUND(ct, 10); LT(ct, b);
352 ROUND(b, 12); LT(b, ct);
353 ROUND(ct, 14); LT(ct, b);
354 /* 192-bit key? */
355 if (skey->saferp.rounds > 8) {
356 ROUND(b, 16); LT(b, ct);
357 ROUND(ct, 18); LT(ct, b);
358 ROUND(b, 20); LT(b, ct);
359 ROUND(ct, 22); LT(ct, b);
360 }
361 /* 256-bit key? */
362 if (skey->saferp.rounds > 12) {
363 ROUND(b, 24); LT(b, ct);
364 ROUND(ct, 26); LT(ct, b);
365 ROUND(b, 28); LT(b, ct);
366 ROUND(ct, 30); LT(ct, b);
367 }
368 ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
369 ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
370 ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
371 ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
372 ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
373 ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
374 ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
375 ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
376 ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
377 ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
378 ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
379 ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
380 ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
381 ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
382 ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
383 ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
384 #ifdef LTC_CLEAN_STACK
385 zeromem(b, sizeof(b));
386 #endif
387 return CRYPT_OK;
388 }
389
390 /**
391 Decrypts a block of text with LTC_SAFER+
392 @param ct The input ciphertext (16 bytes)
393 @param pt The output plaintext (16 bytes)
394 @param skey The key as scheduled
395 @return CRYPT_OK if successful
396 */
397 int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
398 {
399 unsigned char b[16];
400 int x;
401
402 LTC_ARGCHK(pt != NULL);
403 LTC_ARGCHK(ct != NULL);
404 LTC_ARGCHK(skey != NULL);
405
406 /* do eight rounds */
407 b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
408 b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
409 b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
410 b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
411 b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
412 b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
413 b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
414 b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
415 b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
416 b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
417 b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
418 b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
419 b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
420 b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
421 b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
422 b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
423 /* 256-bit key? */
424 if (skey->saferp.rounds > 12) {
425 iLT(b, pt); iROUND(pt, 30);
426 iLT(pt, b); iROUND(b, 28);
427 iLT(b, pt); iROUND(pt, 26);
428 iLT(pt, b); iROUND(b, 24);
429 }
430 /* 192-bit key? */
431 if (skey->saferp.rounds > 8) {
432 iLT(b, pt); iROUND(pt, 22);
433 iLT(pt, b); iROUND(b, 20);
434 iLT(b, pt); iROUND(pt, 18);
435 iLT(pt, b); iROUND(b, 16);
436 }
437 iLT(b, pt); iROUND(pt, 14);
438 iLT(pt, b); iROUND(b, 12);
439 iLT(b, pt); iROUND(pt,10);
440 iLT(pt, b); iROUND(b, 8);
441 iLT(b, pt); iROUND(pt,6);
442 iLT(pt, b); iROUND(b, 4);
443 iLT(b, pt); iROUND(pt,2);
444 iLT(pt, b); iROUND(b, 0);
445 for (x = 0; x < 16; x++) {
446 pt[x] = b[x];
447 }
448 #ifdef LTC_CLEAN_STACK
449 zeromem(b, sizeof(b));
450 #endif
451 return CRYPT_OK;
452 }
453
454 /**
455 Performs a self-test of the LTC_SAFER+ block cipher
456 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
457 */
458 int saferp_test(void)
459 {
460 #ifndef LTC_TEST
461 return CRYPT_NOP;
462 #else
463 static const struct {
464 int keylen;
465 unsigned char key[32], pt[16], ct[16];
466 } tests[] = {
467 {
468 16,
469 { 41, 35, 190, 132, 225, 108, 214, 174,
470 82, 144, 73, 241, 241, 187, 233, 235 },
471 { 179, 166, 219, 60, 135, 12, 62, 153,
472 36, 94, 13, 28, 6, 183, 71, 222 },
473 { 224, 31, 182, 10, 12, 255, 84, 70,
474 127, 13, 89, 249, 9, 57, 165, 220 }
475 }, {
476 24,
477 { 72, 211, 143, 117, 230, 217, 29, 42,
478 229, 192, 247, 43, 120, 129, 135, 68,
479 14, 95, 80, 0, 212, 97, 141, 190 },
480 { 123, 5, 21, 7, 59, 51, 130, 31,
481 24, 112, 146, 218, 100, 84, 206, 177 },
482 { 92, 136, 4, 63, 57, 95, 100, 0,
483 150, 130, 130, 16, 193, 111, 219, 133 }
484 }, {
485 32,
486 { 243, 168, 141, 254, 190, 242, 235, 113,
487 255, 160, 208, 59, 117, 6, 140, 126,
488 135, 120, 115, 77, 208, 190, 130, 190,
489 219, 194, 70, 65, 43, 140, 250, 48 },
490 { 127, 112, 240, 167, 84, 134, 50, 149,
491 170, 91, 104, 19, 11, 230, 252, 245 },
492 { 88, 11, 25, 36, 172, 229, 202, 213,
493 170, 65, 105, 153, 220, 104, 153, 138 }
494 }
495 };
496
497 unsigned char tmp[2][16];
498 symmetric_key skey;
499 int err, i, y;
500
501 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
502 if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) {
503 return err;
504 }
505 saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey);
506 saferp_ecb_decrypt(tmp[0], tmp[1], &skey);
507
508 /* compare */
509 if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
510 return CRYPT_FAIL_TESTVECTOR;
511 }
512
513 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
514 for (y = 0; y < 16; y++) tmp[0][y] = 0;
515 for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey);
516 for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey);
517 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
518 }
519
520 return CRYPT_OK;
521 #endif
522 }
523
524 /** Terminate the context
525 @param skey The scheduled key
526 */
527 void saferp_done(symmetric_key *skey)
528 {
529 }
530
531 /**
532 Gets suitable key size
533 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
534 @return CRYPT_OK if the input key size is acceptable.
535 */
536 int saferp_keysize(int *keysize)
537 {
538 LTC_ARGCHK(keysize != NULL);
539
540 if (*keysize < 16)
541 return CRYPT_INVALID_KEYSIZE;
542 if (*keysize < 24) {
543 *keysize = 16;
544 } else if (*keysize < 32) {
545 *keysize = 24;
546 } else {
547 *keysize = 32;
548 }
549 return CRYPT_OK;
550 }
551
552 #endif
553
554
555
556 /* $Source$ */
557 /* $Revision$ */
558 /* $Date$ */
+0
-343
libtom-src/ciphers/skipjack.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file skipjack.c
13 Skipjack Implementation by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_SKIPJACK
18
19 const struct ltc_cipher_descriptor skipjack_desc =
20 {
21 "skipjack",
22 17,
23 10, 10, 8, 32,
24 &skipjack_setup,
25 &skipjack_ecb_encrypt,
26 &skipjack_ecb_decrypt,
27 &skipjack_test,
28 &skipjack_done,
29 &skipjack_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 static const unsigned char sbox[256] = {
34 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9,
35 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28,
36 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53,
37 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2,
38 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8,
39 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90,
40 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76,
41 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d,
42 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18,
43 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4,
44 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40,
45 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5,
46 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2,
47 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8,
48 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac,
49 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
50 };
51
52 /* simple x + 1 (mod 10) in one step. */
53 static const int keystep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
54
55 /* simple x - 1 (mod 10) in one step */
56 static const int ikeystep[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 };
57
58 /**
59 Initialize the Skipjack block cipher
60 @param key The symmetric key you wish to pass
61 @param keylen The key length in bytes
62 @param num_rounds The number of rounds desired (0 for default)
63 @param skey The key in as scheduled by this function.
64 @return CRYPT_OK if successful
65 */
66 int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
67 {
68 int x;
69
70 LTC_ARGCHK(key != NULL);
71 LTC_ARGCHK(skey != NULL);
72
73 if (keylen != 10) {
74 return CRYPT_INVALID_KEYSIZE;
75 }
76
77 if (num_rounds != 32 && num_rounds != 0) {
78 return CRYPT_INVALID_ROUNDS;
79 }
80
81 /* make sure the key is in range for platforms where CHAR_BIT != 8 */
82 for (x = 0; x < 10; x++) {
83 skey->skipjack.key[x] = key[x] & 255;
84 }
85
86 return CRYPT_OK;
87 }
88
89 #define RULE_A \
90 tmp = g_func(w1, &kp, skey->skipjack.key); \
91 w1 = tmp ^ w4 ^ x; \
92 w4 = w3; w3 = w2; \
93 w2 = tmp;
94
95 #define RULE_B \
96 tmp = g_func(w1, &kp, skey->skipjack.key); \
97 tmp1 = w4; w4 = w3; \
98 w3 = w1 ^ w2 ^ x; \
99 w1 = tmp1; w2 = tmp;
100
101 #define RULE_A1 \
102 tmp = w1 ^ w2 ^ x; \
103 w1 = ig_func(w2, &kp, skey->skipjack.key); \
104 w2 = w3; w3 = w4; w4 = tmp;
105
106 #define RULE_B1 \
107 tmp = ig_func(w2, &kp, skey->skipjack.key); \
108 w2 = tmp ^ w3 ^ x; \
109 w3 = w4; w4 = w1; w1 = tmp;
110
111 static unsigned g_func(unsigned w, int *kp, unsigned char *key)
112 {
113 unsigned char g1,g2;
114
115 g1 = (w >> 8) & 255; g2 = w & 255;
116 g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp];
117 g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp];
118 g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp];
119 g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp];
120 return ((unsigned)g1<<8)|(unsigned)g2;
121 }
122
123 static unsigned ig_func(unsigned w, int *kp, unsigned char *key)
124 {
125 unsigned char g1,g2;
126
127 g1 = (w >> 8) & 255; g2 = w & 255;
128 *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]];
129 *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]];
130 *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]];
131 *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]];
132 return ((unsigned)g1<<8)|(unsigned)g2;
133 }
134
135 /**
136 Encrypts a block of text with Skipjack
137 @param pt The input plaintext (8 bytes)
138 @param ct The output ciphertext (8 bytes)
139 @param skey The key as scheduled
140 @return CRYPT_OK if successful
141 */
142 #ifdef LTC_CLEAN_STACK
143 static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
144 #else
145 int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
146 #endif
147 {
148 unsigned w1,w2,w3,w4,tmp,tmp1;
149 int x, kp;
150
151 LTC_ARGCHK(pt != NULL);
152 LTC_ARGCHK(ct != NULL);
153 LTC_ARGCHK(skey != NULL);
154
155 /* load block */
156 w1 = ((unsigned)pt[0]<<8)|pt[1];
157 w2 = ((unsigned)pt[2]<<8)|pt[3];
158 w3 = ((unsigned)pt[4]<<8)|pt[5];
159 w4 = ((unsigned)pt[6]<<8)|pt[7];
160
161 /* 8 rounds of RULE A */
162 for (x = 1, kp = 0; x < 9; x++) {
163 RULE_A;
164 }
165
166 /* 8 rounds of RULE B */
167 for (; x < 17; x++) {
168 RULE_B;
169 }
170
171 /* 8 rounds of RULE A */
172 for (; x < 25; x++) {
173 RULE_A;
174 }
175
176 /* 8 rounds of RULE B */
177 for (; x < 33; x++) {
178 RULE_B;
179 }
180
181 /* store block */
182 ct[0] = (w1>>8)&255; ct[1] = w1&255;
183 ct[2] = (w2>>8)&255; ct[3] = w2&255;
184 ct[4] = (w3>>8)&255; ct[5] = w3&255;
185 ct[6] = (w4>>8)&255; ct[7] = w4&255;
186
187 return CRYPT_OK;
188 }
189
190 #ifdef LTC_CLEAN_STACK
191 int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
192 {
193 int err = _skipjack_ecb_encrypt(pt, ct, skey);
194 burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2);
195 return err;
196 }
197 #endif
198
199 /**
200 Decrypts a block of text with Skipjack
201 @param ct The input ciphertext (8 bytes)
202 @param pt The output plaintext (8 bytes)
203 @param skey The key as scheduled
204 @return CRYPT_OK if successful
205 */
206 #ifdef LTC_CLEAN_STACK
207 static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
208 #else
209 int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
210 #endif
211 {
212 unsigned w1,w2,w3,w4,tmp;
213 int x, kp;
214
215 LTC_ARGCHK(pt != NULL);
216 LTC_ARGCHK(ct != NULL);
217 LTC_ARGCHK(skey != NULL);
218
219 /* load block */
220 w1 = ((unsigned)ct[0]<<8)|ct[1];
221 w2 = ((unsigned)ct[2]<<8)|ct[3];
222 w3 = ((unsigned)ct[4]<<8)|ct[5];
223 w4 = ((unsigned)ct[6]<<8)|ct[7];
224
225 /* 8 rounds of RULE B^-1
226
227 Note the value "kp = 8" comes from "kp = (32 * 4) mod 10" where 32*4 is 128 which mod 10 is 8
228 */
229 for (x = 32, kp = 8; x > 24; x--) {
230 RULE_B1;
231 }
232
233 /* 8 rounds of RULE A^-1 */
234 for (; x > 16; x--) {
235 RULE_A1;
236 }
237
238
239 /* 8 rounds of RULE B^-1 */
240 for (; x > 8; x--) {
241 RULE_B1;
242 }
243
244 /* 8 rounds of RULE A^-1 */
245 for (; x > 0; x--) {
246 RULE_A1;
247 }
248
249 /* store block */
250 pt[0] = (w1>>8)&255; pt[1] = w1&255;
251 pt[2] = (w2>>8)&255; pt[3] = w2&255;
252 pt[4] = (w3>>8)&255; pt[5] = w3&255;
253 pt[6] = (w4>>8)&255; pt[7] = w4&255;
254
255 return CRYPT_OK;
256 }
257
258 #ifdef LTC_CLEAN_STACK
259 int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
260 {
261 int err = _skipjack_ecb_decrypt(ct, pt, skey);
262 burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2);
263 return err;
264 }
265 #endif
266
267 /**
268 Performs a self-test of the Skipjack block cipher
269 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
270 */
271 int skipjack_test(void)
272 {
273 #ifndef LTC_TEST
274 return CRYPT_NOP;
275 #else
276 static const struct {
277 unsigned char key[10], pt[8], ct[8];
278 } tests[] = {
279 {
280 { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 },
281 { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa },
282 { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 }
283 }
284 };
285 unsigned char buf[2][8];
286 int x, y, err;
287 symmetric_key key;
288
289 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
290 /* setup key */
291 if ((err = skipjack_setup(tests[x].key, 10, 0, &key)) != CRYPT_OK) {
292 return err;
293 }
294
295 /* encrypt and decrypt */
296 skipjack_ecb_encrypt(tests[x].pt, buf[0], &key);
297 skipjack_ecb_decrypt(buf[0], buf[1], &key);
298
299 /* compare */
300 if (XMEMCMP(buf[0], tests[x].ct, 8) != 0 || XMEMCMP(buf[1], tests[x].pt, 8) != 0) {
301 return CRYPT_FAIL_TESTVECTOR;
302 }
303
304 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
305 for (y = 0; y < 8; y++) buf[0][y] = 0;
306 for (y = 0; y < 1000; y++) skipjack_ecb_encrypt(buf[0], buf[0], &key);
307 for (y = 0; y < 1000; y++) skipjack_ecb_decrypt(buf[0], buf[0], &key);
308 for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
309 }
310
311 return CRYPT_OK;
312 #endif
313 }
314
315 /** Terminate the context
316 @param skey The scheduled key
317 */
318 void skipjack_done(symmetric_key *skey)
319 {
320 }
321
322 /**
323 Gets suitable key size
324 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
325 @return CRYPT_OK if the input key size is acceptable.
326 */
327 int skipjack_keysize(int *keysize)
328 {
329 LTC_ARGCHK(keysize != NULL);
330 if (*keysize < 10) {
331 return CRYPT_INVALID_KEYSIZE;
332 } else if (*keysize > 10) {
333 *keysize = 10;
334 }
335 return CRYPT_OK;
336 }
337
338 #endif
339
340 /* $Source$ */
341 /* $Revision$ */
342 /* $Date$ */
+0
-710
libtom-src/ciphers/twofish/twofish.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file twofish.c
13 Implementation of Twofish by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_TWOFISH
18
19 /* first LTC_TWOFISH_ALL_TABLES must ensure LTC_TWOFISH_TABLES is defined */
20 #ifdef LTC_TWOFISH_ALL_TABLES
21 #ifndef LTC_TWOFISH_TABLES
22 #define LTC_TWOFISH_TABLES
23 #endif
24 #endif
25
26 const struct ltc_cipher_descriptor twofish_desc =
27 {
28 "twofish",
29 7,
30 16, 32, 16, 16,
31 &twofish_setup,
32 &twofish_ecb_encrypt,
33 &twofish_ecb_decrypt,
34 &twofish_test,
35 &twofish_done,
36 &twofish_keysize,
37 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
38 };
39
40 /* the two polynomials */
41 #define MDS_POLY 0x169
42 #define RS_POLY 0x14D
43
44 /* The 4x8 RS Linear Transform */
45 static const unsigned char RS[4][8] = {
46 { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E },
47 { 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 },
48 { 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 },
49 { 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 }
50 };
51
52 #ifdef LTC_TWOFISH_SMALL
53 /* sbox usage orderings */
54 static const unsigned char qord[4][5] = {
55 { 1, 1, 0, 0, 1 },
56 { 0, 1, 1, 0, 0 },
57 { 0, 0, 0, 1, 1 },
58 { 1, 0, 1, 1, 0 }
59 };
60 #endif /* LTC_TWOFISH_SMALL */
61
62 #ifdef LTC_TWOFISH_TABLES
63
64 #include "twofish_tab.c.inc"
65
66 #define sbox(i, x) ((ulong32)SBOX[i][(x)&255])
67
68 #else
69
70 /* The Q-box tables */
71 static const unsigned char qbox[2][4][16] = {
72 {
73 { 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 },
74 { 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD },
75 { 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 },
76 { 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA }
77 },
78 {
79 { 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 },
80 { 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 },
81 { 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF },
82 { 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA }
83 }
84 };
85
86 /* computes S_i[x] */
87 #ifdef LTC_CLEAN_STACK
88 static ulong32 _sbox(int i, ulong32 x)
89 #else
90 static ulong32 sbox(int i, ulong32 x)
91 #endif
92 {
93 unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y;
94
95 /* a0,b0 = [x/16], x mod 16 */
96 a0 = (unsigned char)((x>>4)&15);
97 b0 = (unsigned char)((x)&15);
98
99 /* a1 = a0 ^ b0 */
100 a1 = a0 ^ b0;
101
102 /* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */
103 b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15;
104
105 /* a2,b2 = t0[a1], t1[b1] */
106 a2 = qbox[i][0][(int)a1];
107 b2 = qbox[i][1][(int)b1];
108
109 /* a3 = a2 ^ b2 */
110 a3 = a2 ^ b2;
111
112 /* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */
113 b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15;
114
115 /* a4,b4 = t2[a3], t3[b3] */
116 a4 = qbox[i][2][(int)a3];
117 b4 = qbox[i][3][(int)b3];
118
119 /* y = 16b4 + a4 */
120 y = (b4 << 4) + a4;
121
122 /* return result */
123 return (ulong32)y;
124 }
125
126 #ifdef LTC_CLEAN_STACK
127 static ulong32 sbox(int i, ulong32 x)
128 {
129 ulong32 y;
130 y = _sbox(i, x);
131 burn_stack(sizeof(unsigned char) * 11);
132 return y;
133 }
134 #endif /* LTC_CLEAN_STACK */
135
136 #endif /* LTC_TWOFISH_TABLES */
137
138 /* computes ab mod p */
139 static ulong32 gf_mult(ulong32 a, ulong32 b, ulong32 p)
140 {
141 ulong32 result, B[2], P[2];
142
143 P[1] = p;
144 B[1] = b;
145 result = P[0] = B[0] = 0;
146
147 /* unrolled branchless GF multiplier */
148 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
149 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
150 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
151 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
152 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
153 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
154 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
155 result ^= B[a&1];
156
157 return result;
158 }
159
160 /* computes [y0 y1 y2 y3] = MDS . [x0] */
161 #ifndef LTC_TWOFISH_TABLES
162 static ulong32 mds_column_mult(unsigned char in, int col)
163 {
164 ulong32 x01, x5B, xEF;
165
166 x01 = in;
167 x5B = gf_mult(in, 0x5B, MDS_POLY);
168 xEF = gf_mult(in, 0xEF, MDS_POLY);
169
170 switch (col) {
171 case 0:
172 return (x01 << 0 ) |
173 (x5B << 8 ) |
174 (xEF << 16) |
175 (xEF << 24);
176 case 1:
177 return (xEF << 0 ) |
178 (xEF << 8 ) |
179 (x5B << 16) |
180 (x01 << 24);
181 case 2:
182 return (x5B << 0 ) |
183 (xEF << 8 ) |
184 (x01 << 16) |
185 (xEF << 24);
186 case 3:
187 return (x5B << 0 ) |
188 (x01 << 8 ) |
189 (xEF << 16) |
190 (x5B << 24);
191 }
192 /* avoid warnings, we'd never get here normally but just to calm compiler warnings... */
193 return 0;
194 }
195
196 #else /* !LTC_TWOFISH_TABLES */
197
198 #define mds_column_mult(x, i) mds_tab[i][x]
199
200 #endif /* LTC_TWOFISH_TABLES */
201
202 /* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */
203 static void mds_mult(const unsigned char *in, unsigned char *out)
204 {
205 int x;
206 ulong32 tmp;
207 for (tmp = x = 0; x < 4; x++) {
208 tmp ^= mds_column_mult(in[x], x);
209 }
210 STORE32L(tmp, out);
211 }
212
213 #ifdef LTC_TWOFISH_ALL_TABLES
214 /* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
215 static void rs_mult(const unsigned char *in, unsigned char *out)
216 {
217 ulong32 tmp;
218 tmp = rs_tab0[in[0]] ^ rs_tab1[in[1]] ^ rs_tab2[in[2]] ^ rs_tab3[in[3]] ^
219 rs_tab4[in[4]] ^ rs_tab5[in[5]] ^ rs_tab6[in[6]] ^ rs_tab7[in[7]];
220 STORE32L(tmp, out);
221 }
222
223 #else /* !LTC_TWOFISH_ALL_TABLES */
224
225 /* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
226 static void rs_mult(const unsigned char *in, unsigned char *out)
227 {
228 int x, y;
229 for (x = 0; x < 4; x++) {
230 out[x] = 0;
231 for (y = 0; y < 8; y++) {
232 out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY);
233 }
234 }
235 }
236
237 #endif
238
239 /* computes h(x) */
240 static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset)
241 {
242 int x;
243 unsigned char y[4];
244 for (x = 0; x < 4; x++) {
245 y[x] = in[x];
246 }
247 switch (k) {
248 case 4:
249 y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]);
250 y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]);
251 y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]);
252 y[3] = (unsigned char)(sbox(1, (ulong32)y[3]) ^ M[4 * (6 + offset) + 3]);
253 case 3:
254 y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (4 + offset) + 0]);
255 y[1] = (unsigned char)(sbox(1, (ulong32)y[1]) ^ M[4 * (4 + offset) + 1]);
256 y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (4 + offset) + 2]);
257 y[3] = (unsigned char)(sbox(0, (ulong32)y[3]) ^ M[4 * (4 + offset) + 3]);
258 case 2:
259 y[0] = (unsigned char)(sbox(1, sbox(0, sbox(0, (ulong32)y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0]));
260 y[1] = (unsigned char)(sbox(0, sbox(0, sbox(1, (ulong32)y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1]));
261 y[2] = (unsigned char)(sbox(1, sbox(1, sbox(0, (ulong32)y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2]));
262 y[3] = (unsigned char)(sbox(0, sbox(1, sbox(1, (ulong32)y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3]));
263 }
264 mds_mult(y, out);
265 }
266
267 #ifndef LTC_TWOFISH_SMALL
268
269 /* for GCC we don't use pointer aliases */
270 #if defined(__GNUC__)
271 #define S1 skey->twofish.S[0]
272 #define S2 skey->twofish.S[1]
273 #define S3 skey->twofish.S[2]
274 #define S4 skey->twofish.S[3]
275 #endif
276
277 /* the G function */
278 #define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)])
279 #define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)])
280
281 #else
282
283 #ifdef LTC_CLEAN_STACK
284 static ulong32 _g_func(ulong32 x, symmetric_key *key)
285 #else
286 static ulong32 g_func(ulong32 x, symmetric_key *key)
287 #endif
288 {
289 unsigned char g, i, y, z;
290 ulong32 res;
291
292 res = 0;
293 for (y = 0; y < 4; y++) {
294 z = key->twofish.start;
295
296 /* do unkeyed substitution */
297 g = sbox(qord[y][z++], (x >> (8*y)) & 255);
298
299 /* first subkey */
300 i = 0;
301
302 /* do key mixing+sbox until z==5 */
303 while (z != 5) {
304 g = g ^ key->twofish.S[4*i++ + y];
305 g = sbox(qord[y][z++], g);
306 }
307
308 /* multiply g by a column of the MDS */
309 res ^= mds_column_mult(g, y);
310 }
311 return res;
312 }
313
314 #define g1_func(x, key) g_func(ROLc(x, 8), key)
315
316 #ifdef LTC_CLEAN_STACK
317 static ulong32 g_func(ulong32 x, symmetric_key *key)
318 {
319 ulong32 y;
320 y = _g_func(x, key);
321 burn_stack(sizeof(unsigned char) * 4 + sizeof(ulong32));
322 return y;
323 }
324 #endif /* LTC_CLEAN_STACK */
325
326 #endif /* LTC_TWOFISH_SMALL */
327
328 /**
329 Initialize the Twofish block cipher
330 @param key The symmetric key you wish to pass
331 @param keylen The key length in bytes
332 @param num_rounds The number of rounds desired (0 for default)
333 @param skey The key in as scheduled by this function.
334 @return CRYPT_OK if successful
335 */
336 #ifdef LTC_CLEAN_STACK
337 static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
338 #else
339 int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
340 #endif
341 {
342 #ifndef LTC_TWOFISH_SMALL
343 unsigned char S[4*4], tmpx0, tmpx1;
344 #endif
345 int k, x, y;
346 unsigned char tmp[4], tmp2[4], M[8*4];
347 ulong32 A, B;
348
349 LTC_ARGCHK(key != NULL);
350 LTC_ARGCHK(skey != NULL);
351
352 /* invalid arguments? */
353 if (num_rounds != 16 && num_rounds != 0) {
354 return CRYPT_INVALID_ROUNDS;
355 }
356
357 if (keylen != 16 && keylen != 24 && keylen != 32) {
358 return CRYPT_INVALID_KEYSIZE;
359 }
360
361 /* k = keysize/64 [but since our keysize is in bytes...] */
362 k = keylen / 8;
363
364 /* copy the key into M */
365 for (x = 0; x < keylen; x++) {
366 M[x] = key[x] & 255;
367 }
368
369 /* create the S[..] words */
370 #ifndef LTC_TWOFISH_SMALL
371 for (x = 0; x < k; x++) {
372 rs_mult(M+(x*8), S+(x*4));
373 }
374 #else
375 for (x = 0; x < k; x++) {
376 rs_mult(M+(x*8), skey->twofish.S+(x*4));
377 }
378 #endif
379
380 /* make subkeys */
381 for (x = 0; x < 20; x++) {
382 /* A = h(p * 2x, Me) */
383 for (y = 0; y < 4; y++) {
384 tmp[y] = x+x;
385 }
386 h_func(tmp, tmp2, M, k, 0);
387 LOAD32L(A, tmp2);
388
389 /* B = ROL(h(p * (2x + 1), Mo), 8) */
390 for (y = 0; y < 4; y++) {
391 tmp[y] = (unsigned char)(x+x+1);
392 }
393 h_func(tmp, tmp2, M, k, 1);
394 LOAD32L(B, tmp2);
395 B = ROLc(B, 8);
396
397 /* K[2i] = A + B */
398 skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL;
399
400 /* K[2i+1] = (A + 2B) <<< 9 */
401 skey->twofish.K[x+x+1] = ROLc(B + B + A, 9);
402 }
403
404 #ifndef LTC_TWOFISH_SMALL
405 /* make the sboxes (large ram variant) */
406 if (k == 2) {
407 for (x = 0; x < 256; x++) {
408 tmpx0 = (unsigned char)sbox(0, x);
409 tmpx1 = (unsigned char)sbox(1, x);
410 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0);
411 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1);
412 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2);
413 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3);
414 }
415 } else if (k == 3) {
416 for (x = 0; x < 256; x++) {
417 tmpx0 = (unsigned char)sbox(0, x);
418 tmpx1 = (unsigned char)sbox(1, x);
419 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0);
420 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1);
421 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2);
422 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3);
423 }
424 } else {
425 for (x = 0; x < 256; x++) {
426 tmpx0 = (unsigned char)sbox(0, x);
427 tmpx1 = (unsigned char)sbox(1, x);
428 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0);
429 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1);
430 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2);
431 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3);
432 }
433 }
434 #else
435 /* where to start in the sbox layers */
436 /* small ram variant */
437 switch (k) {
438 case 4 : skey->twofish.start = 0; break;
439 case 3 : skey->twofish.start = 1; break;
440 default: skey->twofish.start = 2; break;
441 }
442 #endif
443 return CRYPT_OK;
444 }
445
446 #ifdef LTC_CLEAN_STACK
447 int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
448 {
449 int x;
450 x = _twofish_setup(key, keylen, num_rounds, skey);
451 burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(ulong32) * 2);
452 return x;
453 }
454 #endif
455
456 /**
457 Encrypts a block of text with Twofish
458 @param pt The input plaintext (16 bytes)
459 @param ct The output ciphertext (16 bytes)
460 @param skey The key as scheduled
461 @return CRYPT_OK if successful
462 */
463 #ifdef LTC_CLEAN_STACK
464 static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
465 #else
466 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
467 #endif
468 {
469 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
470 int r;
471 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
472 ulong32 *S1, *S2, *S3, *S4;
473 #endif
474
475 LTC_ARGCHK(pt != NULL);
476 LTC_ARGCHK(ct != NULL);
477 LTC_ARGCHK(skey != NULL);
478
479 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
480 S1 = skey->twofish.S[0];
481 S2 = skey->twofish.S[1];
482 S3 = skey->twofish.S[2];
483 S4 = skey->twofish.S[3];
484 #endif
485
486 LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);
487 LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);
488 a ^= skey->twofish.K[0];
489 b ^= skey->twofish.K[1];
490 c ^= skey->twofish.K[2];
491 d ^= skey->twofish.K[3];
492
493 k = skey->twofish.K + 8;
494 for (r = 8; r != 0; --r) {
495 t2 = g1_func(b, skey);
496 t1 = g_func(a, skey) + t2;
497 c = RORc(c ^ (t1 + k[0]), 1);
498 d = ROLc(d, 1) ^ (t2 + t1 + k[1]);
499
500 t2 = g1_func(d, skey);
501 t1 = g_func(c, skey) + t2;
502 a = RORc(a ^ (t1 + k[2]), 1);
503 b = ROLc(b, 1) ^ (t2 + t1 + k[3]);
504 k += 4;
505 }
506
507 /* output with "undo last swap" */
508 ta = c ^ skey->twofish.K[4];
509 tb = d ^ skey->twofish.K[5];
510 tc = a ^ skey->twofish.K[6];
511 td = b ^ skey->twofish.K[7];
512
513 /* store output */
514 STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
515 STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
516
517 return CRYPT_OK;
518 }
519
520 #ifdef LTC_CLEAN_STACK
521 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
522 {
523 int err = _twofish_ecb_encrypt(pt, ct, skey);
524 burn_stack(sizeof(ulong32) * 10 + sizeof(int));
525 return err;
526 }
527 #endif
528
529 /**
530 Decrypts a block of text with Twofish
531 @param ct The input ciphertext (16 bytes)
532 @param pt The output plaintext (16 bytes)
533 @param skey The key as scheduled
534 @return CRYPT_OK if successful
535 */
536 #ifdef LTC_CLEAN_STACK
537 static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
538 #else
539 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
540 #endif
541 {
542 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
543 int r;
544 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
545 ulong32 *S1, *S2, *S3, *S4;
546 #endif
547
548 LTC_ARGCHK(pt != NULL);
549 LTC_ARGCHK(ct != NULL);
550 LTC_ARGCHK(skey != NULL);
551
552 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
553 S1 = skey->twofish.S[0];
554 S2 = skey->twofish.S[1];
555 S3 = skey->twofish.S[2];
556 S4 = skey->twofish.S[3];
557 #endif
558
559 /* load input */
560 LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]);
561 LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]);
562
563 /* undo undo final swap */
564 a = tc ^ skey->twofish.K[6];
565 b = td ^ skey->twofish.K[7];
566 c = ta ^ skey->twofish.K[4];
567 d = tb ^ skey->twofish.K[5];
568
569 k = skey->twofish.K + 36;
570 for (r = 8; r != 0; --r) {
571 t2 = g1_func(d, skey);
572 t1 = g_func(c, skey) + t2;
573 a = ROLc(a, 1) ^ (t1 + k[2]);
574 b = RORc(b ^ (t2 + t1 + k[3]), 1);
575
576 t2 = g1_func(b, skey);
577 t1 = g_func(a, skey) + t2;
578 c = ROLc(c, 1) ^ (t1 + k[0]);
579 d = RORc(d ^ (t2 + t1 + k[1]), 1);
580 k -= 4;
581 }
582
583 /* pre-white */
584 a ^= skey->twofish.K[0];
585 b ^= skey->twofish.K[1];
586 c ^= skey->twofish.K[2];
587 d ^= skey->twofish.K[3];
588
589 /* store */
590 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
591 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
592 return CRYPT_OK;
593 }
594
595 #ifdef LTC_CLEAN_STACK
596 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
597 {
598 int err =_twofish_ecb_decrypt(ct, pt, skey);
599 burn_stack(sizeof(ulong32) * 10 + sizeof(int));
600 return err;
601 }
602 #endif
603
604 /**
605 Performs a self-test of the Twofish block cipher
606 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
607 */
608 int twofish_test(void)
609 {
610 #ifndef LTC_TEST
611 return CRYPT_NOP;
612 #else
613 static const struct {
614 int keylen;
615 unsigned char key[32], pt[16], ct[16];
616 } tests[] = {
617 { 16,
618 { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
619 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A },
620 { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
621 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 },
622 { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
623 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 }
624 }, {
625 24,
626 { 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,
627 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
628 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 },
629 { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
630 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 },
631 { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
632 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 }
633 }, {
634 32,
635 { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
636 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
637 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
638 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F },
639 { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
640 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 },
641 { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
642 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA }
643 }
644 };
645
646
647 symmetric_key key;
648 unsigned char tmp[2][16];
649 int err, i, y;
650
651 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
652 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
653 return err;
654 }
655 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key);
656 twofish_ecb_decrypt(tmp[0], tmp[1], &key);
657 if (XMEMCMP(tmp[0], tests[i].ct, 16) != 0 || XMEMCMP(tmp[1], tests[i].pt, 16) != 0) {
658 #if 0
659 printf("Twofish failed test %d, %d, %d\n", i, XMEMCMP(tmp[0], tests[i].ct, 16), XMEMCMP(tmp[1], tests[i].pt, 16));
660 #endif
661 return CRYPT_FAIL_TESTVECTOR;
662 }
663 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
664 for (y = 0; y < 16; y++) tmp[0][y] = 0;
665 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key);
666 for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key);
667 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
668 }
669 return CRYPT_OK;
670 #endif
671 }
672
673 /** Terminate the context
674 @param skey The scheduled key
675 */
676 void twofish_done(symmetric_key *skey)
677 {
678 }
679
680 /**
681 Gets suitable key size
682 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
683 @return CRYPT_OK if the input key size is acceptable.
684 */
685 int twofish_keysize(int *keysize)
686 {
687 LTC_ARGCHK(keysize);
688 if (*keysize < 16)
689 return CRYPT_INVALID_KEYSIZE;
690 if (*keysize < 24) {
691 *keysize = 16;
692 return CRYPT_OK;
693 } else if (*keysize < 32) {
694 *keysize = 24;
695 return CRYPT_OK;
696 } else {
697 *keysize = 32;
698 return CRYPT_OK;
699 }
700 }
701
702 #endif
703
704
705
706
707 /* $Source$ */
708 /* $Revision$ */
709 /* $Date$ */
+0
-496
libtom-src/ciphers/twofish/twofish_tab.c.inc less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file twofish_tab.c
13 Twofish tables, Tom St Denis
14 */
15 #ifdef LTC_TWOFISH_TABLES
16
17 /* pre generated 8x8 tables from the four 4x4s */
18 static const unsigned char SBOX[2][256] = {
19 {
20 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92,
21 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98,
22 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13,
23 0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23,
24 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01,
25 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe,
26 0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c,
27 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
28 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95,
29 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5,
30 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9,
31 0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8,
32 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d,
33 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11,
34 0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c,
35 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
36 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87,
37 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f,
38 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e,
39 0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02,
40 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7,
41 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12,
42 0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc,
43 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
44 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d,
45 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0},
46 {
47 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3,
48 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd,
49 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa,
50 0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d,
51 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84,
52 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54,
53 0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60,
54 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
55 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3,
56 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff,
57 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7,
58 0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9,
59 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94,
60 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c,
61 0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76,
62 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
63 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23,
64 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e,
65 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f,
66 0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5,
67 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e,
68 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34,
69 0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4,
70 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
71 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25,
72 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91}
73 };
74
75 /* the 4x4 MDS in a nicer format */
76 static const ulong32 mds_tab[4][256] = {
77 {
78 0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL,
79 0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL,
80 0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL,
81 0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL,
82 0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL,
83 0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL,
84 0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL,
85 0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL,
86 0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL,
87 0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL,
88 0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL,
89 0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL,
90 0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL,
91 0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL,
92 0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL,
93 0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL,
94 0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL,
95 0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL,
96 0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL,
97 0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL,
98 0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL,
99 0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL,
100 0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL,
101 0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL,
102 0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL,
103 0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL,
104 0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL,
105 0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL,
106 0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL,
107 0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL,
108 0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL,
109 0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL
110 },
111 {
112 0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL,
113 0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL,
114 0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL,
115 0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL,
116 0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL,
117 0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL,
118 0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL,
119 0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL,
120 0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL,
121 0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL,
122 0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL,
123 0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL,
124 0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL,
125 0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL,
126 0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL,
127 0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL,
128 0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL,
129 0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL,
130 0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL,
131 0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL,
132 0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL,
133 0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL,
134 0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL,
135 0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL,
136 0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL,
137 0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL,
138 0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL,
139 0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL,
140 0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL,
141 0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL,
142 0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL,
143 0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL
144 },
145 {
146 0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL,
147 0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL,
148 0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL,
149 0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL,
150 0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL,
151 0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL,
152 0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL,
153 0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL,
154 0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL,
155 0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL,
156 0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL,
157 0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL,
158 0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL,
159 0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL,
160 0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL,
161 0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL,
162 0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL,
163 0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL,
164 0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL,
165 0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL,
166 0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL,
167 0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL,
168 0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL,
169 0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL,
170 0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL,
171 0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL,
172 0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL,
173 0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL,
174 0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL,
175 0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL,
176 0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL,
177 0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL
178 },
179 {
180 0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL,
181 0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL,
182 0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL,
183 0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL,
184 0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL,
185 0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL,
186 0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL,
187 0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL,
188 0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL,
189 0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL,
190 0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL,
191 0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL,
192 0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL,
193 0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL,
194 0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL,
195 0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL,
196 0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL,
197 0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL,
198 0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL,
199 0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL,
200 0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL,
201 0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL,
202 0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL,
203 0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL,
204 0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL,
205 0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL,
206 0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL,
207 0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL,
208 0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL,
209 0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL,
210 0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL,
211 0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL
212 }};
213
214 #ifdef LTC_TWOFISH_ALL_TABLES
215
216 /* the 4x8 RS transform */
217 static const ulong32 rs_tab0[256] = {
218 0x00000000LU, 0xa402a401LU, 0x05040502LU, 0xa106a103LU, 0x0a080a04LU, 0xae0aae05LU, 0x0f0c0f06LU, 0xab0eab07LU,
219 0x14101408LU, 0xb012b009LU, 0x1114110aLU, 0xb516b50bLU, 0x1e181e0cLU, 0xba1aba0dLU, 0x1b1c1b0eLU, 0xbf1ebf0fLU,
220 0x28202810LU, 0x8c228c11LU, 0x2d242d12LU, 0x89268913LU, 0x22282214LU, 0x862a8615LU, 0x272c2716LU, 0x832e8317LU,
221 0x3c303c18LU, 0x98329819LU, 0x3934391aLU, 0x9d369d1bLU, 0x3638361cLU, 0x923a921dLU, 0x333c331eLU, 0x973e971fLU,
222 0x50405020LU, 0xf442f421LU, 0x55445522LU, 0xf146f123LU, 0x5a485a24LU, 0xfe4afe25LU, 0x5f4c5f26LU, 0xfb4efb27LU,
223 0x44504428LU, 0xe052e029LU, 0x4154412aLU, 0xe556e52bLU, 0x4e584e2cLU, 0xea5aea2dLU, 0x4b5c4b2eLU, 0xef5eef2fLU,
224 0x78607830LU, 0xdc62dc31LU, 0x7d647d32LU, 0xd966d933LU, 0x72687234LU, 0xd66ad635LU, 0x776c7736LU, 0xd36ed337LU,
225 0x6c706c38LU, 0xc872c839LU, 0x6974693aLU, 0xcd76cd3bLU, 0x6678663cLU, 0xc27ac23dLU, 0x637c633eLU, 0xc77ec73fLU,
226 0xa080a040LU, 0x04820441LU, 0xa584a542LU, 0x01860143LU, 0xaa88aa44LU, 0x0e8a0e45LU, 0xaf8caf46LU, 0x0b8e0b47LU,
227 0xb490b448LU, 0x10921049LU, 0xb194b14aLU, 0x1596154bLU, 0xbe98be4cLU, 0x1a9a1a4dLU, 0xbb9cbb4eLU, 0x1f9e1f4fLU,
228 0x88a08850LU, 0x2ca22c51LU, 0x8da48d52LU, 0x29a62953LU, 0x82a88254LU, 0x26aa2655LU, 0x87ac8756LU, 0x23ae2357LU,
229 0x9cb09c58LU, 0x38b23859LU, 0x99b4995aLU, 0x3db63d5bLU, 0x96b8965cLU, 0x32ba325dLU, 0x93bc935eLU, 0x37be375fLU,
230 0xf0c0f060LU, 0x54c25461LU, 0xf5c4f562LU, 0x51c65163LU, 0xfac8fa64LU, 0x5eca5e65LU, 0xffccff66LU, 0x5bce5b67LU,
231 0xe4d0e468LU, 0x40d24069LU, 0xe1d4e16aLU, 0x45d6456bLU, 0xeed8ee6cLU, 0x4ada4a6dLU, 0xebdceb6eLU, 0x4fde4f6fLU,
232 0xd8e0d870LU, 0x7ce27c71LU, 0xdde4dd72LU, 0x79e67973LU, 0xd2e8d274LU, 0x76ea7675LU, 0xd7ecd776LU, 0x73ee7377LU,
233 0xccf0cc78LU, 0x68f26879LU, 0xc9f4c97aLU, 0x6df66d7bLU, 0xc6f8c67cLU, 0x62fa627dLU, 0xc3fcc37eLU, 0x67fe677fLU,
234 0x0d4d0d80LU, 0xa94fa981LU, 0x08490882LU, 0xac4bac83LU, 0x07450784LU, 0xa347a385LU, 0x02410286LU, 0xa643a687LU,
235 0x195d1988LU, 0xbd5fbd89LU, 0x1c591c8aLU, 0xb85bb88bLU, 0x1355138cLU, 0xb757b78dLU, 0x1651168eLU, 0xb253b28fLU,
236 0x256d2590LU, 0x816f8191LU, 0x20692092LU, 0x846b8493LU, 0x2f652f94LU, 0x8b678b95LU, 0x2a612a96LU, 0x8e638e97LU,
237 0x317d3198LU, 0x957f9599LU, 0x3479349aLU, 0x907b909bLU, 0x3b753b9cLU, 0x9f779f9dLU, 0x3e713e9eLU, 0x9a739a9fLU,
238 0x5d0d5da0LU, 0xf90ff9a1LU, 0x580958a2LU, 0xfc0bfca3LU, 0x570557a4LU, 0xf307f3a5LU, 0x520152a6LU, 0xf603f6a7LU,
239 0x491d49a8LU, 0xed1feda9LU, 0x4c194caaLU, 0xe81be8abLU, 0x431543acLU, 0xe717e7adLU, 0x461146aeLU, 0xe213e2afLU,
240 0x752d75b0LU, 0xd12fd1b1LU, 0x702970b2LU, 0xd42bd4b3LU, 0x7f257fb4LU, 0xdb27dbb5LU, 0x7a217ab6LU, 0xde23deb7LU,
241 0x613d61b8LU, 0xc53fc5b9LU, 0x643964baLU, 0xc03bc0bbLU, 0x6b356bbcLU, 0xcf37cfbdLU, 0x6e316ebeLU, 0xca33cabfLU,
242 0xadcdadc0LU, 0x09cf09c1LU, 0xa8c9a8c2LU, 0x0ccb0cc3LU, 0xa7c5a7c4LU, 0x03c703c5LU, 0xa2c1a2c6LU, 0x06c306c7LU,
243 0xb9ddb9c8LU, 0x1ddf1dc9LU, 0xbcd9bccaLU, 0x18db18cbLU, 0xb3d5b3ccLU, 0x17d717cdLU, 0xb6d1b6ceLU, 0x12d312cfLU,
244 0x85ed85d0LU, 0x21ef21d1LU, 0x80e980d2LU, 0x24eb24d3LU, 0x8fe58fd4LU, 0x2be72bd5LU, 0x8ae18ad6LU, 0x2ee32ed7LU,
245 0x91fd91d8LU, 0x35ff35d9LU, 0x94f994daLU, 0x30fb30dbLU, 0x9bf59bdcLU, 0x3ff73fddLU, 0x9ef19edeLU, 0x3af33adfLU,
246 0xfd8dfde0LU, 0x598f59e1LU, 0xf889f8e2LU, 0x5c8b5ce3LU, 0xf785f7e4LU, 0x538753e5LU, 0xf281f2e6LU, 0x568356e7LU,
247 0xe99de9e8LU, 0x4d9f4de9LU, 0xec99eceaLU, 0x489b48ebLU, 0xe395e3ecLU, 0x479747edLU, 0xe691e6eeLU, 0x429342efLU,
248 0xd5add5f0LU, 0x71af71f1LU, 0xd0a9d0f2LU, 0x74ab74f3LU, 0xdfa5dff4LU, 0x7ba77bf5LU, 0xdaa1daf6LU, 0x7ea37ef7LU,
249 0xc1bdc1f8LU, 0x65bf65f9LU, 0xc4b9c4faLU, 0x60bb60fbLU, 0xcbb5cbfcLU, 0x6fb76ffdLU, 0xceb1cefeLU, 0x6ab36affLU };
250
251 static const ulong32 rs_tab1[256] = {
252 0x00000000LU, 0x55a156a4LU, 0xaa0fac05LU, 0xffaefaa1LU, 0x191e150aLU, 0x4cbf43aeLU, 0xb311b90fLU, 0xe6b0efabLU,
253 0x323c2a14LU, 0x679d7cb0LU, 0x98338611LU, 0xcd92d0b5LU, 0x2b223f1eLU, 0x7e8369baLU, 0x812d931bLU, 0xd48cc5bfLU,
254 0x64785428LU, 0x31d9028cLU, 0xce77f82dLU, 0x9bd6ae89LU, 0x7d664122LU, 0x28c71786LU, 0xd769ed27LU, 0x82c8bb83LU,
255 0x56447e3cLU, 0x03e52898LU, 0xfc4bd239LU, 0xa9ea849dLU, 0x4f5a6b36LU, 0x1afb3d92LU, 0xe555c733LU, 0xb0f49197LU,
256 0xc8f0a850LU, 0x9d51fef4LU, 0x62ff0455LU, 0x375e52f1LU, 0xd1eebd5aLU, 0x844febfeLU, 0x7be1115fLU, 0x2e4047fbLU,
257 0xfacc8244LU, 0xaf6dd4e0LU, 0x50c32e41LU, 0x056278e5LU, 0xe3d2974eLU, 0xb673c1eaLU, 0x49dd3b4bLU, 0x1c7c6defLU,
258 0xac88fc78LU, 0xf929aadcLU, 0x0687507dLU, 0x532606d9LU, 0xb596e972LU, 0xe037bfd6LU, 0x1f994577LU, 0x4a3813d3LU,
259 0x9eb4d66cLU, 0xcb1580c8LU, 0x34bb7a69LU, 0x611a2ccdLU, 0x87aac366LU, 0xd20b95c2LU, 0x2da56f63LU, 0x780439c7LU,
260 0xddad1da0LU, 0x880c4b04LU, 0x77a2b1a5LU, 0x2203e701LU, 0xc4b308aaLU, 0x91125e0eLU, 0x6ebca4afLU, 0x3b1df20bLU,
261 0xef9137b4LU, 0xba306110LU, 0x459e9bb1LU, 0x103fcd15LU, 0xf68f22beLU, 0xa32e741aLU, 0x5c808ebbLU, 0x0921d81fLU,
262 0xb9d54988LU, 0xec741f2cLU, 0x13dae58dLU, 0x467bb329LU, 0xa0cb5c82LU, 0xf56a0a26LU, 0x0ac4f087LU, 0x5f65a623LU,
263 0x8be9639cLU, 0xde483538LU, 0x21e6cf99LU, 0x7447993dLU, 0x92f77696LU, 0xc7562032LU, 0x38f8da93LU, 0x6d598c37LU,
264 0x155db5f0LU, 0x40fce354LU, 0xbf5219f5LU, 0xeaf34f51LU, 0x0c43a0faLU, 0x59e2f65eLU, 0xa64c0cffLU, 0xf3ed5a5bLU,
265 0x27619fe4LU, 0x72c0c940LU, 0x8d6e33e1LU, 0xd8cf6545LU, 0x3e7f8aeeLU, 0x6bdedc4aLU, 0x947026ebLU, 0xc1d1704fLU,
266 0x7125e1d8LU, 0x2484b77cLU, 0xdb2a4dddLU, 0x8e8b1b79LU, 0x683bf4d2LU, 0x3d9aa276LU, 0xc23458d7LU, 0x97950e73LU,
267 0x4319cbccLU, 0x16b89d68LU, 0xe91667c9LU, 0xbcb7316dLU, 0x5a07dec6LU, 0x0fa68862LU, 0xf00872c3LU, 0xa5a92467LU,
268 0xf7173a0dLU, 0xa2b66ca9LU, 0x5d189608LU, 0x08b9c0acLU, 0xee092f07LU, 0xbba879a3LU, 0x44068302LU, 0x11a7d5a6LU,
269 0xc52b1019LU, 0x908a46bdLU, 0x6f24bc1cLU, 0x3a85eab8LU, 0xdc350513LU, 0x899453b7LU, 0x763aa916LU, 0x239bffb2LU,
270 0x936f6e25LU, 0xc6ce3881LU, 0x3960c220LU, 0x6cc19484LU, 0x8a717b2fLU, 0xdfd02d8bLU, 0x207ed72aLU, 0x75df818eLU,
271 0xa1534431LU, 0xf4f21295LU, 0x0b5ce834LU, 0x5efdbe90LU, 0xb84d513bLU, 0xedec079fLU, 0x1242fd3eLU, 0x47e3ab9aLU,
272 0x3fe7925dLU, 0x6a46c4f9LU, 0x95e83e58LU, 0xc04968fcLU, 0x26f98757LU, 0x7358d1f3LU, 0x8cf62b52LU, 0xd9577df6LU,
273 0x0ddbb849LU, 0x587aeeedLU, 0xa7d4144cLU, 0xf27542e8LU, 0x14c5ad43LU, 0x4164fbe7LU, 0xbeca0146LU, 0xeb6b57e2LU,
274 0x5b9fc675LU, 0x0e3e90d1LU, 0xf1906a70LU, 0xa4313cd4LU, 0x4281d37fLU, 0x172085dbLU, 0xe88e7f7aLU, 0xbd2f29deLU,
275 0x69a3ec61LU, 0x3c02bac5LU, 0xc3ac4064LU, 0x960d16c0LU, 0x70bdf96bLU, 0x251cafcfLU, 0xdab2556eLU, 0x8f1303caLU,
276 0x2aba27adLU, 0x7f1b7109LU, 0x80b58ba8LU, 0xd514dd0cLU, 0x33a432a7LU, 0x66056403LU, 0x99ab9ea2LU, 0xcc0ac806LU,
277 0x18860db9LU, 0x4d275b1dLU, 0xb289a1bcLU, 0xe728f718LU, 0x019818b3LU, 0x54394e17LU, 0xab97b4b6LU, 0xfe36e212LU,
278 0x4ec27385LU, 0x1b632521LU, 0xe4cddf80LU, 0xb16c8924LU, 0x57dc668fLU, 0x027d302bLU, 0xfdd3ca8aLU, 0xa8729c2eLU,
279 0x7cfe5991LU, 0x295f0f35LU, 0xd6f1f594LU, 0x8350a330LU, 0x65e04c9bLU, 0x30411a3fLU, 0xcfefe09eLU, 0x9a4eb63aLU,
280 0xe24a8ffdLU, 0xb7ebd959LU, 0x484523f8LU, 0x1de4755cLU, 0xfb549af7LU, 0xaef5cc53LU, 0x515b36f2LU, 0x04fa6056LU,
281 0xd076a5e9LU, 0x85d7f34dLU, 0x7a7909ecLU, 0x2fd85f48LU, 0xc968b0e3LU, 0x9cc9e647LU, 0x63671ce6LU, 0x36c64a42LU,
282 0x8632dbd5LU, 0xd3938d71LU, 0x2c3d77d0LU, 0x799c2174LU, 0x9f2ccedfLU, 0xca8d987bLU, 0x352362daLU, 0x6082347eLU,
283 0xb40ef1c1LU, 0xe1afa765LU, 0x1e015dc4LU, 0x4ba00b60LU, 0xad10e4cbLU, 0xf8b1b26fLU, 0x071f48ceLU, 0x52be1e6aLU };
284
285 static const ulong32 rs_tab2[256] = {
286 0x00000000LU, 0x87fc8255LU, 0x43b549aaLU, 0xc449cbffLU, 0x86279219LU, 0x01db104cLU, 0xc592dbb3LU, 0x426e59e6LU,
287 0x414e6932LU, 0xc6b2eb67LU, 0x02fb2098LU, 0x8507a2cdLU, 0xc769fb2bLU, 0x4095797eLU, 0x84dcb281LU, 0x032030d4LU,
288 0x829cd264LU, 0x05605031LU, 0xc1299bceLU, 0x46d5199bLU, 0x04bb407dLU, 0x8347c228LU, 0x470e09d7LU, 0xc0f28b82LU,
289 0xc3d2bb56LU, 0x442e3903LU, 0x8067f2fcLU, 0x079b70a9LU, 0x45f5294fLU, 0xc209ab1aLU, 0x064060e5LU, 0x81bce2b0LU,
290 0x4975e9c8LU, 0xce896b9dLU, 0x0ac0a062LU, 0x8d3c2237LU, 0xcf527bd1LU, 0x48aef984LU, 0x8ce7327bLU, 0x0b1bb02eLU,
291 0x083b80faLU, 0x8fc702afLU, 0x4b8ec950LU, 0xcc724b05LU, 0x8e1c12e3LU, 0x09e090b6LU, 0xcda95b49LU, 0x4a55d91cLU,
292 0xcbe93bacLU, 0x4c15b9f9LU, 0x885c7206LU, 0x0fa0f053LU, 0x4dcea9b5LU, 0xca322be0LU, 0x0e7be01fLU, 0x8987624aLU,
293 0x8aa7529eLU, 0x0d5bd0cbLU, 0xc9121b34LU, 0x4eee9961LU, 0x0c80c087LU, 0x8b7c42d2LU, 0x4f35892dLU, 0xc8c90b78LU,
294 0x92ea9fddLU, 0x15161d88LU, 0xd15fd677LU, 0x56a35422LU, 0x14cd0dc4LU, 0x93318f91LU, 0x5778446eLU, 0xd084c63bLU,
295 0xd3a4f6efLU, 0x545874baLU, 0x9011bf45LU, 0x17ed3d10LU, 0x558364f6LU, 0xd27fe6a3LU, 0x16362d5cLU, 0x91caaf09LU,
296 0x10764db9LU, 0x978acfecLU, 0x53c30413LU, 0xd43f8646LU, 0x9651dfa0LU, 0x11ad5df5LU, 0xd5e4960aLU, 0x5218145fLU,
297 0x5138248bLU, 0xd6c4a6deLU, 0x128d6d21LU, 0x9571ef74LU, 0xd71fb692LU, 0x50e334c7LU, 0x94aaff38LU, 0x13567d6dLU,
298 0xdb9f7615LU, 0x5c63f440LU, 0x982a3fbfLU, 0x1fd6bdeaLU, 0x5db8e40cLU, 0xda446659LU, 0x1e0dada6LU, 0x99f12ff3LU,
299 0x9ad11f27LU, 0x1d2d9d72LU, 0xd964568dLU, 0x5e98d4d8LU, 0x1cf68d3eLU, 0x9b0a0f6bLU, 0x5f43c494LU, 0xd8bf46c1LU,
300 0x5903a471LU, 0xdeff2624LU, 0x1ab6eddbLU, 0x9d4a6f8eLU, 0xdf243668LU, 0x58d8b43dLU, 0x9c917fc2LU, 0x1b6dfd97LU,
301 0x184dcd43LU, 0x9fb14f16LU, 0x5bf884e9LU, 0xdc0406bcLU, 0x9e6a5f5aLU, 0x1996dd0fLU, 0xdddf16f0LU, 0x5a2394a5LU,
302 0x699973f7LU, 0xee65f1a2LU, 0x2a2c3a5dLU, 0xadd0b808LU, 0xefbee1eeLU, 0x684263bbLU, 0xac0ba844LU, 0x2bf72a11LU,
303 0x28d71ac5LU, 0xaf2b9890LU, 0x6b62536fLU, 0xec9ed13aLU, 0xaef088dcLU, 0x290c0a89LU, 0xed45c176LU, 0x6ab94323LU,
304 0xeb05a193LU, 0x6cf923c6LU, 0xa8b0e839LU, 0x2f4c6a6cLU, 0x6d22338aLU, 0xeadeb1dfLU, 0x2e977a20LU, 0xa96bf875LU,
305 0xaa4bc8a1LU, 0x2db74af4LU, 0xe9fe810bLU, 0x6e02035eLU, 0x2c6c5ab8LU, 0xab90d8edLU, 0x6fd91312LU, 0xe8259147LU,
306 0x20ec9a3fLU, 0xa710186aLU, 0x6359d395LU, 0xe4a551c0LU, 0xa6cb0826LU, 0x21378a73LU, 0xe57e418cLU, 0x6282c3d9LU,
307 0x61a2f30dLU, 0xe65e7158LU, 0x2217baa7LU, 0xa5eb38f2LU, 0xe7856114LU, 0x6079e341LU, 0xa43028beLU, 0x23ccaaebLU,
308 0xa270485bLU, 0x258cca0eLU, 0xe1c501f1LU, 0x663983a4LU, 0x2457da42LU, 0xa3ab5817LU, 0x67e293e8LU, 0xe01e11bdLU,
309 0xe33e2169LU, 0x64c2a33cLU, 0xa08b68c3LU, 0x2777ea96LU, 0x6519b370LU, 0xe2e53125LU, 0x26acfadaLU, 0xa150788fLU,
310 0xfb73ec2aLU, 0x7c8f6e7fLU, 0xb8c6a580LU, 0x3f3a27d5LU, 0x7d547e33LU, 0xfaa8fc66LU, 0x3ee13799LU, 0xb91db5ccLU,
311 0xba3d8518LU, 0x3dc1074dLU, 0xf988ccb2LU, 0x7e744ee7LU, 0x3c1a1701LU, 0xbbe69554LU, 0x7faf5eabLU, 0xf853dcfeLU,
312 0x79ef3e4eLU, 0xfe13bc1bLU, 0x3a5a77e4LU, 0xbda6f5b1LU, 0xffc8ac57LU, 0x78342e02LU, 0xbc7de5fdLU, 0x3b8167a8LU,
313 0x38a1577cLU, 0xbf5dd529LU, 0x7b141ed6LU, 0xfce89c83LU, 0xbe86c565LU, 0x397a4730LU, 0xfd338ccfLU, 0x7acf0e9aLU,
314 0xb20605e2LU, 0x35fa87b7LU, 0xf1b34c48LU, 0x764fce1dLU, 0x342197fbLU, 0xb3dd15aeLU, 0x7794de51LU, 0xf0685c04LU,
315 0xf3486cd0LU, 0x74b4ee85LU, 0xb0fd257aLU, 0x3701a72fLU, 0x756ffec9LU, 0xf2937c9cLU, 0x36dab763LU, 0xb1263536LU,
316 0x309ad786LU, 0xb76655d3LU, 0x732f9e2cLU, 0xf4d31c79LU, 0xb6bd459fLU, 0x3141c7caLU, 0xf5080c35LU, 0x72f48e60LU,
317 0x71d4beb4LU, 0xf6283ce1LU, 0x3261f71eLU, 0xb59d754bLU, 0xf7f32cadLU, 0x700faef8LU, 0xb4466507LU, 0x33bae752LU };
318
319 static const ulong32 rs_tab3[256] = {
320 0x00000000LU, 0x5ac1f387LU, 0xb4cfab43LU, 0xee0e58c4LU, 0x25d31b86LU, 0x7f12e801LU, 0x911cb0c5LU, 0xcbdd4342LU,
321 0x4aeb3641LU, 0x102ac5c6LU, 0xfe249d02LU, 0xa4e56e85LU, 0x6f382dc7LU, 0x35f9de40LU, 0xdbf78684LU, 0x81367503LU,
322 0x949b6c82LU, 0xce5a9f05LU, 0x2054c7c1LU, 0x7a953446LU, 0xb1487704LU, 0xeb898483LU, 0x0587dc47LU, 0x5f462fc0LU,
323 0xde705ac3LU, 0x84b1a944LU, 0x6abff180LU, 0x307e0207LU, 0xfba34145LU, 0xa162b2c2LU, 0x4f6cea06LU, 0x15ad1981LU,
324 0x657bd849LU, 0x3fba2bceLU, 0xd1b4730aLU, 0x8b75808dLU, 0x40a8c3cfLU, 0x1a693048LU, 0xf467688cLU, 0xaea69b0bLU,
325 0x2f90ee08LU, 0x75511d8fLU, 0x9b5f454bLU, 0xc19eb6ccLU, 0x0a43f58eLU, 0x50820609LU, 0xbe8c5ecdLU, 0xe44dad4aLU,
326 0xf1e0b4cbLU, 0xab21474cLU, 0x452f1f88LU, 0x1feeec0fLU, 0xd433af4dLU, 0x8ef25ccaLU, 0x60fc040eLU, 0x3a3df789LU,
327 0xbb0b828aLU, 0xe1ca710dLU, 0x0fc429c9LU, 0x5505da4eLU, 0x9ed8990cLU, 0xc4196a8bLU, 0x2a17324fLU, 0x70d6c1c8LU,
328 0xcaf6fd92LU, 0x90370e15LU, 0x7e3956d1LU, 0x24f8a556LU, 0xef25e614LU, 0xb5e41593LU, 0x5bea4d57LU, 0x012bbed0LU,
329 0x801dcbd3LU, 0xdadc3854LU, 0x34d26090LU, 0x6e139317LU, 0xa5ced055LU, 0xff0f23d2LU, 0x11017b16LU, 0x4bc08891LU,
330 0x5e6d9110LU, 0x04ac6297LU, 0xeaa23a53LU, 0xb063c9d4LU, 0x7bbe8a96LU, 0x217f7911LU, 0xcf7121d5LU, 0x95b0d252LU,
331 0x1486a751LU, 0x4e4754d6LU, 0xa0490c12LU, 0xfa88ff95LU, 0x3155bcd7LU, 0x6b944f50LU, 0x859a1794LU, 0xdf5be413LU,
332 0xaf8d25dbLU, 0xf54cd65cLU, 0x1b428e98LU, 0x41837d1fLU, 0x8a5e3e5dLU, 0xd09fcddaLU, 0x3e91951eLU, 0x64506699LU,
333 0xe566139aLU, 0xbfa7e01dLU, 0x51a9b8d9LU, 0x0b684b5eLU, 0xc0b5081cLU, 0x9a74fb9bLU, 0x747aa35fLU, 0x2ebb50d8LU,
334 0x3b164959LU, 0x61d7badeLU, 0x8fd9e21aLU, 0xd518119dLU, 0x1ec552dfLU, 0x4404a158LU, 0xaa0af99cLU, 0xf0cb0a1bLU,
335 0x71fd7f18LU, 0x2b3c8c9fLU, 0xc532d45bLU, 0x9ff327dcLU, 0x542e649eLU, 0x0eef9719LU, 0xe0e1cfddLU, 0xba203c5aLU,
336 0xd9a1b769LU, 0x836044eeLU, 0x6d6e1c2aLU, 0x37afefadLU, 0xfc72acefLU, 0xa6b35f68LU, 0x48bd07acLU, 0x127cf42bLU,
337 0x934a8128LU, 0xc98b72afLU, 0x27852a6bLU, 0x7d44d9ecLU, 0xb6999aaeLU, 0xec586929LU, 0x025631edLU, 0x5897c26aLU,
338 0x4d3adbebLU, 0x17fb286cLU, 0xf9f570a8LU, 0xa334832fLU, 0x68e9c06dLU, 0x322833eaLU, 0xdc266b2eLU, 0x86e798a9LU,
339 0x07d1edaaLU, 0x5d101e2dLU, 0xb31e46e9LU, 0xe9dfb56eLU, 0x2202f62cLU, 0x78c305abLU, 0x96cd5d6fLU, 0xcc0caee8LU,
340 0xbcda6f20LU, 0xe61b9ca7LU, 0x0815c463LU, 0x52d437e4LU, 0x990974a6LU, 0xc3c88721LU, 0x2dc6dfe5LU, 0x77072c62LU,
341 0xf6315961LU, 0xacf0aae6LU, 0x42fef222LU, 0x183f01a5LU, 0xd3e242e7LU, 0x8923b160LU, 0x672de9a4LU, 0x3dec1a23LU,
342 0x284103a2LU, 0x7280f025LU, 0x9c8ea8e1LU, 0xc64f5b66LU, 0x0d921824LU, 0x5753eba3LU, 0xb95db367LU, 0xe39c40e0LU,
343 0x62aa35e3LU, 0x386bc664LU, 0xd6659ea0LU, 0x8ca46d27LU, 0x47792e65LU, 0x1db8dde2LU, 0xf3b68526LU, 0xa97776a1LU,
344 0x13574afbLU, 0x4996b97cLU, 0xa798e1b8LU, 0xfd59123fLU, 0x3684517dLU, 0x6c45a2faLU, 0x824bfa3eLU, 0xd88a09b9LU,
345 0x59bc7cbaLU, 0x037d8f3dLU, 0xed73d7f9LU, 0xb7b2247eLU, 0x7c6f673cLU, 0x26ae94bbLU, 0xc8a0cc7fLU, 0x92613ff8LU,
346 0x87cc2679LU, 0xdd0dd5feLU, 0x33038d3aLU, 0x69c27ebdLU, 0xa21f3dffLU, 0xf8dece78LU, 0x16d096bcLU, 0x4c11653bLU,
347 0xcd271038LU, 0x97e6e3bfLU, 0x79e8bb7bLU, 0x232948fcLU, 0xe8f40bbeLU, 0xb235f839LU, 0x5c3ba0fdLU, 0x06fa537aLU,
348 0x762c92b2LU, 0x2ced6135LU, 0xc2e339f1LU, 0x9822ca76LU, 0x53ff8934LU, 0x093e7ab3LU, 0xe7302277LU, 0xbdf1d1f0LU,
349 0x3cc7a4f3LU, 0x66065774LU, 0x88080fb0LU, 0xd2c9fc37LU, 0x1914bf75LU, 0x43d54cf2LU, 0xaddb1436LU, 0xf71ae7b1LU,
350 0xe2b7fe30LU, 0xb8760db7LU, 0x56785573LU, 0x0cb9a6f4LU, 0xc764e5b6LU, 0x9da51631LU, 0x73ab4ef5LU, 0x296abd72LU,
351 0xa85cc871LU, 0xf29d3bf6LU, 0x1c936332LU, 0x465290b5LU, 0x8d8fd3f7LU, 0xd74e2070LU, 0x394078b4LU, 0x63818b33LU };
352
353 static const ulong32 rs_tab4[256] = {
354 0x00000000LU, 0x58471e5aLU, 0xb08e3cb4LU, 0xe8c922eeLU, 0x2d517825LU, 0x7516667fLU, 0x9ddf4491LU, 0xc5985acbLU,
355 0x5aa2f04aLU, 0x02e5ee10LU, 0xea2cccfeLU, 0xb26bd2a4LU, 0x77f3886fLU, 0x2fb49635LU, 0xc77db4dbLU, 0x9f3aaa81LU,
356 0xb409ad94LU, 0xec4eb3ceLU, 0x04879120LU, 0x5cc08f7aLU, 0x9958d5b1LU, 0xc11fcbebLU, 0x29d6e905LU, 0x7191f75fLU,
357 0xeeab5ddeLU, 0xb6ec4384LU, 0x5e25616aLU, 0x06627f30LU, 0xc3fa25fbLU, 0x9bbd3ba1LU, 0x7374194fLU, 0x2b330715LU,
358 0x25121765LU, 0x7d55093fLU, 0x959c2bd1LU, 0xcddb358bLU, 0x08436f40LU, 0x5004711aLU, 0xb8cd53f4LU, 0xe08a4daeLU,
359 0x7fb0e72fLU, 0x27f7f975LU, 0xcf3edb9bLU, 0x9779c5c1LU, 0x52e19f0aLU, 0x0aa68150LU, 0xe26fa3beLU, 0xba28bde4LU,
360 0x911bbaf1LU, 0xc95ca4abLU, 0x21958645LU, 0x79d2981fLU, 0xbc4ac2d4LU, 0xe40ddc8eLU, 0x0cc4fe60LU, 0x5483e03aLU,
361 0xcbb94abbLU, 0x93fe54e1LU, 0x7b37760fLU, 0x23706855LU, 0xe6e8329eLU, 0xbeaf2cc4LU, 0x56660e2aLU, 0x0e211070LU,
362 0x4a242ecaLU, 0x12633090LU, 0xfaaa127eLU, 0xa2ed0c24LU, 0x677556efLU, 0x3f3248b5LU, 0xd7fb6a5bLU, 0x8fbc7401LU,
363 0x1086de80LU, 0x48c1c0daLU, 0xa008e234LU, 0xf84ffc6eLU, 0x3dd7a6a5LU, 0x6590b8ffLU, 0x8d599a11LU, 0xd51e844bLU,
364 0xfe2d835eLU, 0xa66a9d04LU, 0x4ea3bfeaLU, 0x16e4a1b0LU, 0xd37cfb7bLU, 0x8b3be521LU, 0x63f2c7cfLU, 0x3bb5d995LU,
365 0xa48f7314LU, 0xfcc86d4eLU, 0x14014fa0LU, 0x4c4651faLU, 0x89de0b31LU, 0xd199156bLU, 0x39503785LU, 0x611729dfLU,
366 0x6f3639afLU, 0x377127f5LU, 0xdfb8051bLU, 0x87ff1b41LU, 0x4267418aLU, 0x1a205fd0LU, 0xf2e97d3eLU, 0xaaae6364LU,
367 0x3594c9e5LU, 0x6dd3d7bfLU, 0x851af551LU, 0xdd5deb0bLU, 0x18c5b1c0LU, 0x4082af9aLU, 0xa84b8d74LU, 0xf00c932eLU,
368 0xdb3f943bLU, 0x83788a61LU, 0x6bb1a88fLU, 0x33f6b6d5LU, 0xf66eec1eLU, 0xae29f244LU, 0x46e0d0aaLU, 0x1ea7cef0LU,
369 0x819d6471LU, 0xd9da7a2bLU, 0x311358c5LU, 0x6954469fLU, 0xaccc1c54LU, 0xf48b020eLU, 0x1c4220e0LU, 0x44053ebaLU,
370 0x94485cd9LU, 0xcc0f4283LU, 0x24c6606dLU, 0x7c817e37LU, 0xb91924fcLU, 0xe15e3aa6LU, 0x09971848LU, 0x51d00612LU,
371 0xceeaac93LU, 0x96adb2c9LU, 0x7e649027LU, 0x26238e7dLU, 0xe3bbd4b6LU, 0xbbfccaecLU, 0x5335e802LU, 0x0b72f658LU,
372 0x2041f14dLU, 0x7806ef17LU, 0x90cfcdf9LU, 0xc888d3a3LU, 0x0d108968LU, 0x55579732LU, 0xbd9eb5dcLU, 0xe5d9ab86LU,
373 0x7ae30107LU, 0x22a41f5dLU, 0xca6d3db3LU, 0x922a23e9LU, 0x57b27922LU, 0x0ff56778LU, 0xe73c4596LU, 0xbf7b5bccLU,
374 0xb15a4bbcLU, 0xe91d55e6LU, 0x01d47708LU, 0x59936952LU, 0x9c0b3399LU, 0xc44c2dc3LU, 0x2c850f2dLU, 0x74c21177LU,
375 0xebf8bbf6LU, 0xb3bfa5acLU, 0x5b768742LU, 0x03319918LU, 0xc6a9c3d3LU, 0x9eeedd89LU, 0x7627ff67LU, 0x2e60e13dLU,
376 0x0553e628LU, 0x5d14f872LU, 0xb5ddda9cLU, 0xed9ac4c6LU, 0x28029e0dLU, 0x70458057LU, 0x988ca2b9LU, 0xc0cbbce3LU,
377 0x5ff11662LU, 0x07b60838LU, 0xef7f2ad6LU, 0xb738348cLU, 0x72a06e47LU, 0x2ae7701dLU, 0xc22e52f3LU, 0x9a694ca9LU,
378 0xde6c7213LU, 0x862b6c49LU, 0x6ee24ea7LU, 0x36a550fdLU, 0xf33d0a36LU, 0xab7a146cLU, 0x43b33682LU, 0x1bf428d8LU,
379 0x84ce8259LU, 0xdc899c03LU, 0x3440beedLU, 0x6c07a0b7LU, 0xa99ffa7cLU, 0xf1d8e426LU, 0x1911c6c8LU, 0x4156d892LU,
380 0x6a65df87LU, 0x3222c1ddLU, 0xdaebe333LU, 0x82acfd69LU, 0x4734a7a2LU, 0x1f73b9f8LU, 0xf7ba9b16LU, 0xaffd854cLU,
381 0x30c72fcdLU, 0x68803197LU, 0x80491379LU, 0xd80e0d23LU, 0x1d9657e8LU, 0x45d149b2LU, 0xad186b5cLU, 0xf55f7506LU,
382 0xfb7e6576LU, 0xa3397b2cLU, 0x4bf059c2LU, 0x13b74798LU, 0xd62f1d53LU, 0x8e680309LU, 0x66a121e7LU, 0x3ee63fbdLU,
383 0xa1dc953cLU, 0xf99b8b66LU, 0x1152a988LU, 0x4915b7d2LU, 0x8c8ded19LU, 0xd4caf343LU, 0x3c03d1adLU, 0x6444cff7LU,
384 0x4f77c8e2LU, 0x1730d6b8LU, 0xfff9f456LU, 0xa7beea0cLU, 0x6226b0c7LU, 0x3a61ae9dLU, 0xd2a88c73LU, 0x8aef9229LU,
385 0x15d538a8LU, 0x4d9226f2LU, 0xa55b041cLU, 0xfd1c1a46LU, 0x3884408dLU, 0x60c35ed7LU, 0x880a7c39LU, 0xd04d6263LU };
386
387 static const ulong32 rs_tab5[256] = {
388 0x00000000LU, 0xdbaec658LU, 0xfb11c1b0LU, 0x20bf07e8LU, 0xbb22cf2dLU, 0x608c0975LU, 0x40330e9dLU, 0x9b9dc8c5LU,
389 0x3b44d35aLU, 0xe0ea1502LU, 0xc05512eaLU, 0x1bfbd4b2LU, 0x80661c77LU, 0x5bc8da2fLU, 0x7b77ddc7LU, 0xa0d91b9fLU,
390 0x7688ebb4LU, 0xad262decLU, 0x8d992a04LU, 0x5637ec5cLU, 0xcdaa2499LU, 0x1604e2c1LU, 0x36bbe529LU, 0xed152371LU,
391 0x4dcc38eeLU, 0x9662feb6LU, 0xb6ddf95eLU, 0x6d733f06LU, 0xf6eef7c3LU, 0x2d40319bLU, 0x0dff3673LU, 0xd651f02bLU,
392 0xec5d9b25LU, 0x37f35d7dLU, 0x174c5a95LU, 0xcce29ccdLU, 0x577f5408LU, 0x8cd19250LU, 0xac6e95b8LU, 0x77c053e0LU,
393 0xd719487fLU, 0x0cb78e27LU, 0x2c0889cfLU, 0xf7a64f97LU, 0x6c3b8752LU, 0xb795410aLU, 0x972a46e2LU, 0x4c8480baLU,
394 0x9ad57091LU, 0x417bb6c9LU, 0x61c4b121LU, 0xba6a7779LU, 0x21f7bfbcLU, 0xfa5979e4LU, 0xdae67e0cLU, 0x0148b854LU,
395 0xa191a3cbLU, 0x7a3f6593LU, 0x5a80627bLU, 0x812ea423LU, 0x1ab36ce6LU, 0xc11daabeLU, 0xe1a2ad56LU, 0x3a0c6b0eLU,
396 0x95ba7b4aLU, 0x4e14bd12LU, 0x6eabbafaLU, 0xb5057ca2LU, 0x2e98b467LU, 0xf536723fLU, 0xd58975d7LU, 0x0e27b38fLU,
397 0xaefea810LU, 0x75506e48LU, 0x55ef69a0LU, 0x8e41aff8LU, 0x15dc673dLU, 0xce72a165LU, 0xeecda68dLU, 0x356360d5LU,
398 0xe33290feLU, 0x389c56a6LU, 0x1823514eLU, 0xc38d9716LU, 0x58105fd3LU, 0x83be998bLU, 0xa3019e63LU, 0x78af583bLU,
399 0xd87643a4LU, 0x03d885fcLU, 0x23678214LU, 0xf8c9444cLU, 0x63548c89LU, 0xb8fa4ad1LU, 0x98454d39LU, 0x43eb8b61LU,
400 0x79e7e06fLU, 0xa2492637LU, 0x82f621dfLU, 0x5958e787LU, 0xc2c52f42LU, 0x196be91aLU, 0x39d4eef2LU, 0xe27a28aaLU,
401 0x42a33335LU, 0x990df56dLU, 0xb9b2f285LU, 0x621c34ddLU, 0xf981fc18LU, 0x222f3a40LU, 0x02903da8LU, 0xd93efbf0LU,
402 0x0f6f0bdbLU, 0xd4c1cd83LU, 0xf47eca6bLU, 0x2fd00c33LU, 0xb44dc4f6LU, 0x6fe302aeLU, 0x4f5c0546LU, 0x94f2c31eLU,
403 0x342bd881LU, 0xef851ed9LU, 0xcf3a1931LU, 0x1494df69LU, 0x8f0917acLU, 0x54a7d1f4LU, 0x7418d61cLU, 0xafb61044LU,
404 0x6739f694LU, 0xbc9730ccLU, 0x9c283724LU, 0x4786f17cLU, 0xdc1b39b9LU, 0x07b5ffe1LU, 0x270af809LU, 0xfca43e51LU,
405 0x5c7d25ceLU, 0x87d3e396LU, 0xa76ce47eLU, 0x7cc22226LU, 0xe75feae3LU, 0x3cf12cbbLU, 0x1c4e2b53LU, 0xc7e0ed0bLU,
406 0x11b11d20LU, 0xca1fdb78LU, 0xeaa0dc90LU, 0x310e1ac8LU, 0xaa93d20dLU, 0x713d1455LU, 0x518213bdLU, 0x8a2cd5e5LU,
407 0x2af5ce7aLU, 0xf15b0822LU, 0xd1e40fcaLU, 0x0a4ac992LU, 0x91d70157LU, 0x4a79c70fLU, 0x6ac6c0e7LU, 0xb16806bfLU,
408 0x8b646db1LU, 0x50caabe9LU, 0x7075ac01LU, 0xabdb6a59LU, 0x3046a29cLU, 0xebe864c4LU, 0xcb57632cLU, 0x10f9a574LU,
409 0xb020beebLU, 0x6b8e78b3LU, 0x4b317f5bLU, 0x909fb903LU, 0x0b0271c6LU, 0xd0acb79eLU, 0xf013b076LU, 0x2bbd762eLU,
410 0xfdec8605LU, 0x2642405dLU, 0x06fd47b5LU, 0xdd5381edLU, 0x46ce4928LU, 0x9d608f70LU, 0xbddf8898LU, 0x66714ec0LU,
411 0xc6a8555fLU, 0x1d069307LU, 0x3db994efLU, 0xe61752b7LU, 0x7d8a9a72LU, 0xa6245c2aLU, 0x869b5bc2LU, 0x5d359d9aLU,
412 0xf2838ddeLU, 0x292d4b86LU, 0x09924c6eLU, 0xd23c8a36LU, 0x49a142f3LU, 0x920f84abLU, 0xb2b08343LU, 0x691e451bLU,
413 0xc9c75e84LU, 0x126998dcLU, 0x32d69f34LU, 0xe978596cLU, 0x72e591a9LU, 0xa94b57f1LU, 0x89f45019LU, 0x525a9641LU,
414 0x840b666aLU, 0x5fa5a032LU, 0x7f1aa7daLU, 0xa4b46182LU, 0x3f29a947LU, 0xe4876f1fLU, 0xc43868f7LU, 0x1f96aeafLU,
415 0xbf4fb530LU, 0x64e17368LU, 0x445e7480LU, 0x9ff0b2d8LU, 0x046d7a1dLU, 0xdfc3bc45LU, 0xff7cbbadLU, 0x24d27df5LU,
416 0x1ede16fbLU, 0xc570d0a3LU, 0xe5cfd74bLU, 0x3e611113LU, 0xa5fcd9d6LU, 0x7e521f8eLU, 0x5eed1866LU, 0x8543de3eLU,
417 0x259ac5a1LU, 0xfe3403f9LU, 0xde8b0411LU, 0x0525c249LU, 0x9eb80a8cLU, 0x4516ccd4LU, 0x65a9cb3cLU, 0xbe070d64LU,
418 0x6856fd4fLU, 0xb3f83b17LU, 0x93473cffLU, 0x48e9faa7LU, 0xd3743262LU, 0x08daf43aLU, 0x2865f3d2LU, 0xf3cb358aLU,
419 0x53122e15LU, 0x88bce84dLU, 0xa803efa5LU, 0x73ad29fdLU, 0xe830e138LU, 0x339e2760LU, 0x13212088LU, 0xc88fe6d0LU };
420
421 static const ulong32 rs_tab6[256] = {
422 0x00000000LU, 0x9e3d68dbLU, 0x717ad0fbLU, 0xef47b820LU, 0xe2f4edbbLU, 0x7cc98560LU, 0x938e3d40LU, 0x0db3559bLU,
423 0x89a5973bLU, 0x1798ffe0LU, 0xf8df47c0LU, 0x66e22f1bLU, 0x6b517a80LU, 0xf56c125bLU, 0x1a2baa7bLU, 0x8416c2a0LU,
424 0x5f076376LU, 0xc13a0badLU, 0x2e7db38dLU, 0xb040db56LU, 0xbdf38ecdLU, 0x23cee616LU, 0xcc895e36LU, 0x52b436edLU,
425 0xd6a2f44dLU, 0x489f9c96LU, 0xa7d824b6LU, 0x39e54c6dLU, 0x345619f6LU, 0xaa6b712dLU, 0x452cc90dLU, 0xdb11a1d6LU,
426 0xbe0ec6ecLU, 0x2033ae37LU, 0xcf741617LU, 0x51497eccLU, 0x5cfa2b57LU, 0xc2c7438cLU, 0x2d80fbacLU, 0xb3bd9377LU,
427 0x37ab51d7LU, 0xa996390cLU, 0x46d1812cLU, 0xd8ece9f7LU, 0xd55fbc6cLU, 0x4b62d4b7LU, 0xa4256c97LU, 0x3a18044cLU,
428 0xe109a59aLU, 0x7f34cd41LU, 0x90737561LU, 0x0e4e1dbaLU, 0x03fd4821LU, 0x9dc020faLU, 0x728798daLU, 0xecbaf001LU,
429 0x68ac32a1LU, 0xf6915a7aLU, 0x19d6e25aLU, 0x87eb8a81LU, 0x8a58df1aLU, 0x1465b7c1LU, 0xfb220fe1LU, 0x651f673aLU,
430 0x311cc195LU, 0xaf21a94eLU, 0x4066116eLU, 0xde5b79b5LU, 0xd3e82c2eLU, 0x4dd544f5LU, 0xa292fcd5LU, 0x3caf940eLU,
431 0xb8b956aeLU, 0x26843e75LU, 0xc9c38655LU, 0x57feee8eLU, 0x5a4dbb15LU, 0xc470d3ceLU, 0x2b376beeLU, 0xb50a0335LU,
432 0x6e1ba2e3LU, 0xf026ca38LU, 0x1f617218LU, 0x815c1ac3LU, 0x8cef4f58LU, 0x12d22783LU, 0xfd959fa3LU, 0x63a8f778LU,
433 0xe7be35d8LU, 0x79835d03LU, 0x96c4e523LU, 0x08f98df8LU, 0x054ad863LU, 0x9b77b0b8LU, 0x74300898LU, 0xea0d6043LU,
434 0x8f120779LU, 0x112f6fa2LU, 0xfe68d782LU, 0x6055bf59LU, 0x6de6eac2LU, 0xf3db8219LU, 0x1c9c3a39LU, 0x82a152e2LU,
435 0x06b79042LU, 0x988af899LU, 0x77cd40b9LU, 0xe9f02862LU, 0xe4437df9LU, 0x7a7e1522LU, 0x9539ad02LU, 0x0b04c5d9LU,
436 0xd015640fLU, 0x4e280cd4LU, 0xa16fb4f4LU, 0x3f52dc2fLU, 0x32e189b4LU, 0xacdce16fLU, 0x439b594fLU, 0xdda63194LU,
437 0x59b0f334LU, 0xc78d9befLU, 0x28ca23cfLU, 0xb6f74b14LU, 0xbb441e8fLU, 0x25797654LU, 0xca3ece74LU, 0x5403a6afLU,
438 0x6238cf67LU, 0xfc05a7bcLU, 0x13421f9cLU, 0x8d7f7747LU, 0x80cc22dcLU, 0x1ef14a07LU, 0xf1b6f227LU, 0x6f8b9afcLU,
439 0xeb9d585cLU, 0x75a03087LU, 0x9ae788a7LU, 0x04dae07cLU, 0x0969b5e7LU, 0x9754dd3cLU, 0x7813651cLU, 0xe62e0dc7LU,
440 0x3d3fac11LU, 0xa302c4caLU, 0x4c457ceaLU, 0xd2781431LU, 0xdfcb41aaLU, 0x41f62971LU, 0xaeb19151LU, 0x308cf98aLU,
441 0xb49a3b2aLU, 0x2aa753f1LU, 0xc5e0ebd1LU, 0x5bdd830aLU, 0x566ed691LU, 0xc853be4aLU, 0x2714066aLU, 0xb9296eb1LU,
442 0xdc36098bLU, 0x420b6150LU, 0xad4cd970LU, 0x3371b1abLU, 0x3ec2e430LU, 0xa0ff8cebLU, 0x4fb834cbLU, 0xd1855c10LU,
443 0x55939eb0LU, 0xcbaef66bLU, 0x24e94e4bLU, 0xbad42690LU, 0xb767730bLU, 0x295a1bd0LU, 0xc61da3f0LU, 0x5820cb2bLU,
444 0x83316afdLU, 0x1d0c0226LU, 0xf24bba06LU, 0x6c76d2ddLU, 0x61c58746LU, 0xfff8ef9dLU, 0x10bf57bdLU, 0x8e823f66LU,
445 0x0a94fdc6LU, 0x94a9951dLU, 0x7bee2d3dLU, 0xe5d345e6LU, 0xe860107dLU, 0x765d78a6LU, 0x991ac086LU, 0x0727a85dLU,
446 0x53240ef2LU, 0xcd196629LU, 0x225ede09LU, 0xbc63b6d2LU, 0xb1d0e349LU, 0x2fed8b92LU, 0xc0aa33b2LU, 0x5e975b69LU,
447 0xda8199c9LU, 0x44bcf112LU, 0xabfb4932LU, 0x35c621e9LU, 0x38757472LU, 0xa6481ca9LU, 0x490fa489LU, 0xd732cc52LU,
448 0x0c236d84LU, 0x921e055fLU, 0x7d59bd7fLU, 0xe364d5a4LU, 0xeed7803fLU, 0x70eae8e4LU, 0x9fad50c4LU, 0x0190381fLU,
449 0x8586fabfLU, 0x1bbb9264LU, 0xf4fc2a44LU, 0x6ac1429fLU, 0x67721704LU, 0xf94f7fdfLU, 0x1608c7ffLU, 0x8835af24LU,
450 0xed2ac81eLU, 0x7317a0c5LU, 0x9c5018e5LU, 0x026d703eLU, 0x0fde25a5LU, 0x91e34d7eLU, 0x7ea4f55eLU, 0xe0999d85LU,
451 0x648f5f25LU, 0xfab237feLU, 0x15f58fdeLU, 0x8bc8e705LU, 0x867bb29eLU, 0x1846da45LU, 0xf7016265LU, 0x693c0abeLU,
452 0xb22dab68LU, 0x2c10c3b3LU, 0xc3577b93LU, 0x5d6a1348LU, 0x50d946d3LU, 0xcee42e08LU, 0x21a39628LU, 0xbf9efef3LU,
453 0x3b883c53LU, 0xa5b55488LU, 0x4af2eca8LU, 0xd4cf8473LU, 0xd97cd1e8LU, 0x4741b933LU, 0xa8060113LU, 0x363b69c8LU };
454
455 static const ulong32 rs_tab7[256] = {
456 0x00000000LU, 0x0319e59eLU, 0x06328771LU, 0x052b62efLU, 0x0c6443e2LU, 0x0f7da67cLU, 0x0a56c493LU, 0x094f210dLU,
457 0x18c88689LU, 0x1bd16317LU, 0x1efa01f8LU, 0x1de3e466LU, 0x14acc56bLU, 0x17b520f5LU, 0x129e421aLU, 0x1187a784LU,
458 0x30dd415fLU, 0x33c4a4c1LU, 0x36efc62eLU, 0x35f623b0LU, 0x3cb902bdLU, 0x3fa0e723LU, 0x3a8b85ccLU, 0x39926052LU,
459 0x2815c7d6LU, 0x2b0c2248LU, 0x2e2740a7LU, 0x2d3ea539LU, 0x24718434LU, 0x276861aaLU, 0x22430345LU, 0x215ae6dbLU,
460 0x60f782beLU, 0x63ee6720LU, 0x66c505cfLU, 0x65dce051LU, 0x6c93c15cLU, 0x6f8a24c2LU, 0x6aa1462dLU, 0x69b8a3b3LU,
461 0x783f0437LU, 0x7b26e1a9LU, 0x7e0d8346LU, 0x7d1466d8LU, 0x745b47d5LU, 0x7742a24bLU, 0x7269c0a4LU, 0x7170253aLU,
462 0x502ac3e1LU, 0x5333267fLU, 0x56184490LU, 0x5501a10eLU, 0x5c4e8003LU, 0x5f57659dLU, 0x5a7c0772LU, 0x5965e2ecLU,
463 0x48e24568LU, 0x4bfba0f6LU, 0x4ed0c219LU, 0x4dc92787LU, 0x4486068aLU, 0x479fe314LU, 0x42b481fbLU, 0x41ad6465LU,
464 0xc0a34931LU, 0xc3baacafLU, 0xc691ce40LU, 0xc5882bdeLU, 0xccc70ad3LU, 0xcfdeef4dLU, 0xcaf58da2LU, 0xc9ec683cLU,
465 0xd86bcfb8LU, 0xdb722a26LU, 0xde5948c9LU, 0xdd40ad57LU, 0xd40f8c5aLU, 0xd71669c4LU, 0xd23d0b2bLU, 0xd124eeb5LU,
466 0xf07e086eLU, 0xf367edf0LU, 0xf64c8f1fLU, 0xf5556a81LU, 0xfc1a4b8cLU, 0xff03ae12LU, 0xfa28ccfdLU, 0xf9312963LU,
467 0xe8b68ee7LU, 0xebaf6b79LU, 0xee840996LU, 0xed9dec08LU, 0xe4d2cd05LU, 0xe7cb289bLU, 0xe2e04a74LU, 0xe1f9afeaLU,
468 0xa054cb8fLU, 0xa34d2e11LU, 0xa6664cfeLU, 0xa57fa960LU, 0xac30886dLU, 0xaf296df3LU, 0xaa020f1cLU, 0xa91bea82LU,
469 0xb89c4d06LU, 0xbb85a898LU, 0xbeaeca77LU, 0xbdb72fe9LU, 0xb4f80ee4LU, 0xb7e1eb7aLU, 0xb2ca8995LU, 0xb1d36c0bLU,
470 0x90898ad0LU, 0x93906f4eLU, 0x96bb0da1LU, 0x95a2e83fLU, 0x9cedc932LU, 0x9ff42cacLU, 0x9adf4e43LU, 0x99c6abddLU,
471 0x88410c59LU, 0x8b58e9c7LU, 0x8e738b28LU, 0x8d6a6eb6LU, 0x84254fbbLU, 0x873caa25LU, 0x8217c8caLU, 0x810e2d54LU,
472 0xcd0b9262LU, 0xce1277fcLU, 0xcb391513LU, 0xc820f08dLU, 0xc16fd180LU, 0xc276341eLU, 0xc75d56f1LU, 0xc444b36fLU,
473 0xd5c314ebLU, 0xd6daf175LU, 0xd3f1939aLU, 0xd0e87604LU, 0xd9a75709LU, 0xdabeb297LU, 0xdf95d078LU, 0xdc8c35e6LU,
474 0xfdd6d33dLU, 0xfecf36a3LU, 0xfbe4544cLU, 0xf8fdb1d2LU, 0xf1b290dfLU, 0xf2ab7541LU, 0xf78017aeLU, 0xf499f230LU,
475 0xe51e55b4LU, 0xe607b02aLU, 0xe32cd2c5LU, 0xe035375bLU, 0xe97a1656LU, 0xea63f3c8LU, 0xef489127LU, 0xec5174b9LU,
476 0xadfc10dcLU, 0xaee5f542LU, 0xabce97adLU, 0xa8d77233LU, 0xa198533eLU, 0xa281b6a0LU, 0xa7aad44fLU, 0xa4b331d1LU,
477 0xb5349655LU, 0xb62d73cbLU, 0xb3061124LU, 0xb01ff4baLU, 0xb950d5b7LU, 0xba493029LU, 0xbf6252c6LU, 0xbc7bb758LU,
478 0x9d215183LU, 0x9e38b41dLU, 0x9b13d6f2LU, 0x980a336cLU, 0x91451261LU, 0x925cf7ffLU, 0x97779510LU, 0x946e708eLU,
479 0x85e9d70aLU, 0x86f03294LU, 0x83db507bLU, 0x80c2b5e5LU, 0x898d94e8LU, 0x8a947176LU, 0x8fbf1399LU, 0x8ca6f607LU,
480 0x0da8db53LU, 0x0eb13ecdLU, 0x0b9a5c22LU, 0x0883b9bcLU, 0x01cc98b1LU, 0x02d57d2fLU, 0x07fe1fc0LU, 0x04e7fa5eLU,
481 0x15605ddaLU, 0x1679b844LU, 0x1352daabLU, 0x104b3f35LU, 0x19041e38LU, 0x1a1dfba6LU, 0x1f369949LU, 0x1c2f7cd7LU,
482 0x3d759a0cLU, 0x3e6c7f92LU, 0x3b471d7dLU, 0x385ef8e3LU, 0x3111d9eeLU, 0x32083c70LU, 0x37235e9fLU, 0x343abb01LU,
483 0x25bd1c85LU, 0x26a4f91bLU, 0x238f9bf4LU, 0x20967e6aLU, 0x29d95f67LU, 0x2ac0baf9LU, 0x2febd816LU, 0x2cf23d88LU,
484 0x6d5f59edLU, 0x6e46bc73LU, 0x6b6dde9cLU, 0x68743b02LU, 0x613b1a0fLU, 0x6222ff91LU, 0x67099d7eLU, 0x641078e0LU,
485 0x7597df64LU, 0x768e3afaLU, 0x73a55815LU, 0x70bcbd8bLU, 0x79f39c86LU, 0x7aea7918LU, 0x7fc11bf7LU, 0x7cd8fe69LU,
486 0x5d8218b2LU, 0x5e9bfd2cLU, 0x5bb09fc3LU, 0x58a97a5dLU, 0x51e65b50LU, 0x52ffbeceLU, 0x57d4dc21LU, 0x54cd39bfLU,
487 0x454a9e3bLU, 0x46537ba5LU, 0x4378194aLU, 0x4061fcd4LU, 0x492eddd9LU, 0x4a373847LU, 0x4f1c5aa8LU, 0x4c05bf36LU };
488
489 #endif /* LTC_TWOFISH_ALL_TABLES */
490
491 #endif
492
493 /* $Source$ */
494 /* $Revision$ */
495 /* $Date$ */
+0
-277
libtom-src/ciphers/xtea.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file xtea.c
13 Implementation of LTC_XTEA, Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_XTEA
18
19 const struct ltc_cipher_descriptor xtea_desc =
20 {
21 "xtea",
22 1,
23 16, 16, 8, 32,
24 &xtea_setup,
25 &xtea_ecb_encrypt,
26 &xtea_ecb_decrypt,
27 &xtea_test,
28 &xtea_done,
29 &xtea_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
34 {
35 unsigned long x, sum, K[4];
36
37 LTC_ARGCHK(key != NULL);
38 LTC_ARGCHK(skey != NULL);
39
40 /* check arguments */
41 if (keylen != 16) {
42 return CRYPT_INVALID_KEYSIZE;
43 }
44
45 if (num_rounds != 0 && num_rounds != 32) {
46 return CRYPT_INVALID_ROUNDS;
47 }
48
49 /* load key */
50 LOAD32H(K[0], key+0);
51 LOAD32H(K[1], key+4);
52 LOAD32H(K[2], key+8);
53 LOAD32H(K[3], key+12);
54
55 for (x = sum = 0; x < 32; x++) {
56 skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL;
57 sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL;
58 skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL;
59 }
60
61 #ifdef LTC_CLEAN_STACK
62 zeromem(&K, sizeof(K));
63 #endif
64
65 return CRYPT_OK;
66 }
67
68 /**
69 Encrypts a block of text with LTC_XTEA
70 @param pt The input plaintext (8 bytes)
71 @param ct The output ciphertext (8 bytes)
72 @param skey The key as scheduled
73 @return CRYPT_OK if successful
74 */
75 int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
76 {
77 unsigned long y, z;
78 int r;
79
80 LTC_ARGCHK(pt != NULL);
81 LTC_ARGCHK(ct != NULL);
82 LTC_ARGCHK(skey != NULL);
83
84 LOAD32H(y, &pt[0]);
85 LOAD32H(z, &pt[4]);
86 for (r = 0; r < 32; r += 4) {
87 y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL;
88 z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL;
89
90 y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+1])) & 0xFFFFFFFFUL;
91 z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+1])) & 0xFFFFFFFFUL;
92
93 y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+2])) & 0xFFFFFFFFUL;
94 z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+2])) & 0xFFFFFFFFUL;
95
96 y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+3])) & 0xFFFFFFFFUL;
97 z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+3])) & 0xFFFFFFFFUL;
98 }
99 STORE32H(y, &ct[0]);
100 STORE32H(z, &ct[4]);
101 return CRYPT_OK;
102 }
103
104 /**
105 Decrypts a block of text with LTC_XTEA
106 @param ct The input ciphertext (8 bytes)
107 @param pt The output plaintext (8 bytes)
108 @param skey The key as scheduled
109 @return CRYPT_OK if successful
110 */
111 int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
112 {
113 unsigned long y, z;
114 int r;
115
116 LTC_ARGCHK(pt != NULL);
117 LTC_ARGCHK(ct != NULL);
118 LTC_ARGCHK(skey != NULL);
119
120 LOAD32H(y, &ct[0]);
121 LOAD32H(z, &ct[4]);
122 for (r = 31; r >= 0; r -= 4) {
123 z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL;
124 y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL;
125
126 z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-1])) & 0xFFFFFFFFUL;
127 y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-1])) & 0xFFFFFFFFUL;
128
129 z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-2])) & 0xFFFFFFFFUL;
130 y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-2])) & 0xFFFFFFFFUL;
131
132 z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-3])) & 0xFFFFFFFFUL;
133 y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-3])) & 0xFFFFFFFFUL;
134 }
135 STORE32H(y, &pt[0]);
136 STORE32H(z, &pt[4]);
137 return CRYPT_OK;
138 }
139
140 /**
141 Performs a self-test of the LTC_XTEA block cipher
142 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
143 */
144 int xtea_test(void)
145 {
146 #ifndef LTC_TEST
147 return CRYPT_NOP;
148 #else
149 static const struct {
150 unsigned char key[16], pt[8], ct[8];
151 } tests[] = {
152 {
153 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
155 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
156 { 0xde, 0xe9, 0xd4, 0xd8, 0xf7, 0x13, 0x1e, 0xd9 }
157 }, {
158 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
159 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04 },
160 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
161 { 0xa5, 0x97, 0xab, 0x41, 0x76, 0x01, 0x4d, 0x72 }
162 }, {
163 { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
164 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06 },
165 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02 },
166 { 0xb1, 0xfd, 0x5d, 0xa9, 0xcc, 0x6d, 0xc9, 0xdc }
167 }, {
168 { 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
169 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
170 { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
171 { 0x70, 0x4b, 0x31, 0x34, 0x47, 0x44, 0xdf, 0xab }
172 }, {
173 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
174 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
175 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
176 { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }
177 }, {
178 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
179 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
180 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
181 { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }
182 }, {
183 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
184 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
185 { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
186 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
187 }, {
188 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
190 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
191 { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }
192 }, {
193 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
195 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
196 { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }
197 }, {
198 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
200 { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 },
201 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
202 }
203 };
204 unsigned char tmp[2][8];
205 symmetric_key skey;
206 int i, err, y;
207 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
208 zeromem(&skey, sizeof(skey));
209 if ((err = xtea_setup(tests[i].key, 16, 0, &skey)) != CRYPT_OK) {
210 return err;
211 }
212 xtea_ecb_encrypt(tests[i].pt, tmp[0], &skey);
213 xtea_ecb_decrypt(tmp[0], tmp[1], &skey);
214
215 if (XMEMCMP(tmp[0], tests[i].ct, 8) != 0 || XMEMCMP(tmp[1], tests[i].pt, 8) != 0) {
216 #if 0
217 printf("\n\nTest %d failed\n", i);
218 if (XMEMCMP(tmp[0], tests[i].ct, 8)) {
219 printf("CT: ");
220 for (i = 0; i < 8; i++) {
221 printf("%02x ", tmp[0][i]);
222 }
223 printf("\n");
224 } else {
225 printf("PT: ");
226 for (i = 0; i < 8; i++) {
227 printf("%02x ", tmp[1][i]);
228 }
229 printf("\n");
230 }
231 #endif
232 return CRYPT_FAIL_TESTVECTOR;
233 }
234
235 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
236 for (y = 0; y < 8; y++) tmp[0][y] = 0;
237 for (y = 0; y < 1000; y++) xtea_ecb_encrypt(tmp[0], tmp[0], &skey);
238 for (y = 0; y < 1000; y++) xtea_ecb_decrypt(tmp[0], tmp[0], &skey);
239 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
240 } /* for */
241
242 return CRYPT_OK;
243 #endif
244 }
245
246 /** Terminate the context
247 @param skey The scheduled key
248 */
249 void xtea_done(symmetric_key *skey)
250 {
251 }
252
253 /**
254 Gets suitable key size
255 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
256 @return CRYPT_OK if the input key size is acceptable.
257 */
258 int xtea_keysize(int *keysize)
259 {
260 LTC_ARGCHK(keysize != NULL);
261 if (*keysize < 16) {
262 return CRYPT_INVALID_KEYSIZE;
263 }
264 *keysize = 16;
265 return CRYPT_OK;
266 }
267
268
269 #endif
270
271
272
273
274 /* $Source$ */
275 /* $Revision$ */
276 /* $Date$ */
+0
-351
libtom-src/encauth/ccm/ccm_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ccm_memory.c
14 CCM support, process a block of memory, Tom St Denis
15 */
16
17 #ifdef LTC_CCM_MODE
18
19 /**
20 CCM encrypt/decrypt and produce an authentication tag
21 @param cipher The index of the cipher desired
22 @param key The secret key to use
23 @param keylen The length of the secret key (octets)
24 @param uskey A previously scheduled key [optional can be NULL]
25 @param nonce The session nonce [use once]
26 @param noncelen The length of the nonce
27 @param header The header for the session
28 @param headerlen The length of the header (octets)
29 @param pt [out] The plaintext
30 @param ptlen The length of the plaintext (octets)
31 @param ct [out] The ciphertext
32 @param tag [out] The destination tag
33 @param taglen [in/out] The max size and resulting size of the authentication tag
34 @param direction Encrypt or Decrypt direction (0 or 1)
35 @return CRYPT_OK if successful
36 */
37 int ccm_memory(int cipher,
38 const unsigned char *key, unsigned long keylen,
39 symmetric_key *uskey,
40 const unsigned char *nonce, unsigned long noncelen,
41 const unsigned char *header, unsigned long headerlen,
42 unsigned char *pt, unsigned long ptlen,
43 unsigned char *ct,
44 unsigned char *tag, unsigned long *taglen,
45 int direction)
46 {
47 unsigned char PAD[16], ctr[16], CTRPAD[16], b;
48 symmetric_key *skey;
49 int err;
50 unsigned long len, L, x, y, z, CTRlen;
51
52 if (uskey == NULL) {
53 LTC_ARGCHK(key != NULL);
54 }
55 LTC_ARGCHK(nonce != NULL);
56 if (headerlen > 0) {
57 LTC_ARGCHK(header != NULL);
58 }
59 LTC_ARGCHK(pt != NULL);
60 LTC_ARGCHK(ct != NULL);
61 LTC_ARGCHK(tag != NULL);
62 LTC_ARGCHK(taglen != NULL);
63
64 #ifdef LTC_FAST
65 if (16 % sizeof(LTC_FAST_TYPE)) {
66 return CRYPT_INVALID_ARG;
67 }
68 #endif
69
70 /* check cipher input */
71 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
72 return err;
73 }
74 if (cipher_descriptor[cipher].block_length != 16) {
75 return CRYPT_INVALID_CIPHER;
76 }
77
78 /* make sure the taglen is even and <= 16 */
79 *taglen &= ~1;
80 if (*taglen > 16) {
81 *taglen = 16;
82 }
83
84 /* can't use < 4 */
85 if (*taglen < 4) {
86 return CRYPT_INVALID_ARG;
87 }
88
89 /* is there an accelerator? */
90 if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
91 return cipher_descriptor[cipher].accel_ccm_memory(
92 key, keylen,
93 uskey,
94 nonce, noncelen,
95 header, headerlen,
96 pt, ptlen,
97 ct,
98 tag, taglen,
99 direction);
100 }
101
102 /* let's get the L value */
103 len = ptlen;
104 L = 0;
105 while (len) {
106 ++L;
107 len >>= 8;
108 }
109 if (L <= 1) {
110 L = 2;
111 }
112
113 /* increase L to match the nonce len */
114 noncelen = (noncelen > 13) ? 13 : noncelen;
115 if ((15 - noncelen) > L) {
116 L = 15 - noncelen;
117 }
118
119 /* decrease noncelen to match L */
120 if ((noncelen + L) > 15) {
121 noncelen = 15 - L;
122 }
123
124 /* allocate mem for the symmetric key */
125 if (uskey == NULL) {
126 skey = XMALLOC(sizeof(*skey));
127 if (skey == NULL) {
128 return CRYPT_MEM;
129 }
130
131 /* initialize the cipher */
132 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
133 XFREE(skey);
134 return err;
135 }
136 } else {
137 skey = uskey;
138 }
139
140 /* form B_0 == flags | Nonce N | l(m) */
141 x = 0;
142 PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
143 (((*taglen - 2)>>1)<<3) |
144 (L-1));
145
146 /* nonce */
147 for (y = 0; y < (16 - (L + 1)); y++) {
148 PAD[x++] = nonce[y];
149 }
150
151 /* store len */
152 len = ptlen;
153
154 /* shift len so the upper bytes of len are the contents of the length */
155 for (y = L; y < 4; y++) {
156 len <<= 8;
157 }
158
159 /* store l(m) (only store 32-bits) */
160 for (y = 0; L > 4 && (L-y)>4; y++) {
161 PAD[x++] = 0;
162 }
163 for (; y < L; y++) {
164 PAD[x++] = (unsigned char)((len >> 24) & 255);
165 len <<= 8;
166 }
167
168 /* encrypt PAD */
169 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
170 goto error;
171 }
172
173 /* handle header */
174 if (headerlen > 0) {
175 x = 0;
176
177 /* store length */
178 if (headerlen < ((1UL<<16) - (1UL<<8))) {
179 PAD[x++] ^= (headerlen>>8) & 255;
180 PAD[x++] ^= headerlen & 255;
181 } else {
182 PAD[x++] ^= 0xFF;
183 PAD[x++] ^= 0xFE;
184 PAD[x++] ^= (headerlen>>24) & 255;
185 PAD[x++] ^= (headerlen>>16) & 255;
186 PAD[x++] ^= (headerlen>>8) & 255;
187 PAD[x++] ^= headerlen & 255;
188 }
189
190 /* now add the data */
191 for (y = 0; y < headerlen; y++) {
192 if (x == 16) {
193 /* full block so let's encrypt it */
194 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
195 goto error;
196 }
197 x = 0;
198 }
199 PAD[x++] ^= header[y];
200 }
201
202 /* remainder? */
203 if (x != 0) {
204 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
205 goto error;
206 }
207 }
208 }
209
210 /* setup the ctr counter */
211 x = 0;
212
213 /* flags */
214 ctr[x++] = (unsigned char)L-1;
215
216 /* nonce */
217 for (y = 0; y < (16 - (L+1)); ++y) {
218 ctr[x++] = nonce[y];
219 }
220 /* offset */
221 while (x < 16) {
222 ctr[x++] = 0;
223 }
224
225 x = 0;
226 CTRlen = 16;
227
228 /* now handle the PT */
229 if (ptlen > 0) {
230 y = 0;
231 #ifdef LTC_FAST
232 if (ptlen & ~15) {
233 if (direction == CCM_ENCRYPT) {
234 for (; y < (ptlen & ~15); y += 16) {
235 /* increment the ctr? */
236 for (z = 15; z > 15-L; z--) {
237 ctr[z] = (ctr[z] + 1) & 255;
238 if (ctr[z]) break;
239 }
240 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
241 goto error;
242 }
243
244 /* xor the PT against the pad first */
245 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
246 *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
247 *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
248 }
249 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
250 goto error;
251 }
252 }
253 } else {
254 for (; y < (ptlen & ~15); y += 16) {
255 /* increment the ctr? */
256 for (z = 15; z > 15-L; z--) {
257 ctr[z] = (ctr[z] + 1) & 255;
258 if (ctr[z]) break;
259 }
260 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
261 goto error;
262 }
263
264 /* xor the PT against the pad last */
265 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
266 *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
267 *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
268 }
269 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
270 goto error;
271 }
272 }
273 }
274 }
275 #endif
276
277 for (; y < ptlen; y++) {
278 /* increment the ctr? */
279 if (CTRlen == 16) {
280 for (z = 15; z > 15-L; z--) {
281 ctr[z] = (ctr[z] + 1) & 255;
282 if (ctr[z]) break;
283 }
284 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
285 goto error;
286 }
287 CTRlen = 0;
288 }
289
290 /* if we encrypt we add the bytes to the MAC first */
291 if (direction == CCM_ENCRYPT) {
292 b = pt[y];
293 ct[y] = b ^ CTRPAD[CTRlen++];
294 } else {
295 b = ct[y] ^ CTRPAD[CTRlen++];
296 pt[y] = b;
297 }
298
299 if (x == 16) {
300 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
301 goto error;
302 }
303 x = 0;
304 }
305 PAD[x++] ^= b;
306 }
307
308 if (x != 0) {
309 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
310 goto error;
311 }
312 }
313 }
314
315 /* setup CTR for the TAG (zero the count) */
316 for (y = 15; y > 15 - L; y--) {
317 ctr[y] = 0x00;
318 }
319 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
320 goto error;
321 }
322
323 if (skey != uskey) {
324 cipher_descriptor[cipher].done(skey);
325 }
326
327 /* store the TAG */
328 for (x = 0; x < 16 && x < *taglen; x++) {
329 tag[x] = PAD[x] ^ CTRPAD[x];
330 }
331 *taglen = x;
332
333 #ifdef LTC_CLEAN_STACK
334 zeromem(skey, sizeof(*skey));
335 zeromem(PAD, sizeof(PAD));
336 zeromem(CTRPAD, sizeof(CTRPAD));
337 #endif
338 error:
339 if (skey != uskey) {
340 XFREE(skey);
341 }
342
343 return err;
344 }
345
346 #endif
347
348 /* $Source$ */
349 /* $Revision$ */
350 /* $Date$ */
+0
-383
libtom-src/encauth/ccm/ccm_memory_ex.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ccm_memory.c
14 CCM support, process a block of memory, Tom St Denis
15 */
16
17 #ifdef CCM_MODE
18
19 /**
20 CCM encrypt/decrypt and produce an authentication tag
21 @param cipher The index of the cipher desired
22 @param key The secret key to use
23 @param keylen The length of the secret key (octets)
24 @param uskey A previously scheduled key [optional can be NULL]
25 @param nonce The session nonce [use once]
26 @param noncelen The length of the nonce
27 @param header The header for the session
28 @param headerlen The length of the header (octets)
29 @param pt [out] The plaintext
30 @param ptlen The length of the plaintext (octets)
31 @param ct [out] The ciphertext
32 @param tag [out] The destination tag
33 @param taglen [in/out] The max size and resulting size of the authentication tag
34 @param direction Encrypt or Decrypt direction (0 or 1)
35 @return CRYPT_OK if successful
36 */
37 int ccm_memory_ex(int cipher,
38 const unsigned char *key, unsigned long keylen,
39 symmetric_key *uskey,
40 const unsigned char *nonce, unsigned long noncelen,
41 const unsigned char *header, unsigned long headerlen,
42 unsigned char *pt, unsigned long ptlen,
43 unsigned char *ct,
44 unsigned char *tag, unsigned long *taglen,
45 int direction,
46 const unsigned char *B_0,
47 const unsigned char *CTR,
48 int ctrwidth)
49 {
50 unsigned char PAD[16], ctr[16], CTRPAD[16], ctrcopy[16], b;
51 symmetric_key *skey;
52 int err;
53 unsigned long len, L, x, y, z, CTRlen;
54
55 if (uskey == NULL) {
56 LTC_ARGCHK(key != NULL);
57 }
58 LTC_ARGCHK(nonce != NULL);
59 if (headerlen > 0) {
60 LTC_ARGCHK(header != NULL);
61 }
62 LTC_ARGCHK(pt != NULL);
63 LTC_ARGCHK(ct != NULL);
64 LTC_ARGCHK(tag != NULL);
65 LTC_ARGCHK(taglen != NULL);
66
67 #ifdef LTC_FAST
68 if (16 % sizeof(LTC_FAST_TYPE)) {
69 return CRYPT_INVALID_ARG;
70 }
71 #endif
72
73 /* check cipher input */
74 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
75 return err;
76 }
77 if (cipher_descriptor[cipher].block_length != 16) {
78 return CRYPT_INVALID_CIPHER;
79 }
80
81 /* make sure the taglen is even and <= 16 */
82 *taglen &= ~1;
83 if (*taglen > 16) {
84 *taglen = 16;
85 }
86
87 /* can't use < 4 */
88 if (*taglen < 4) {
89 return CRYPT_INVALID_ARG;
90 }
91
92 /* is there an accelerator? */
93 if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
94 return cipher_descriptor[cipher].accel_ccm_memory(
95 key, keylen,
96 uskey,
97 nonce, noncelen,
98 header, headerlen,
99 pt, ptlen,
100 ct,
101 tag, taglen,
102 direction);
103 }
104
105 /* let's get the L value */
106 len = ptlen;
107 L = 0;
108 while (len) {
109 ++L;
110 len >>= 8;
111 }
112 if (L <= 1) {
113 L = 2;
114 }
115
116 /* increase L to match the nonce len */
117 noncelen = (noncelen > 13) ? 13 : noncelen;
118 if ((15 - noncelen) > L) {
119 L = 15 - noncelen;
120 }
121
122 /* decrease noncelen to match L */
123 if ((noncelen + L) > 15) {
124 noncelen = 15 - L;
125 }
126
127 /* allocate mem for the symmetric key */
128 if (uskey == NULL) {
129 skey = XMALLOC(sizeof(*skey));
130 if (skey == NULL) {
131 return CRYPT_MEM;
132 }
133
134 /* initialize the cipher */
135 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
136 XFREE(skey);
137 return err;
138 }
139 } else {
140 skey = uskey;
141 }
142
143 /* form B_0 == flags | Nonce N | l(m) */
144 x = 0;
145
146 if (B_0 == NULL) {
147 PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
148 (((*taglen - 2)>>1)<<3) |
149 (L-1));
150
151 /* nonce */
152 for (y = 0; y < (16 - (L + 1)); y++) {
153 PAD[x++] = nonce[y];
154 }
155
156 /* store len */
157 len = ptlen;
158
159 /* shift len so the upper bytes of len are the contents of the length */
160 for (y = L; y < 4; y++) {
161 len <<= 8;
162 }
163
164 /* store l(m) (only store 32-bits) */
165 for (y = 0; L > 4 && (L-y)>4; y++) {
166 PAD[x++] = 0;
167 }
168 for (; y < L; y++) {
169 PAD[x++] = (unsigned char)((len >> 24) & 255);
170 len <<= 8;
171 }
172
173 } else {
174 // B_0 != NULL
175 XMEMCPY(PAD, B_0, 16);
176 }
177
178 /* encrypt PAD */
179 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
180 goto error;
181 }
182
183 /* handle header */
184 if (headerlen > 0) {
185 x = 0;
186
187 #if 0
188 /* store length */
189 if (headerlen < ((1UL<<16) - (1UL<<8))) {
190 PAD[x++] ^= (headerlen>>8) & 255;
191 PAD[x++] ^= headerlen & 255;
192 } else {
193 PAD[x++] ^= 0xFF;
194 PAD[x++] ^= 0xFE;
195 PAD[x++] ^= (headerlen>>24) & 255;
196 PAD[x++] ^= (headerlen>>16) & 255;
197 PAD[x++] ^= (headerlen>>8) & 255;
198 PAD[x++] ^= headerlen & 255;
199 }
200 #endif
201
202 /* now add the data */
203 for (y = 0; y < headerlen; y++) {
204 if (x == 16) {
205 /* full block so let's encrypt it */
206 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
207 goto error;
208 }
209 x = 0;
210 }
211 PAD[x++] ^= header[y];
212 }
213
214 /* remainder? */
215 if (x != 0) {
216 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
217 goto error;
218 }
219 }
220 }
221
222 /* setup the ctr counter */
223 if (CTR == NULL) {
224 x = 0;
225
226 /* flags */
227 ctr[x++] = (unsigned char)L-1;
228
229 /* nonce */
230 for (y = 0; y < (16 - (L+1)); ++y) {
231 ctr[x++] = nonce[y];
232 }
233 /* offset */
234 while (x < 16) {
235 ctr[x++] = 0;
236 }
237 } else {
238 XMEMCPY(ctr, CTR, 16);
239 }
240
241 x = 0;
242 CTRlen = 16;
243
244 /* now handle the PT */
245 if (ptlen > 0) {
246 y = 0;
247 #ifdef LTC_FAST2
248 if (ptlen & ~15) {
249 if (direction == CCM_ENCRYPT) {
250 for (; y < (ptlen & ~15); y += 16) {
251 /* increment the ctr? */
252 for (z = 15; z > 15-ctrwidth; z--) {
253 ctr[z] = (ctr[z] + 1) & 255;
254 if (ctr[z]) break;
255 }
256 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
257 goto error;
258 }
259
260 /* xor the PT against the pad first */
261 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
262 *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
263 *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
264 }
265 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
266 goto error;
267 }
268 }
269 } else {
270 for (; y < (ptlen & ~15); y += 16) {
271 /* increment the ctr? */
272 for (z = 15; z > 15-ctrwidth; z--) {
273 ctr[z] = (ctr[z] + 1) & 255;
274 if (ctr[z]) break;
275 }
276 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
277 goto error;
278 }
279
280 /* xor the PT against the pad last */
281 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
282 *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
283 *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
284 }
285 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
286 goto error;
287 }
288 }
289 }
290 }
291 #endif
292
293 for (; y < ptlen; y++) {
294 /* increment the ctr? */
295 if (CTRlen == 16) {
296 for (z = 15; z > 15-ctrwidth; z--) {
297 ctr[z] = (ctr[z] + 1) & 255;
298 if (ctr[z]) break;
299 }
300 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
301 goto error;
302 }
303 CTRlen = 0;
304 }
305
306 /* if we encrypt we add the bytes to the MAC first */
307 if (direction == CCM_ENCRYPT) {
308 b = pt[y];
309 ct[y] = b ^ CTRPAD[CTRlen++];
310 } else {
311 b = ct[y] ^ CTRPAD[CTRlen++];
312 pt[y] = b;
313 }
314
315 if (x == 16) {
316 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
317 goto error;
318 }
319 x = 0;
320 }
321 PAD[x++] ^= b;
322 }
323
324 if (x != 0) {
325 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
326 goto error;
327 }
328 }
329 }
330
331 // grab the CTR
332 memcpy(ctrcopy, ctr, 16);
333
334 /* setup CTR for the TAG (zero the count) */
335 if (CTR == NULL) {
336 for (y = 15; y > 15 - L; y--) {
337 ctr[y] = 0x00;
338 }
339 } else {
340 XMEMCPY(ctr, CTR, 16);
341 }
342
343 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
344 goto error;
345 }
346
347 if (skey != uskey) {
348 cipher_descriptor[cipher].done(skey);
349 }
350
351 /* store the TAG */
352 for (x = 0; x < 16 && x < *taglen; x++) {
353 tag[x] = PAD[x] ^ CTRPAD[x];
354 }
355 *taglen = x;
356
357 if (CTR != NULL) {
358 for (z = 15; z > 15-ctrwidth; z--) {
359 ctrcopy[z] = (ctrcopy[z] + 1) & 255;
360 if (ctrcopy[z]) break;
361 }
362 memcpy(CTR, ctrcopy, 16);
363 }
364
365 #ifdef LTC_CLEAN_STACK
366 zeromem(skey, sizeof(*skey));
367 zeromem(PAD, sizeof(PAD));
368 zeromem(CTRPAD, sizeof(CTRPAD));
369 #endif
370 error:
371 if (skey != uskey) {
372 XFREE(skey);
373 }
374
375 return err;
376 }
377
378 #endif
379
380 /* $Source$ */
381 /* $Revision$ */
382 /* $Date$ */
+0
-38
libtom-src/encauth/eax/eax_addheader.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @file eax_addheader.c
12 EAX implementation, add meta-data, by Tom St Denis
13 */
14 #include "tomcrypt.h"
15
16 #ifdef LTC_EAX_MODE
17
18 /**
19 add header (metadata) to the stream
20 @param eax The current EAX state
21 @param header The header (meta-data) data you wish to add to the state
22 @param length The length of the header data
23 @return CRYPT_OK if successful
24 */
25 int eax_addheader(eax_state *eax, const unsigned char *header,
26 unsigned long length)
27 {
28 LTC_ARGCHK(eax != NULL);
29 LTC_ARGCHK(header != NULL);
30 return omac_process(&eax->headeromac, header, length);
31 }
32
33 #endif
34
35 /* $Source$ */
36 /* $Revision$ */
37 /* $Date$ */
+0
-50
libtom-src/encauth/eax/eax_decrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_decrypt.c
13 EAX implementation, decrypt block, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Decrypt data with the EAX protocol
21 @param eax The EAX state
22 @param ct The ciphertext
23 @param pt [out] The plaintext
24 @param length The length (octets) of the ciphertext
25 @return CRYPT_OK if successful
26 */
27 int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt,
28 unsigned long length)
29 {
30 int err;
31
32 LTC_ARGCHK(eax != NULL);
33 LTC_ARGCHK(pt != NULL);
34 LTC_ARGCHK(ct != NULL);
35
36 /* omac ciphertext */
37 if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) {
38 return err;
39 }
40
41 /* decrypt */
42 return ctr_decrypt(ct, pt, length, &eax->ctr);
43 }
44
45 #endif
46
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
+0
-108
libtom-src/encauth/eax/eax_decrypt_verify_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_decrypt_verify_memory.c
13 EAX implementation, decrypt block of memory, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Decrypt a block of memory and verify the provided MAC tag with EAX
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the key (octets)
24 @param nonce The nonce data (use once) for the session
25 @param noncelen The length of the nonce data.
26 @param header The session header data
27 @param headerlen The length of the header (octets)
28 @param ct The ciphertext
29 @param ctlen The length of the ciphertext (octets)
30 @param pt [out] The plaintext
31 @param tag The authentication tag provided by the encoder
32 @param taglen [in/out] The length of the tag (octets)
33 @param stat [out] The result of the decryption (1==valid tag, 0==invalid)
34 @return CRYPT_OK if successful regardless of the resulting tag comparison
35 */
36 int eax_decrypt_verify_memory(int cipher,
37 const unsigned char *key, unsigned long keylen,
38 const unsigned char *nonce, unsigned long noncelen,
39 const unsigned char *header, unsigned long headerlen,
40 const unsigned char *ct, unsigned long ctlen,
41 unsigned char *pt,
42 unsigned char *tag, unsigned long taglen,
43 int *stat)
44 {
45 int err;
46 eax_state *eax;
47 unsigned char *buf;
48 unsigned long buflen;
49
50 LTC_ARGCHK(stat != NULL);
51 LTC_ARGCHK(key != NULL);
52 LTC_ARGCHK(pt != NULL);
53 LTC_ARGCHK(ct != NULL);
54 LTC_ARGCHK(tag != NULL);
55
56 /* default to zero */
57 *stat = 0;
58
59 /* allocate ram */
60 buf = XMALLOC(taglen);
61 eax = XMALLOC(sizeof(*eax));
62 if (eax == NULL || buf == NULL) {
63 if (eax != NULL) {
64 XFREE(eax);
65 }
66 if (buf != NULL) {
67 XFREE(buf);
68 }
69 return CRYPT_MEM;
70 }
71
72 if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
73 goto LBL_ERR;
74 }
75
76 if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79
80 buflen = taglen;
81 if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) {
82 goto LBL_ERR;
83 }
84
85 /* compare tags */
86 if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) {
87 *stat = 1;
88 }
89
90 err = CRYPT_OK;
91 LBL_ERR:
92 #ifdef LTC_CLEAN_STACK
93 zeromem(buf, taglen);
94 zeromem(eax, sizeof(*eax));
95 #endif
96
97 XFREE(eax);
98 XFREE(buf);
99
100 return err;
101 }
102
103 #endif
104
105 /* $Source$ */
106 /* $Revision$ */
107 /* $Date$ */
+0
-94
libtom-src/encauth/eax/eax_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_done.c
13 EAX implementation, terminate session, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Terminate an EAX session and get the tag.
21 @param eax The EAX state
22 @param tag [out] The destination of the authentication tag
23 @param taglen [in/out] The max length and resulting length of the authentication tag
24 @return CRYPT_OK if successful
25 */
26 int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen)
27 {
28 int err;
29 unsigned char *headermac, *ctmac;
30 unsigned long x, len;
31
32 LTC_ARGCHK(eax != NULL);
33 LTC_ARGCHK(tag != NULL);
34 LTC_ARGCHK(taglen != NULL);
35
36 /* allocate ram */
37 headermac = XMALLOC(MAXBLOCKSIZE);
38 ctmac = XMALLOC(MAXBLOCKSIZE);
39
40 if (headermac == NULL || ctmac == NULL) {
41 if (headermac != NULL) {
42 XFREE(headermac);
43 }
44 if (ctmac != NULL) {
45 XFREE(ctmac);
46 }
47 return CRYPT_MEM;
48 }
49
50 /* finish ctomac */
51 len = MAXBLOCKSIZE;
52 if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) {
53 goto LBL_ERR;
54 }
55
56 /* finish headeromac */
57
58 /* note we specifically don't reset len so the two lens are minimal */
59
60 if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) {
61 goto LBL_ERR;
62 }
63
64 /* terminate the CTR chain */
65 if ((err = ctr_done(&eax->ctr)) != CRYPT_OK) {
66 goto LBL_ERR;
67 }
68
69 /* compute N xor H xor C */
70 for (x = 0; x < len && x < *taglen; x++) {
71 tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x];
72 }
73 *taglen = x;
74
75 err = CRYPT_OK;
76 LBL_ERR:
77 #ifdef LTC_CLEAN_STACK
78 zeromem(ctmac, MAXBLOCKSIZE);
79 zeromem(headermac, MAXBLOCKSIZE);
80 zeromem(eax, sizeof(*eax));
81 #endif
82
83 XFREE(ctmac);
84 XFREE(headermac);
85
86 return err;
87 }
88
89 #endif
90
91 /* $Source$ */
92 /* $Revision$ */
93 /* $Date$ */
+0
-51
libtom-src/encauth/eax/eax_encrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_encrypt.c
13 EAX implementation, encrypt block by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Encrypt with EAX a block of data.
21 @param eax The EAX state
22 @param pt The plaintext to encrypt
23 @param ct [out] The ciphertext as encrypted
24 @param length The length of the plaintext (octets)
25 @return CRYPT_OK if successful
26 */
27 int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct,
28 unsigned long length)
29 {
30 int err;
31
32 LTC_ARGCHK(eax != NULL);
33 LTC_ARGCHK(pt != NULL);
34 LTC_ARGCHK(ct != NULL);
35
36 /* encrypt */
37 if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) {
38 return err;
39 }
40
41 /* omac ciphertext */
42 return omac_process(&eax->ctomac, ct, length);
43 }
44
45 #endif
46
47
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
+0
-82
libtom-src/encauth/eax/eax_encrypt_authenticate_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_encrypt_authenticate_memory.c
13 EAX implementation, encrypt a block of memory, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 EAX encrypt and produce an authentication tag
21 @param cipher The index of the cipher desired
22 @param key The secret key to use
23 @param keylen The length of the secret key (octets)
24 @param nonce The session nonce [use once]
25 @param noncelen The length of the nonce
26 @param header The header for the session
27 @param headerlen The length of the header (octets)
28 @param pt The plaintext
29 @param ptlen The length of the plaintext (octets)
30 @param ct [out] The ciphertext
31 @param tag [out] The destination tag
32 @param taglen [in/out] The max size and resulting size of the authentication tag
33 @return CRYPT_OK if successful
34 */
35 int eax_encrypt_authenticate_memory(int cipher,
36 const unsigned char *key, unsigned long keylen,
37 const unsigned char *nonce, unsigned long noncelen,
38 const unsigned char *header, unsigned long headerlen,
39 const unsigned char *pt, unsigned long ptlen,
40 unsigned char *ct,
41 unsigned char *tag, unsigned long *taglen)
42 {
43 int err;
44 eax_state *eax;
45
46 LTC_ARGCHK(key != NULL);
47 LTC_ARGCHK(pt != NULL);
48 LTC_ARGCHK(ct != NULL);
49 LTC_ARGCHK(tag != NULL);
50 LTC_ARGCHK(taglen != NULL);
51
52 eax = XMALLOC(sizeof(*eax));
53
54 if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57
58 if ((err = eax_encrypt(eax, pt, ct, ptlen)) != CRYPT_OK) {
59 goto LBL_ERR;
60 }
61
62 if ((err = eax_done(eax, tag, taglen)) != CRYPT_OK) {
63 goto LBL_ERR;
64 }
65
66 err = CRYPT_OK;
67 LBL_ERR:
68 #ifdef LTC_CLEAN_STACK
69 zeromem(eax, sizeof(*eax));
70 #endif
71
72 XFREE(eax);
73
74 return err;
75 }
76
77 #endif
78
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
+0
-144
libtom-src/encauth/eax/eax_init.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_init.c
13 EAX implementation, initialized EAX state, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Initialized an EAX state
21 @param eax [out] The EAX state to initialize
22 @param cipher The index of the desired cipher
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param nonce The use-once nonce for the session
26 @param noncelen The length of the nonce (octets)
27 @param header The header for the EAX state
28 @param headerlen The header length (octets)
29 @return CRYPT_OK if successful
30 */
31 int eax_init(eax_state *eax, int cipher,
32 const unsigned char *key, unsigned long keylen,
33 const unsigned char *nonce, unsigned long noncelen,
34 const unsigned char *header, unsigned long headerlen)
35 {
36 unsigned char *buf;
37 int err, blklen;
38 omac_state *omac;
39 unsigned long len;
40
41
42 LTC_ARGCHK(eax != NULL);
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(nonce != NULL);
45 if (headerlen > 0) {
46 LTC_ARGCHK(header != NULL);
47 }
48
49 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
50 return err;
51 }
52 blklen = cipher_descriptor[cipher].block_length;
53
54 /* allocate ram */
55 buf = XMALLOC(MAXBLOCKSIZE);
56 omac = XMALLOC(sizeof(*omac));
57
58 if (buf == NULL || omac == NULL) {
59 if (buf != NULL) {
60 XFREE(buf);
61 }
62 if (omac != NULL) {
63 XFREE(omac);
64 }
65 return CRYPT_MEM;
66 }
67
68 /* N = LTC_OMAC_0K(nonce) */
69 zeromem(buf, MAXBLOCKSIZE);
70 if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
71 goto LBL_ERR;
72 }
73
74 /* omac the [0]_n */
75 if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) {
76 goto LBL_ERR;
77 }
78 /* omac the nonce */
79 if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) {
80 goto LBL_ERR;
81 }
82 /* store result */
83 len = sizeof(eax->N);
84 if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) {
85 goto LBL_ERR;
86 }
87
88 /* H = LTC_OMAC_1K(header) */
89 zeromem(buf, MAXBLOCKSIZE);
90 buf[blklen - 1] = 1;
91
92 if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) {
93 goto LBL_ERR;
94 }
95
96 /* omac the [1]_n */
97 if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) {
98 goto LBL_ERR;
99 }
100 /* omac the header */
101 if (headerlen != 0) {
102 if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) {
103 goto LBL_ERR;
104 }
105 }
106
107 /* note we don't finish the headeromac, this allows us to add more header later */
108
109 /* setup the CTR mode */
110 if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) {
111 goto LBL_ERR;
112 }
113
114 /* setup the LTC_OMAC for the ciphertext */
115 if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) {
116 goto LBL_ERR;
117 }
118
119 /* omac [2]_n */
120 zeromem(buf, MAXBLOCKSIZE);
121 buf[blklen-1] = 2;
122 if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) {
123 goto LBL_ERR;
124 }
125
126 err = CRYPT_OK;
127 LBL_ERR:
128 #ifdef LTC_CLEAN_STACK
129 zeromem(buf, MAXBLOCKSIZE);
130 zeromem(omac, sizeof(*omac));
131 #endif
132
133 XFREE(omac);
134 XFREE(buf);
135
136 return err;
137 }
138
139 #endif
140
141 /* $Source$ */
142 /* $Revision$ */
143 /* $Date$ */
+0
-124
libtom-src/encauth/gcm/gcm_add_aad.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_add_aad.c
13 GCM implementation, Add AAD data to the stream, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Add AAD to the GCM state
21 @param gcm The GCM state
22 @param adata The additional authentication data to add to the GCM state
23 @param adatalen The length of the AAD data.
24 @return CRYPT_OK on success
25 */
26 int gcm_add_aad(gcm_state *gcm,
27 const unsigned char *adata, unsigned long adatalen)
28 {
29 unsigned long x;
30 int err;
31 #ifdef LTC_FAST
32 unsigned long y;
33 #endif
34
35 LTC_ARGCHK(gcm != NULL);
36 if (adatalen > 0) {
37 LTC_ARGCHK(adata != NULL);
38 }
39
40 if (gcm->buflen > 16 || gcm->buflen < 0) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* in IV mode? */
49 if (gcm->mode == LTC_GCM_MODE_IV) {
50 /* let's process the IV */
51 if (gcm->ivmode || gcm->buflen != 12) {
52 for (x = 0; x < (unsigned long)gcm->buflen; x++) {
53 gcm->X[x] ^= gcm->buf[x];
54 }
55 if (gcm->buflen) {
56 gcm->totlen += gcm->buflen * CONST64(8);
57 gcm_mult_h(gcm, gcm->X);
58 }
59
60 /* mix in the length */
61 zeromem(gcm->buf, 8);
62 STORE64H(gcm->totlen, gcm->buf+8);
63 for (x = 0; x < 16; x++) {
64 gcm->X[x] ^= gcm->buf[x];
65 }
66 gcm_mult_h(gcm, gcm->X);
67
68 /* copy counter out */
69 XMEMCPY(gcm->Y, gcm->X, 16);
70 zeromem(gcm->X, 16);
71 } else {
72 XMEMCPY(gcm->Y, gcm->buf, 12);
73 gcm->Y[12] = 0;
74 gcm->Y[13] = 0;
75 gcm->Y[14] = 0;
76 gcm->Y[15] = 1;
77 }
78 XMEMCPY(gcm->Y_0, gcm->Y, 16);
79 zeromem(gcm->buf, 16);
80 gcm->buflen = 0;
81 gcm->totlen = 0;
82 gcm->mode = LTC_GCM_MODE_AAD;
83 }
84
85 if (gcm->mode != LTC_GCM_MODE_AAD || gcm->buflen >= 16) {
86 return CRYPT_INVALID_ARG;
87 }
88
89 x = 0;
90 #ifdef LTC_FAST
91 if (gcm->buflen == 0) {
92 for (x = 0; x < (adatalen & ~15); x += 16) {
93 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
94 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&adata[x + y]));
95 }
96 gcm_mult_h(gcm, gcm->X);
97 gcm->totlen += 128;
98 }
99 adata += x;
100 }
101 #endif
102
103
104 /* start adding AAD data to the state */
105 for (; x < adatalen; x++) {
106 gcm->X[gcm->buflen++] ^= *adata++;
107
108 if (gcm->buflen == 16) {
109 /* GF mult it */
110 gcm_mult_h(gcm, gcm->X);
111 gcm->buflen = 0;
112 gcm->totlen += 128;
113 }
114 }
115
116 return CRYPT_OK;
117 }
118 #endif
119
120
121 /* $Source$ */
122 /* $Revision$ */
123 /* $Date$ */
+0
-94
libtom-src/encauth/gcm/gcm_add_iv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_add_iv.c
13 GCM implementation, add IV data to the state, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Add IV data to the GCM state
21 @param gcm The GCM state
22 @param IV The initial value data to add
23 @param IVlen The length of the IV
24 @return CRYPT_OK on success
25 */
26 int gcm_add_iv(gcm_state *gcm,
27 const unsigned char *IV, unsigned long IVlen)
28 {
29 unsigned long x, y;
30 int err;
31
32 LTC_ARGCHK(gcm != NULL);
33 if (IVlen > 0) {
34 LTC_ARGCHK(IV != NULL);
35 }
36
37 /* must be in IV mode */
38 if (gcm->mode != LTC_GCM_MODE_IV) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 if (gcm->buflen >= 16 || gcm->buflen < 0) {
43 return CRYPT_INVALID_ARG;
44 }
45
46 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
47 return err;
48 }
49
50
51 /* trip the ivmode flag */
52 if (IVlen + gcm->buflen > 12) {
53 gcm->ivmode |= 1;
54 }
55
56 x = 0;
57 #ifdef LTC_FAST
58 if (gcm->buflen == 0) {
59 for (x = 0; x < (IVlen & ~15); x += 16) {
60 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
61 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&IV[x + y]));
62 }
63 gcm_mult_h(gcm, gcm->X);
64 gcm->totlen += 128;
65 }
66 IV += x;
67 }
68 #endif
69
70 /* start adding IV data to the state */
71 for (; x < IVlen; x++) {
72 gcm->buf[gcm->buflen++] = *IV++;
73
74 if (gcm->buflen == 16) {
75 /* GF mult it */
76 for (y = 0; y < 16; y++) {
77 gcm->X[y] ^= gcm->buf[y];
78 }
79 gcm_mult_h(gcm, gcm->X);
80 gcm->buflen = 0;
81 gcm->totlen += 128;
82 }
83 }
84
85 return CRYPT_OK;
86 }
87
88 #endif
89
90
91 /* $Source$ */
92 /* $Revision$ */
93 /* $Date$ */
+0
-83
libtom-src/encauth/gcm/gcm_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_done.c
13 GCM implementation, Terminate the stream, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Terminate a GCM stream
21 @param gcm The GCM state
22 @param tag [out] The destination for the MAC tag
23 @param taglen [in/out] The length of the MAC tag
24 @return CRYPT_OK on success
25 */
26 int gcm_done(gcm_state *gcm,
27 unsigned char *tag, unsigned long *taglen)
28 {
29 unsigned long x;
30 int err;
31
32 LTC_ARGCHK(gcm != NULL);
33 LTC_ARGCHK(tag != NULL);
34 LTC_ARGCHK(taglen != NULL);
35
36 if (gcm->buflen > 16 || gcm->buflen < 0) {
37 return CRYPT_INVALID_ARG;
38 }
39
40 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
41 return err;
42 }
43
44
45 if (gcm->mode != LTC_GCM_MODE_TEXT) {
46 return CRYPT_INVALID_ARG;
47 }
48
49 /* handle remaining ciphertext */
50 if (gcm->buflen) {
51 gcm->pttotlen += gcm->buflen * CONST64(8);
52 gcm_mult_h(gcm, gcm->X);
53 }
54
55 /* length */
56 STORE64H(gcm->totlen, gcm->buf);
57 STORE64H(gcm->pttotlen, gcm->buf+8);
58 for (x = 0; x < 16; x++) {
59 gcm->X[x] ^= gcm->buf[x];
60 }
61 gcm_mult_h(gcm, gcm->X);
62
63 /* encrypt original counter */
64 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
65 return err;
66 }
67 for (x = 0; x < 16 && x < *taglen; x++) {
68 tag[x] = gcm->buf[x] ^ gcm->X[x];
69 }
70 *taglen = x;
71
72 cipher_descriptor[gcm->cipher].done(&gcm->K);
73
74 return CRYPT_OK;
75 }
76
77 #endif
78
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
+0
-221
libtom-src/encauth/gcm/gcm_gf_mult.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_gf_mult.c
13 GCM implementation, do the GF mult, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
18
19 /* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the
20 * lower 16 bits are not zero'ed I removed the upper 14 bytes */
21 const unsigned char gcm_shift_table[256*2] = {
22 0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e,
23 0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e,
24 0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e,
25 0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e,
26 0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e,
27 0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e,
28 0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e,
29 0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e,
30 0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce,
31 0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde,
32 0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee,
33 0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe,
34 0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e,
35 0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e,
36 0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae,
37 0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe,
38 0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e,
39 0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e,
40 0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e,
41 0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e,
42 0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e,
43 0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e,
44 0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e,
45 0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e,
46 0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce,
47 0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde,
48 0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee,
49 0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe,
50 0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e,
51 0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e,
52 0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae,
53 0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe };
54
55 #endif
56
57
58 #if defined(LTC_GCM_MODE) || defined(LRW_MODE)
59
60 #ifndef LTC_FAST
61 /* right shift */
62 static void gcm_rightshift(unsigned char *a)
63 {
64 int x;
65 for (x = 15; x > 0; x--) {
66 a[x] = (a[x]>>1) | ((a[x-1]<<7)&0x80);
67 }
68 a[0] >>= 1;
69 }
70
71 /* c = b*a */
72 static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
73 static const unsigned char poly[] = { 0x00, 0xE1 };
74
75
76 /**
77 GCM GF multiplier (internal use only) bitserial
78 @param a First value
79 @param b Second value
80 @param c Destination for a * b
81 */
82 void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c)
83 {
84 unsigned char Z[16], V[16];
85 unsigned x, y, z;
86
87 zeromem(Z, 16);
88 XMEMCPY(V, a, 16);
89 for (x = 0; x < 128; x++) {
90 if (b[x>>3] & mask[x&7]) {
91 for (y = 0; y < 16; y++) {
92 Z[y] ^= V[y];
93 }
94 }
95 z = V[15] & 0x01;
96 gcm_rightshift(V);
97 V[0] ^= poly[z];
98 }
99 XMEMCPY(c, Z, 16);
100 }
101
102 #else
103
104 /* map normal numbers to "ieee" way ... e.g. bit reversed */
105 #define M(x) ( ((x&8)>>3) | ((x&4)>>1) | ((x&2)<<1) | ((x&1)<<3) )
106
107 #define BPD (sizeof(LTC_FAST_TYPE) * 8)
108 #define WPV (1 + (16 / sizeof(LTC_FAST_TYPE)))
109
110 /**
111 GCM GF multiplier (internal use only) word oriented
112 @param a First value
113 @param b Second value
114 @param c Destination for a * b
115 */
116 void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c)
117 {
118 int i, j, k, u;
119 LTC_FAST_TYPE B[16][WPV], tmp[32 / sizeof(LTC_FAST_TYPE)], pB[16 / sizeof(LTC_FAST_TYPE)], zz, z;
120 unsigned char pTmp[32];
121
122 /* create simple tables */
123 zeromem(B[0], sizeof(B[0]));
124 zeromem(B[M(1)], sizeof(B[M(1)]));
125
126 #ifdef ENDIAN_32BITWORD
127 for (i = 0; i < 4; i++) {
128 LOAD32H(B[M(1)][i], a + (i<<2));
129 LOAD32L(pB[i], b + (i<<2));
130 }
131 #else
132 for (i = 0; i < 2; i++) {
133 LOAD64H(B[M(1)][i], a + (i<<3));
134 LOAD64L(pB[i], b + (i<<3));
135 }
136 #endif
137
138 /* now create 2, 4 and 8 */
139 B[M(2)][0] = B[M(1)][0] >> 1;
140 B[M(4)][0] = B[M(1)][0] >> 2;
141 B[M(8)][0] = B[M(1)][0] >> 3;
142 for (i = 1; i < (int)WPV; i++) {
143 B[M(2)][i] = (B[M(1)][i-1] << (BPD-1)) | (B[M(1)][i] >> 1);
144 B[M(4)][i] = (B[M(1)][i-1] << (BPD-2)) | (B[M(1)][i] >> 2);
145 B[M(8)][i] = (B[M(1)][i-1] << (BPD-3)) | (B[M(1)][i] >> 3);
146 }
147
148 /* now all values with two bits which are 3, 5, 6, 9, 10, 12 */
149 for (i = 0; i < (int)WPV; i++) {
150 B[M(3)][i] = B[M(1)][i] ^ B[M(2)][i];
151 B[M(5)][i] = B[M(1)][i] ^ B[M(4)][i];
152 B[M(6)][i] = B[M(2)][i] ^ B[M(4)][i];
153 B[M(9)][i] = B[M(1)][i] ^ B[M(8)][i];
154 B[M(10)][i] = B[M(2)][i] ^ B[M(8)][i];
155 B[M(12)][i] = B[M(8)][i] ^ B[M(4)][i];
156
157 /* now all 3 bit values and the only 4 bit value: 7, 11, 13, 14, 15 */
158 B[M(7)][i] = B[M(3)][i] ^ B[M(4)][i];
159 B[M(11)][i] = B[M(3)][i] ^ B[M(8)][i];
160 B[M(13)][i] = B[M(1)][i] ^ B[M(12)][i];
161 B[M(14)][i] = B[M(6)][i] ^ B[M(8)][i];
162 B[M(15)][i] = B[M(7)][i] ^ B[M(8)][i];
163 }
164
165 zeromem(tmp, sizeof(tmp));
166
167 /* compute product four bits of each word at a time */
168 /* for each nibble */
169 for (i = (BPD/4)-1; i >= 0; i--) {
170 /* for each word */
171 for (j = 0; j < (int)(WPV-1); j++) {
172 /* grab the 4 bits recall the nibbles are backwards so it's a shift by (i^1)*4 */
173 u = (pB[j] >> ((i^1)<<2)) & 15;
174
175 /* add offset by the word count the table looked up value to the result */
176 for (k = 0; k < (int)WPV; k++) {
177 tmp[k+j] ^= B[u][k];
178 }
179 }
180 /* shift result up by 4 bits */
181 if (i != 0) {
182 for (z = j = 0; j < (int)(32 / sizeof(LTC_FAST_TYPE)); j++) {
183 zz = tmp[j] << (BPD-4);
184 tmp[j] = (tmp[j] >> 4) | z;
185 z = zz;
186 }
187 }
188 }
189
190 /* store product */
191 #ifdef ENDIAN_32BITWORD
192 for (i = 0; i < 8; i++) {
193 STORE32H(tmp[i], pTmp + (i<<2));
194 }
195 #else
196 for (i = 0; i < 4; i++) {
197 STORE64H(tmp[i], pTmp + (i<<3));
198 }
199 #endif
200
201 /* reduce by taking most significant byte and adding the appropriate two byte sequence 16 bytes down */
202 for (i = 31; i >= 16; i--) {
203 pTmp[i-16] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)];
204 pTmp[i-15] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)+1];
205 }
206
207 for (i = 0; i < 16; i++) {
208 c[i] = pTmp[i];
209 }
210
211 }
212
213 #endif
214
215 #endif
216
217 /* $Source$ */
218 /* $Revision$ */
219 /* $Date$ */
220
+0
-107
libtom-src/encauth/gcm/gcm_init.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_init.c
13 GCM implementation, initialize state, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Initialize a GCM state
21 @param gcm The GCM state to initialize
22 @param cipher The index of the cipher to use
23 @param key The secret key
24 @param keylen The length of the secret key
25 @return CRYPT_OK on success
26 */
27 int gcm_init(gcm_state *gcm, int cipher,
28 const unsigned char *key, int keylen)
29 {
30 int err;
31 unsigned char B[16];
32 #ifdef LTC_GCM_TABLES
33 int x, y, z, t;
34 #endif
35
36 LTC_ARGCHK(gcm != NULL);
37 LTC_ARGCHK(key != NULL);
38
39 #ifdef LTC_FAST
40 if (16 % sizeof(LTC_FAST_TYPE)) {
41 return CRYPT_INVALID_ARG;
42 }
43 #endif
44
45 /* is cipher valid? */
46 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
47 return err;
48 }
49 if (cipher_descriptor[cipher].block_length != 16) {
50 return CRYPT_INVALID_CIPHER;
51 }
52
53 /* schedule key */
54 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) {
55 return err;
56 }
57
58 /* H = E(0) */
59 zeromem(B, 16);
60 if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
61 return err;
62 }
63
64 /* setup state */
65 zeromem(gcm->buf, sizeof(gcm->buf));
66 zeromem(gcm->X, sizeof(gcm->X));
67 gcm->cipher = cipher;
68 gcm->mode = LTC_GCM_MODE_IV;
69 gcm->ivmode = 0;
70 gcm->buflen = 0;
71 gcm->totlen = 0;
72 gcm->pttotlen = 0;
73
74 #ifdef LTC_GCM_TABLES
75 /* setup tables */
76
77 /* generate the first table as it has no shifting (from which we make the other tables) */
78 zeromem(B, 16);
79 for (y = 0; y < 256; y++) {
80 B[0] = y;
81 gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]);
82 }
83
84 /* now generate the rest of the tables based the previous table */
85 for (x = 1; x < 16; x++) {
86 for (y = 0; y < 256; y++) {
87 /* now shift it right by 8 bits */
88 t = gcm->PC[x-1][y][15];
89 for (z = 15; z > 0; z--) {
90 gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1];
91 }
92 gcm->PC[x][y][0] = gcm_shift_table[t<<1];
93 gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
94 }
95 }
96
97 #endif
98
99 return CRYPT_OK;
100 }
101
102 #endif
103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
+0
-109
libtom-src/encauth/gcm/gcm_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_memory.c
13 GCM implementation, process a packet, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Process an entire GCM packet in one call.
21 @param cipher Index of cipher to use
22 @param key The secret key
23 @param keylen The length of the secret key
24 @param IV The initial vector
25 @param IVlen The length of the initial vector
26 @param adata The additional authentication data (header)
27 @param adatalen The length of the adata
28 @param pt The plaintext
29 @param ptlen The length of the plaintext (ciphertext length is the same)
30 @param ct The ciphertext
31 @param tag [out] The MAC tag
32 @param taglen [in/out] The MAC tag length
33 @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
34 @return CRYPT_OK on success
35 */
36 int gcm_memory( int cipher,
37 const unsigned char *key, unsigned long keylen,
38 const unsigned char *IV, unsigned long IVlen,
39 const unsigned char *adata, unsigned long adatalen,
40 unsigned char *pt, unsigned long ptlen,
41 unsigned char *ct,
42 unsigned char *tag, unsigned long *taglen,
43 int direction)
44 {
45 void *orig;
46 gcm_state *gcm;
47 int err;
48
49 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
50 return err;
51 }
52
53 if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
54 return
55 cipher_descriptor[cipher].accel_gcm_memory
56 (key, keylen,
57 IV, IVlen,
58 adata, adatalen,
59 pt, ptlen,
60 ct,
61 tag, taglen,
62 direction);
63 }
64
65
66
67 #ifndef LTC_GCM_TABLES_SSE2
68 orig = gcm = XMALLOC(sizeof(*gcm));
69 #else
70 orig = gcm = XMALLOC(sizeof(*gcm) + 16);
71 #endif
72 if (gcm == NULL) {
73 return CRYPT_MEM;
74 }
75
76 /* Force GCM to be on a multiple of 16 so we can use 128-bit aligned operations
77 * note that we only modify gcm and keep orig intact. This code is not portable
78 * but again it's only for SSE2 anyways, so who cares?
79 */
80 #ifdef LTC_GCM_TABLES_SSE2
81 if ((unsigned long)gcm & 15) {
82 gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
83 }
84 #endif
85
86 if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {
87 goto LTC_ERR;
88 }
89 if ((err = gcm_add_iv(gcm, IV, IVlen)) != CRYPT_OK) {
90 goto LTC_ERR;
91 }
92 if ((err = gcm_add_aad(gcm, adata, adatalen)) != CRYPT_OK) {
93 goto LTC_ERR;
94 }
95 if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) {
96 goto LTC_ERR;
97 }
98 err = gcm_done(gcm, tag, taglen);
99 LTC_ERR:
100 XFREE(orig);
101 return err;
102 }
103 #endif
104
105
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
+0
-58
libtom-src/encauth/gcm/gcm_mult_h.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_mult_h.c
13 GCM implementation, do the GF mult, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #if defined(LTC_GCM_MODE)
18 /**
19 GCM multiply by H
20 @param gcm The GCM state which holds the H value
21 @param I The value to multiply H by
22 */
23 void gcm_mult_h(gcm_state *gcm, unsigned char *I)
24 {
25 unsigned char T[16];
26 #ifdef LTC_GCM_TABLES
27 int x, y;
28 #ifdef LTC_GCM_TABLES_SSE2
29 asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
30 for (x = 1; x < 16; x++) {
31 asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
32 }
33 asm("movdqa %%xmm0,(%0)"::"r"(&T));
34 #else
35 XMEMCPY(T, &gcm->PC[0][I[0]][0], 16);
36 for (x = 1; x < 16; x++) {
37 #ifdef LTC_FAST
38 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
39 *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][I[x]][y]));
40 }
41 #else
42 for (y = 0; y < 16; y++) {
43 T[y] ^= gcm->PC[x][I[x]][y];
44 }
45 #endif /* LTC_FAST */
46 }
47 #endif /* LTC_GCM_TABLES_SSE2 */
48 #else
49 gcm_gf_mult(gcm->H, I, T);
50 #endif
51 XMEMCPY(I, T, 16);
52 }
53 #endif
54
55 /* $Source$ */
56 /* $Revision$ */
57 /* $Date$ */
+0
-152
libtom-src/encauth/gcm/gcm_process.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_process.c
13 GCM implementation, process message data, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Process plaintext/ciphertext through GCM
21 @param gcm The GCM state
22 @param pt The plaintext
23 @param ptlen The plaintext length (ciphertext length is the same)
24 @param ct The ciphertext
25 @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
26 @return CRYPT_OK on success
27 */
28 int gcm_process(gcm_state *gcm,
29 unsigned char *pt, unsigned long ptlen,
30 unsigned char *ct,
31 int direction)
32 {
33 unsigned long x;
34 int y, err;
35 unsigned char b;
36
37 LTC_ARGCHK(gcm != NULL);
38 if (ptlen > 0) {
39 LTC_ARGCHK(pt != NULL);
40 LTC_ARGCHK(ct != NULL);
41 }
42
43 if (gcm->buflen > 16 || gcm->buflen < 0) {
44 return CRYPT_INVALID_ARG;
45 }
46
47 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
48 return err;
49 }
50
51 /* in AAD mode? */
52 if (gcm->mode == LTC_GCM_MODE_AAD) {
53 /* let's process the AAD */
54 if (gcm->buflen) {
55 gcm->totlen += gcm->buflen * CONST64(8);
56 gcm_mult_h(gcm, gcm->X);
57 }
58
59 /* increment counter */
60 for (y = 15; y >= 12; y--) {
61 if (++gcm->Y[y] & 255) { break; }
62 }
63 /* encrypt the counter */
64 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
65 return err;
66 }
67
68 gcm->buflen = 0;
69 gcm->mode = LTC_GCM_MODE_TEXT;
70 }
71
72 if (gcm->mode != LTC_GCM_MODE_TEXT) {
73 return CRYPT_INVALID_ARG;
74 }
75
76 x = 0;
77 #ifdef LTC_FAST
78 if (gcm->buflen == 0) {
79 if (direction == GCM_ENCRYPT) {
80 for (x = 0; x < (ptlen & ~15); x += 16) {
81 /* ctr encrypt */
82 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
83 *((LTC_FAST_TYPE*)(&ct[x + y])) = *((LTC_FAST_TYPE*)(&pt[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y]));
84 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y]));
85 }
86 /* GMAC it */
87 gcm->pttotlen += 128;
88 gcm_mult_h(gcm, gcm->X);
89 /* increment counter */
90 for (y = 15; y >= 12; y--) {
91 if (++gcm->Y[y] & 255) { break; }
92 }
93 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
94 return err;
95 }
96 }
97 } else {
98 for (x = 0; x < (ptlen & ~15); x += 16) {
99 /* ctr encrypt */
100 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
101 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y]));
102 *((LTC_FAST_TYPE*)(&pt[x + y])) = *((LTC_FAST_TYPE*)(&ct[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y]));
103 }
104 /* GMAC it */
105 gcm->pttotlen += 128;
106 gcm_mult_h(gcm, gcm->X);
107 /* increment counter */
108 for (y = 15; y >= 12; y--) {
109 if (++gcm->Y[y] & 255) { break; }
110 }
111 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
112 return err;
113 }
114 }
115 }
116 }
117 #endif
118
119 /* process text */
120 for (; x < ptlen; x++) {
121 if (gcm->buflen == 16) {
122 gcm->pttotlen += 128;
123 gcm_mult_h(gcm, gcm->X);
124
125 /* increment counter */
126 for (y = 15; y >= 12; y--) {
127 if (++gcm->Y[y] & 255) { break; }
128 }
129 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
130 return err;
131 }
132 gcm->buflen = 0;
133 }
134
135 if (direction == GCM_ENCRYPT) {
136 b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen];
137 } else {
138 b = ct[x];
139 pt[x] = ct[x] ^ gcm->buf[gcm->buflen];
140 }
141 gcm->X[gcm->buflen++] ^= b;
142 }
143
144 return CRYPT_OK;
145 }
146
147 #endif
148
149 /* $Source$ */
150 /* $Revision$ */
151 /* $Date$ */
+0
-44
libtom-src/encauth/gcm/gcm_reset.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_reset.c
13 GCM implementation, reset a used state so it can accept IV data, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Reset a GCM state to as if you just called gcm_init(). This saves the initialization time.
21 @param gcm The GCM state to reset
22 @return CRYPT_OK on success
23 */
24 int gcm_reset(gcm_state *gcm)
25 {
26 LTC_ARGCHK(gcm != NULL);
27
28 zeromem(gcm->buf, sizeof(gcm->buf));
29 zeromem(gcm->X, sizeof(gcm->X));
30 gcm->mode = LTC_GCM_MODE_IV;
31 gcm->ivmode = 0;
32 gcm->buflen = 0;
33 gcm->totlen = 0;
34 gcm->pttotlen = 0;
35
36 return CRYPT_OK;
37 }
38
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-81
libtom-src/encauth/ocb3/ocb3_add_aad.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_add_aad.c
11 OCB implementation, add AAD data, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Add AAD - additional associated data
19 @param ocb The OCB state
20 @param aad The AAD data
21 @param aadlen The size of AAD data (octets)
22 @return CRYPT_OK if successful
23 */
24 int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen)
25 {
26 int err, x, full_blocks, full_blocks_len, last_block_len;
27 unsigned char *data;
28 unsigned long datalen, l;
29
30 LTC_ARGCHK(ocb != NULL);
31 LTC_ARGCHK(aad != NULL);
32
33 if (aadlen == 0) return CRYPT_OK;
34
35 if (ocb->adata_buffer_bytes > 0) {
36 l = ocb->block_len - ocb->adata_buffer_bytes;
37 if (l > aadlen) l = aadlen;
38 XMEMCPY(ocb->adata_buffer+ocb->adata_buffer_bytes, aad, l);
39 ocb->adata_buffer_bytes += l;
40
41 if (ocb->adata_buffer_bytes == ocb->block_len) {
42 if ((err = ocb3_int_aad_add_block(ocb, ocb->adata_buffer)) != CRYPT_OK) {
43 return err;
44 }
45 ocb->adata_buffer_bytes = 0;
46 }
47
48 data = (unsigned char *)aad + l;
49 datalen = aadlen - l;
50 }
51 else {
52 data = (unsigned char *)aad;
53 datalen = aadlen;
54 }
55
56 if (datalen <= 0) return CRYPT_OK;
57
58 full_blocks = datalen/ocb->block_len;
59 full_blocks_len = full_blocks * ocb->block_len;
60 last_block_len = datalen - full_blocks_len;
61
62 for (x=0; x<full_blocks; x++) {
63 if ((err = ocb3_int_aad_add_block(ocb, data+x*ocb->block_len)) != CRYPT_OK) {
64 return err;
65 }
66 }
67
68 if (last_block_len>0) {
69 XMEMCPY(ocb->adata_buffer, data+full_blocks_len, last_block_len);
70 ocb->adata_buffer_bytes = last_block_len;
71 }
72
73 return CRYPT_OK;
74 }
75
76 #endif
77
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
+0
-86
libtom-src/encauth/ocb3/ocb3_decrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_decrypt.c
13 OCB implementation, decrypt data, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Decrypt blocks of ciphertext with OCB
21 @param ocb The OCB state
22 @param ct The ciphertext (length multiple of the block size of the block cipher)
23 @param ctlen The length of the input (octets)
24 @param pt [out] The plaintext (length of ct)
25 @return CRYPT_OK if successful
26 */
27 int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
28 {
29 unsigned char tmp[MAXBLOCKSIZE];
30 int err, i, full_blocks;
31 unsigned char *pt_b, *ct_b;
32
33 LTC_ARGCHK(ocb != NULL);
34 LTC_ARGCHK(pt != NULL);
35 LTC_ARGCHK(ct != NULL);
36 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
37 return err;
38 }
39 if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 if (ctlen % ocb->block_len) { /* ctlen has to bu multiple of block_len */
44 return CRYPT_INVALID_ARG;
45 }
46
47 full_blocks = ctlen/ocb->block_len;
48 for(i=0; i<full_blocks; i++) {
49 pt_b = (unsigned char *)pt+i*ocb->block_len;
50 ct_b = (unsigned char *)ct+i*ocb->block_len;
51
52 /* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
53 ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);
54
55 /* tmp[] = ct[] XOR ocb->Offset_current[] */
56 ocb3_int_xor_blocks(tmp, ct_b, ocb->Offset_current, ocb->block_len);
57
58 /* decrypt */
59 if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
60 goto LBL_ERR;
61 }
62
63 /* pt[] = tmp[] XOR ocb->Offset_current[] */
64 ocb3_int_xor_blocks(pt_b, tmp, ocb->Offset_current, ocb->block_len);
65
66 /* ocb->checksum[] = ocb->checksum[] XOR pt[] */
67 ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);
68
69 ocb->block_index++;
70 }
71
72 err = CRYPT_OK;
73
74 LBL_ERR:
75 #ifdef LTC_CLEAN_STACK
76 zeromem(tmp, sizeof(tmp));
77 #endif
78 return err;
79 }
80
81 #endif
82
83 /* $Source$ */
84 /* $Revision$ */
85 /* $Date$ */
+0
-105
libtom-src/encauth/ocb3/ocb3_decrypt_last.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_decrypt_last.c
11 OCB implementation, internal helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Finish an OCB (decryption) stream
19 @param ocb The OCB state
20 @param ct The remaining ciphertext
21 @param ctlen The length of the ciphertext (octets)
22 @param pt [out] The output buffer
23 @return CRYPT_OK if successful
24 */
25 int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
26 {
27 unsigned char iOffset_star[MAXBLOCKSIZE];
28 unsigned char iPad[MAXBLOCKSIZE];
29 int err, x, full_blocks, full_blocks_len, last_block_len;
30
31 LTC_ARGCHK(ocb != NULL);
32 LTC_ARGCHK(ct != NULL);
33 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
34 goto LBL_ERR;
35 }
36
37 full_blocks = ctlen/ocb->block_len;
38 full_blocks_len = full_blocks * ocb->block_len;
39 last_block_len = ctlen - full_blocks_len;
40
41 /* process full blocks first */
42 if (full_blocks>0) {
43 if ((err = ocb3_decrypt(ocb, ct, full_blocks_len, pt)) != CRYPT_OK) {
44 goto LBL_ERR;
45 }
46 }
47
48 if (last_block_len>0) {
49 /* Offset_* = Offset_m xor L_* */
50 ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
51
52 /* Pad = ENCIPHER(K, Offset_*) */
53 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
54 goto LBL_ERR;
55 }
56
57 /* P_* = C_* xor Pad[1..bitlen(C_*)] */
58 ocb3_int_xor_blocks(pt+full_blocks_len, (unsigned char *)ct+full_blocks_len, iPad, last_block_len);
59
60 /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
61 ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
62 for(x=last_block_len; x<ocb->block_len; x++) {
63 if (x == last_block_len)
64 ocb->checksum[x] ^= 0x80;
65 else
66 ocb->checksum[x] ^= 0x00;
67 }
68
69 /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
70 /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
71 for(x=0; x<ocb->block_len; x++) {
72 ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
73 }
74 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77 }
78 else {
79 /* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
80 /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
81 for(x=0; x<ocb->block_len; x++) {
82 ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
83 }
84 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
85 goto LBL_ERR;
86 }
87 }
88
89 err = CRYPT_OK;
90
91 LBL_ERR:
92 #ifdef LTC_CLEAN_STACK
93 zeromem(iOffset_star, MAXBLOCKSIZE);
94 zeromem(iPad, MAXBLOCKSIZE);
95 #endif
96
97 return err;
98 }
99
100 #endif
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
+0
-112
libtom-src/encauth/ocb3/ocb3_decrypt_verify_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_decrypt_verify_memory.c
13 OCB implementation, helper to decrypt block of memory, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Decrypt and compare the tag with OCB
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param nonce The session nonce (length of the block size of the block cipher)
25 @param noncelen The length of the nonce (octets)
26 @param adata The AAD - additional associated data
27 @param adatalen The length of AAD (octets)
28 @param ct The ciphertext
29 @param ctlen The length of the ciphertext (octets)
30 @param pt [out] The plaintext
31 @param tag The tag to compare against
32 @param taglen The length of the tag (octets)
33 @param stat [out] The result of the tag comparison (1==valid, 0==invalid)
34 @return CRYPT_OK if successful regardless of the tag comparison
35 */
36 int ocb3_decrypt_verify_memory(int cipher,
37 const unsigned char *key, unsigned long keylen,
38 const unsigned char *nonce, unsigned long noncelen,
39 const unsigned char *adata, unsigned long adatalen,
40 const unsigned char *ct, unsigned long ctlen,
41 unsigned char *pt,
42 const unsigned char *tag, unsigned long taglen,
43 int *stat)
44 {
45 int err;
46 ocb3_state *ocb;
47 unsigned char *buf;
48 unsigned long buflen;
49
50 LTC_ARGCHK(key != NULL);
51 LTC_ARGCHK(nonce != NULL);
52 LTC_ARGCHK(pt != NULL);
53 LTC_ARGCHK(ct != NULL);
54 LTC_ARGCHK(tag != NULL);
55 LTC_ARGCHK(stat != NULL);
56
57 /* default to zero */
58 *stat = 0;
59
60 /* allocate memory */
61 buf = XMALLOC(taglen);
62 ocb = XMALLOC(sizeof(ocb3_state));
63 if (ocb == NULL || buf == NULL) {
64 if (ocb != NULL) {
65 XFREE(ocb);
66 }
67 if (buf != NULL) {
68 XFREE(buf);
69 }
70 return CRYPT_MEM;
71 }
72
73 if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76
77 if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80
81 if ((err = ocb3_decrypt_last(ocb, ct, ctlen, pt)) != CRYPT_OK) {
82 goto LBL_ERR;
83 }
84
85 buflen = taglen;
86 if ((err = ocb3_done(ocb, buf, &buflen)) != CRYPT_OK) {
87 goto LBL_ERR;
88 }
89
90 /* compare tags */
91 if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) {
92 *stat = 1;
93 }
94
95 err = CRYPT_OK;
96
97 LBL_ERR:
98 #ifdef LTC_CLEAN_STACK
99 zeromem(ocb, sizeof(ocb3_state));
100 #endif
101
102 XFREE(ocb);
103 XFREE(buf);
104 return err;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
+0
-92
libtom-src/encauth/ocb3/ocb3_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_done.c
13 OCB implementation, INTERNAL ONLY helper, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Finish OCB processing and compute the tag
21 @param ocb The OCB state
22 @param tag [out] The destination for the authentication tag
23 @param taglen [in/out] The max size and resulting size of the authentication tag
24 @return CRYPT_OK if successful
25 */
26 int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen)
27 {
28 unsigned char tmp[MAXBLOCKSIZE];
29 int err, x;
30
31 LTC_ARGCHK(ocb != NULL);
32 LTC_ARGCHK(tag != NULL);
33 LTC_ARGCHK(taglen != NULL);
34 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
35 goto LBL_ERR;
36 }
37
38 /* finalize AAD processing */
39
40 if (ocb->adata_buffer_bytes>0) {
41 /* Offset_* = Offset_m xor L_* */
42 ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_star, ocb->block_len);
43
44 /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
45 ocb3_int_xor_blocks(tmp, ocb->adata_buffer, ocb->aOffset_current, ocb->adata_buffer_bytes);
46 for(x=ocb->adata_buffer_bytes; x<ocb->block_len; x++) {
47 if (x == ocb->adata_buffer_bytes) {
48 tmp[x] = 0x80 ^ ocb->aOffset_current[x];
49 }
50 else {
51 tmp[x] = 0x00 ^ ocb->aOffset_current[x];
52 }
53 }
54
55 /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
56 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
57 goto LBL_ERR;
58 }
59 ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
60 }
61
62 /* finalize TAG computing */
63
64 /* at this point ocb->aSum_current = HASH(K, A) */
65 /* tag = tag ^ HASH(K, A) */
66 ocb3_int_xor_blocks(tmp, ocb->tag_part, ocb->aSum_current, ocb->block_len);
67
68 /* fix taglen if needed */
69 if ((int)*taglen > ocb->block_len) {
70 *taglen = (unsigned long)ocb->block_len;
71 }
72
73 /* copy tag bytes */
74 for(x=0; x<(int)*taglen; x++) tag[x] = tmp[x];
75
76 err = CRYPT_OK;
77
78 LBL_ERR:
79 #ifdef LTC_CLEAN_STACK
80 zeromem(tmp, MAXBLOCKSIZE);
81 zeromem(ocb, sizeof(*ocb));
82 #endif
83
84 return err;
85 }
86
87 #endif
88
89 /* $Source$ */
90 /* $Revision$ */
91 /* $Date$ */
+0
-86
libtom-src/encauth/ocb3/ocb3_encrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_encrypt.c
13 OCB implementation, encrypt data, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Encrypt blocks of data with OCB
21 @param ocb The OCB state
22 @param pt The plaintext (length multiple of the block size of the block cipher)
23 @param ptlen The length of the input (octets)
24 @param ct [out] The ciphertext (same size as the pt)
25 @return CRYPT_OK if successful
26 */
27 int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
28 {
29 unsigned char tmp[MAXBLOCKSIZE];
30 int err, i, full_blocks;
31 unsigned char *pt_b, *ct_b;
32
33 LTC_ARGCHK(ocb != NULL);
34 LTC_ARGCHK(pt != NULL);
35 LTC_ARGCHK(ct != NULL);
36 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
37 return err;
38 }
39 if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 if (ptlen % ocb->block_len) { /* ptlen has to bu multiple of block_len */
44 return CRYPT_INVALID_ARG;
45 }
46
47 full_blocks = ptlen/ocb->block_len;
48 for(i=0; i<full_blocks; i++) {
49 pt_b = (unsigned char *)pt+i*ocb->block_len;
50 ct_b = (unsigned char *)ct+i*ocb->block_len;
51
52 /* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
53 ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);
54
55 /* tmp[] = pt[] XOR ocb->Offset_current[] */
56 ocb3_int_xor_blocks(tmp, pt_b, ocb->Offset_current, ocb->block_len);
57
58 /* encrypt */
59 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
60 goto LBL_ERR;
61 }
62
63 /* ct[] = tmp[] XOR ocb->Offset_current[] */
64 ocb3_int_xor_blocks(ct_b, tmp, ocb->Offset_current, ocb->block_len);
65
66 /* ocb->checksum[] = ocb->checksum[] XOR pt[] */
67 ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);
68
69 ocb->block_index++;
70 }
71
72 err = CRYPT_OK;
73
74 LBL_ERR:
75 #ifdef LTC_CLEAN_STACK
76 zeromem(tmp, sizeof(tmp));
77 #endif
78 return err;
79 }
80
81 #endif
82
83 /* $Source$ */
84 /* $Revision$ */
85 /* $Date$ */
+0
-87
libtom-src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_encrypt_authenticate_memory.c
13 OCB implementation, encrypt block of memory, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Encrypt and generate an authentication code for a buffer of memory
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param nonce The session nonce (length of the block ciphers block size)
25 @param noncelen The length of the nonce (octets)
26 @param adata The AAD - additional associated data
27 @param adatalen The length of AAD (octets)
28 @param pt The plaintext
29 @param ptlen The length of the plaintext (octets)
30 @param ct [out] The ciphertext
31 @param tag [out] The authentication tag
32 @param taglen [in/out] The max size and resulting size of the authentication tag
33 @return CRYPT_OK if successful
34 */
35 int ocb3_encrypt_authenticate_memory(int cipher,
36 const unsigned char *key, unsigned long keylen,
37 const unsigned char *nonce, unsigned long noncelen,
38 const unsigned char *adata, unsigned long adatalen,
39 const unsigned char *pt, unsigned long ptlen,
40 unsigned char *ct,
41 unsigned char *tag, unsigned long *taglen)
42 {
43 int err;
44 ocb3_state *ocb;
45
46 LTC_ARGCHK(key != NULL);
47 LTC_ARGCHK(nonce != NULL);
48 LTC_ARGCHK(pt != NULL);
49 LTC_ARGCHK(ct != NULL);
50 LTC_ARGCHK(tag != NULL);
51 LTC_ARGCHK(taglen != NULL);
52
53 /* allocate memory */
54 ocb = XMALLOC(sizeof(ocb3_state));
55 if (ocb == NULL) {
56 return CRYPT_MEM;
57 }
58
59 if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen)) != CRYPT_OK) {
60 goto LBL_ERR;
61 }
62
63 if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66
67 if ((err = ocb3_encrypt_last(ocb, pt, ptlen, ct)) != CRYPT_OK) {
68 goto LBL_ERR;
69 }
70
71 err = ocb3_done(ocb, tag, taglen);
72
73 LBL_ERR:
74 #ifdef LTC_CLEAN_STACK
75 zeromem(ocb, sizeof(ocb3_state));
76 #endif
77
78 XFREE(ocb);
79 return err;
80 }
81
82 #endif
83
84 /* $Source$ */
85 /* $Revision$ */
86 /* $Date$ */
+0
-107
libtom-src/encauth/ocb3/ocb3_encrypt_last.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_encrypt_last.c
11 OCB implementation, internal helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Finish an OCB (encryption) stream
19 @param ocb The OCB state
20 @param pt The remaining plaintext
21 @param ptlen The length of the plaintext (octets)
22 @param ct [out] The output buffer
23 @return CRYPT_OK if successful
24 */
25 int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
26 {
27 unsigned char iOffset_star[MAXBLOCKSIZE];
28 unsigned char iPad[MAXBLOCKSIZE];
29 int err, x, full_blocks, full_blocks_len, last_block_len;
30
31 LTC_ARGCHK(ocb != NULL);
32 LTC_ARGCHK(pt != NULL);
33 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
34 goto LBL_ERR;
35 }
36
37 full_blocks = ptlen/ocb->block_len;
38 full_blocks_len = full_blocks * ocb->block_len;
39 last_block_len = ptlen - full_blocks_len;
40
41 /* process full blocks first */
42 if (full_blocks>0) {
43 if ((err = ocb3_encrypt(ocb, pt, full_blocks_len, ct)) != CRYPT_OK) {
44 goto LBL_ERR;
45 }
46 }
47
48 /* at this point: m = ocb->block_index (last block index), Offset_m = ocb->Offset_current */
49
50 if (last_block_len>0) {
51 /* Offset_* = Offset_m xor L_* */
52 ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
53
54 /* Pad = ENCIPHER(K, Offset_*) */
55 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58
59 /* C_* = P_* xor Pad[1..bitlen(P_*)] */
60 ocb3_int_xor_blocks(ct+full_blocks_len, pt+full_blocks_len, iPad, last_block_len);
61
62 /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
63 ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
64 for(x=last_block_len; x<ocb->block_len; x++) {
65 if (x == last_block_len)
66 ocb->checksum[x] ^= 0x80;
67 else
68 ocb->checksum[x] ^= 0x00;
69 }
70
71 /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
72 /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
73 for(x=0; x<ocb->block_len; x++) {
74 ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
75 }
76 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79 }
80 else {
81 /* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
82 /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
83 for(x=0; x<ocb->block_len; x++) {
84 ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
85 }
86 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
87 goto LBL_ERR;
88 }
89 }
90
91 err = CRYPT_OK;
92
93 LBL_ERR:
94 #ifdef LTC_CLEAN_STACK
95 zeromem(iOffset_star, MAXBLOCKSIZE);
96 zeromem(iPad, MAXBLOCKSIZE);
97 #endif
98
99 return err;
100 }
101
102 #endif
103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
+0
-138
libtom-src/encauth/ocb3/ocb3_init.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_init.c
13 OCB implementation, initialize state, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 static const struct {
20 int len;
21 unsigned char poly_div[MAXBLOCKSIZE],
22 poly_mul[MAXBLOCKSIZE];
23 } polys[] = {
24 {
25 8,
26 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
27 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
28 }, {
29 16,
30 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
32 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
34 }
35 };
36
37 /**
38 Initialize an OCB context
39 @param ocb [out] The destination of the OCB state
40 @param cipher The index of the desired cipher
41 @param key The secret key
42 @param keylen The length of the secret key (octets)
43 @param nonce The session nonce
44 @param noncelen The length of the session nonce (octets)
45 @return CRYPT_OK if successful
46 */
47 int ocb3_init(ocb3_state *ocb, int cipher,
48 const unsigned char *key, unsigned long keylen,
49 const unsigned char *nonce, unsigned long noncelen)
50 {
51 int poly, x, y, m, err;
52 unsigned char *previous, *current;
53
54 LTC_ARGCHK(ocb != NULL);
55 LTC_ARGCHK(key != NULL);
56 LTC_ARGCHK(nonce != NULL);
57
58 /* valid cipher? */
59 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
60 return err;
61 }
62 ocb->cipher = cipher;
63
64 /* determine which polys to use */
65 ocb->block_len = cipher_descriptor[cipher].block_length;
66 x = (int)(sizeof(polys)/sizeof(polys[0]));
67 for (poly = 0; poly < x; poly++) {
68 if (polys[poly].len == ocb->block_len) {
69 break;
70 }
71 }
72 if (poly == x) {
73 return CRYPT_INVALID_ARG; /* block_len not found in polys */
74 }
75 if (polys[poly].len != ocb->block_len) {
76 return CRYPT_INVALID_ARG;
77 }
78
79 /* schedule the key */
80 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
81 return err;
82 }
83
84 /* L_* = ENCIPHER(K, zeros(128)) */
85 zeromem(ocb->L_star, ocb->block_len);
86 if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) {
87 return err;
88 }
89
90 /* compute L_$, L_0, L_1, ... */
91 for (x = -1; x < 32; x++) {
92 if (x == -1) { /* gonna compute: L_$ = double(L_*) */
93 current = ocb->L_dollar;
94 previous = ocb->L_star;
95 }
96 else if (x == 0) { /* gonna compute: L_0 = double(L_$) */
97 current = ocb->L_[0];
98 previous = ocb->L_dollar;
99 }
100 else { /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */
101 current = ocb->L_[x];
102 previous = ocb->L_[x-1];
103 }
104 m = previous[0] >> 7;
105 for (y = 0; y < ocb->block_len-1; y++) {
106 current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255;
107 }
108 current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255;
109 if (m == 1) {
110 /* current[] = current[] XOR polys[poly].poly_mul[]*/
111 ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len);
112 }
113 }
114
115 /* initialize ocb->Offset_current = Offset_0 */
116 ocb3_int_calc_offset_zero(ocb, nonce, noncelen);
117
118 /* initialize checksum to all zeros */
119 zeromem(ocb->checksum, ocb->block_len);
120
121 /* set block index */
122 ocb->block_index = 1;
123
124 /* initialize AAD related stuff */
125 ocb->ablock_index = 1;
126 ocb->adata_buffer_bytes = 0;
127 zeromem(ocb->aOffset_current, ocb->block_len);
128 zeromem(ocb->aSum_current, ocb->block_len);
129
130 return CRYPT_OK;
131 }
132
133 #endif
134
135 /* $Source$ */
136 /* $Revision$ */
137 /* $Date$ */
+0
-49
libtom-src/encauth/ocb3/ocb3_int_aad_add_block.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_int_aad_add_block.c
11 OCB implementation, INTERNALL ONLY helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Add one block of AAD data (internal function)
19 @param ocb The OCB state
20 @param aad_block [in] AAD data (block_len size)
21 @return CRYPT_OK if successful
22 */
23 int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block)
24 {
25 unsigned char tmp[MAXBLOCKSIZE];
26 int err;
27
28 /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
29 ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_[ocb3_int_ntz(ocb->ablock_index)], ocb->block_len);
30
31 /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
32 ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len);
33 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
34 return err;
35 }
36 ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
37
38 ocb->ablock_index++;
39
40 return CRYPT_OK;
41 }
42
43 #endif
44
45
46 /* $Source$ */
47 /* $Revision$ */
48 /* $Date$ */
+0
-72
libtom-src/encauth/ocb3/ocb3_int_calc_offset_zero.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_int_calc_offset_zero.c
11 OCB implementation, INTERNAL ONLY helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Sets 'ocb->Offset_current' to 'Offset_0' value (internal function)
19 @param ocb The OCB state
20 @param nonce The session nonce
21 @param noncelen The length of the session nonce (octets)
22 */
23 void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen)
24 {
25 int x, y, bottom;
26 int idx, shift;
27 unsigned char iNonce[MAXBLOCKSIZE];
28 unsigned char iKtop[MAXBLOCKSIZE];
29 unsigned char iStretch[MAXBLOCKSIZE+8];
30
31 /* Nonce = zeros(127-bitlen(N)) || 1 || N */
32 zeromem(iNonce, sizeof(iNonce));
33 for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) {
34 iNonce[x] = nonce[noncelen-y-1];
35 }
36 iNonce[x] = 0x01;
37
38 /* bottom = str2num(Nonce[123..128]) */
39 bottom = iNonce[ocb->block_len-1] & 0x3F;
40
41 /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */
42 iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0;
43 if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) {
44 zeromem(ocb->Offset_current, ocb->block_len);
45 return;
46 }
47
48 /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
49 for (x = 0; x < ocb->block_len; x++) {
50 iStretch[x] = iKtop[x];
51 }
52 for (y = 0; y < 8; y++) {
53 iStretch[x+y] = iKtop[y] ^ iKtop[y+1];
54 }
55
56 /* Offset_0 = Stretch[1+bottom..128+bottom] */
57 idx = bottom / 8;
58 shift = (bottom % 8);
59 for (x = 0; x < ocb->block_len; x++) {
60 ocb->Offset_current[x] = iStretch[idx+x] << shift;
61 if (shift > 0) {
62 ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift);
63 }
64 }
65 }
66
67 #endif
68
69 /* $Source$ */
70 /* $Revision$ */
71 /* $Date$ */
+0
-41
libtom-src/encauth/ocb3/ocb3_int_ntz.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_int_ntz.c
13 OCB implementation, INTERNAL ONLY helper, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Returns the number of leading zero bits [from lsb up] (internal function)
21 @param x The 32-bit value to observe
22 @return The number of bits [from the lsb up] that are zero
23 */
24 int ocb3_int_ntz(unsigned long x)
25 {
26 int c;
27 x &= 0xFFFFFFFFUL;
28 c = 0;
29 while ((x & 1) == 0) {
30 ++c;
31 x >>= 1;
32 }
33 return c;
34 }
35
36 #endif
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
+0
-40
libtom-src/encauth/ocb3/ocb3_int_xor_blocks.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_int_xor_blocks.c
11 OCB implementation, INTERNAL ONLY helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Compute xor for two blocks of bytes 'out = block_a XOR block_b' (internal function)
19 @param out The block of bytes (output)
20 @param block_a The block of bytes (input)
21 @param block_b The block of bytes (input)
22 @param block_len The size of block_a, block_b, out
23 */
24 void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len)
25 {
26 int x;
27 if (out == block_a) {
28 for (x = 0; x < (int)block_len; x++) out[x] ^= block_b[x];
29 }
30 else {
31 for (x = 0; x < (int)block_len; x++) out[x] = block_a[x] ^ block_b[x];
32 }
33 }
34
35 #endif
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
+0
-298
libtom-src/hashes/chc/chc.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #include "tomcrypt.h"
12
13 /**
14 @file chc.c
15 CHC support. (Tom St Denis)
16 */
17
18 #ifdef LTC_CHC_HASH
19
20 #define UNDEFED_HASH -17
21
22 /* chc settings */
23 static int cipher_idx=UNDEFED_HASH, /* which cipher */
24 cipher_blocksize; /* blocksize of cipher */
25
26
27 const struct ltc_hash_descriptor chc_desc = {
28 "chc_hash", 12, 0, 0, { 0 }, 0,
29 &chc_init,
30 &chc_process,
31 &chc_done,
32 &chc_test,
33 NULL
34 };
35
36 /**
37 Initialize the CHC state with a given cipher
38 @param cipher The index of the cipher you wish to bind
39 @return CRYPT_OK if successful
40 */
41 int chc_register(int cipher)
42 {
43 int err, kl, idx;
44
45 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
46 return err;
47 }
48
49 /* will it be valid? */
50 kl = cipher_descriptor[cipher].block_length;
51
52 /* must be >64 bit block */
53 if (kl <= 8) {
54 return CRYPT_INVALID_CIPHER;
55 }
56
57 /* can we use the ideal keysize? */
58 if ((err = cipher_descriptor[cipher].keysize(&kl)) != CRYPT_OK) {
59 return err;
60 }
61 /* we require that key size == block size be a valid choice */
62 if (kl != cipher_descriptor[cipher].block_length) {
63 return CRYPT_INVALID_CIPHER;
64 }
65
66 /* determine if chc_hash has been register_hash'ed already */
67 if ((err = hash_is_valid(idx = find_hash("chc_hash"))) != CRYPT_OK) {
68 return err;
69 }
70
71 /* store into descriptor */
72 hash_descriptor[idx].hashsize =
73 hash_descriptor[idx].blocksize = cipher_descriptor[cipher].block_length;
74
75 /* store the idx and block size */
76 cipher_idx = cipher;
77 cipher_blocksize = cipher_descriptor[cipher].block_length;
78 return CRYPT_OK;
79 }
80
81 /**
82 Initialize the hash state
83 @param md The hash state you wish to initialize
84 @return CRYPT_OK if successful
85 */
86 int chc_init(hash_state *md)
87 {
88 symmetric_key *key;
89 unsigned char buf[MAXBLOCKSIZE];
90 int err;
91
92 LTC_ARGCHK(md != NULL);
93
94 /* is the cipher valid? */
95 if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
96 return err;
97 }
98
99 if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
100 return CRYPT_INVALID_CIPHER;
101 }
102
103 if ((key = XMALLOC(sizeof(*key))) == NULL) {
104 return CRYPT_MEM;
105 }
106
107 /* zero key and what not */
108 zeromem(buf, cipher_blocksize);
109 if ((err = cipher_descriptor[cipher_idx].setup(buf, cipher_blocksize, 0, key)) != CRYPT_OK) {
110 XFREE(key);
111 return err;
112 }
113
114 /* encrypt zero block */
115 cipher_descriptor[cipher_idx].ecb_encrypt(buf, md->chc.state, key);
116
117 /* zero other members */
118 md->chc.length = 0;
119 md->chc.curlen = 0;
120 zeromem(md->chc.buf, sizeof(md->chc.buf));
121 XFREE(key);
122 return CRYPT_OK;
123 }
124
125 /*
126 key <= state
127 T0,T1 <= block
128 T0 <= encrypt T0
129 state <= state xor T0 xor T1
130 */
131 static int chc_compress(hash_state *md, unsigned char *buf)
132 {
133 unsigned char T[2][MAXBLOCKSIZE];
134 symmetric_key *key;
135 int err, x;
136
137 if ((key = XMALLOC(sizeof(*key))) == NULL) {
138 return CRYPT_MEM;
139 }
140 if ((err = cipher_descriptor[cipher_idx].setup(md->chc.state, cipher_blocksize, 0, key)) != CRYPT_OK) {
141 XFREE(key);
142 return err;
143 }
144 XMEMCPY(T[1], buf, cipher_blocksize);
145 cipher_descriptor[cipher_idx].ecb_encrypt(buf, T[0], key);
146 for (x = 0; x < cipher_blocksize; x++) {
147 md->chc.state[x] ^= T[0][x] ^ T[1][x];
148 }
149 XFREE(key);
150 #ifdef LTC_CLEAN_STACK
151 zeromem(T, sizeof(T));
152 zeromem(&key, sizeof(key));
153 #endif
154 return CRYPT_OK;
155 }
156
157 /* function for processing blocks */
158 int _chc_process(hash_state * md, const unsigned char *buf, unsigned long len);
159 HASH_PROCESS(_chc_process, chc_compress, chc, (unsigned long)cipher_blocksize)
160
161 /**
162 Process a block of memory though the hash
163 @param md The hash state
164 @param in The data to hash
165 @param inlen The length of the data (octets)
166 @return CRYPT_OK if successful
167 */
168 int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen)
169 {
170 int err;
171
172 LTC_ARGCHK(md != NULL);
173 LTC_ARGCHK(in != NULL);
174
175 /* is the cipher valid? */
176 if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
177 return err;
178 }
179 if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
180 return CRYPT_INVALID_CIPHER;
181 }
182
183 return _chc_process(md, in, inlen);
184 }
185
186 /**
187 Terminate the hash to get the digest
188 @param md The hash state
189 @param out [out] The destination of the hash (length of the block size of the block cipher)
190 @return CRYPT_OK if successful
191 */
192 int chc_done(hash_state *md, unsigned char *out)
193 {
194 int err;
195
196 LTC_ARGCHK(md != NULL);
197 LTC_ARGCHK(out != NULL);
198
199 /* is the cipher valid? */
200 if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
201 return err;
202 }
203 if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
204 return CRYPT_INVALID_CIPHER;
205 }
206
207 if (md->chc.curlen >= sizeof(md->chc.buf)) {
208 return CRYPT_INVALID_ARG;
209 }
210
211 /* increase the length of the message */
212 md->chc.length += md->chc.curlen * 8;
213
214 /* append the '1' bit */
215 md->chc.buf[md->chc.curlen++] = (unsigned char)0x80;
216
217 /* if the length is currently above l-8 bytes we append zeros
218 * then compress. Then we can fall back to padding zeros and length
219 * encoding like normal.
220 */
221 if (md->chc.curlen > (unsigned long)(cipher_blocksize - 8)) {
222 while (md->chc.curlen < (unsigned long)cipher_blocksize) {
223 md->chc.buf[md->chc.curlen++] = (unsigned char)0;
224 }
225 chc_compress(md, md->chc.buf);
226 md->chc.curlen = 0;
227 }
228
229 /* pad upto l-8 bytes of zeroes */
230 while (md->chc.curlen < (unsigned long)(cipher_blocksize - 8)) {
231 md->chc.buf[md->chc.curlen++] = (unsigned char)0;
232 }
233
234 /* store length */
235 STORE64L(md->chc.length, md->chc.buf+(cipher_blocksize-8));
236 chc_compress(md, md->chc.buf);
237
238 /* copy output */
239 XMEMCPY(out, md->chc.state, cipher_blocksize);
240
241 #ifdef LTC_CLEAN_STACK
242 zeromem(md, sizeof(hash_state));
243 #endif
244 return CRYPT_OK;
245 }
246
247 /**
248 Self-test the hash
249 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
250 */
251 int chc_test(void)
252 {
253 static const struct {
254 unsigned char *msg,
255 md[MAXBLOCKSIZE];
256 int len;
257 } tests[] = {
258 {
259 (unsigned char *)"hello world",
260 { 0xcf, 0x57, 0x9d, 0xc3, 0x0a, 0x0e, 0xea, 0x61,
261 0x0d, 0x54, 0x47, 0xc4, 0x3c, 0x06, 0xf5, 0x4e },
262 16
263 }
264 };
265 int x, oldhashidx, idx;
266 unsigned char out[MAXBLOCKSIZE];
267 hash_state md;
268
269 /* AES can be under rijndael or aes... try to find it */
270 if ((idx = find_cipher("aes")) == -1) {
271 if ((idx = find_cipher("rijndael")) == -1) {
272 return CRYPT_NOP;
273 }
274 }
275 oldhashidx = cipher_idx;
276 chc_register(idx);
277
278 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
279 chc_init(&md);
280 chc_process(&md, tests[x].msg, strlen((char *)tests[x].msg));
281 chc_done(&md, out);
282 if (XMEMCMP(out, tests[x].md, tests[x].len)) {
283 return CRYPT_FAIL_TESTVECTOR;
284 }
285 }
286 if (oldhashidx != UNDEFED_HASH) {
287 chc_register(oldhashidx);
288 }
289
290 return CRYPT_OK;
291 }
292
293 #endif
294
295 /* $Source$ */
296 /* $Revision$ */
297 /* $Date$ */
+0
-55
libtom-src/hashes/helper/hash_file.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 #ifndef LTC_NO_FILE
13 /**
14 @file hash_file.c
15 Hash a file, Tom St Denis
16 */
17
18 /**
19 @param hash The index of the hash desired
20 @param fname The name of the file you wish to hash
21 @param out [out] The destination of the digest
22 @param outlen [in/out] The max size and resulting size of the message digest
23 @result CRYPT_OK if successful
24 */
25 int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen)
26 {
27 FILE *in;
28 int err;
29 LTC_ARGCHK(fname != NULL);
30 LTC_ARGCHK(out != NULL);
31 LTC_ARGCHK(outlen != NULL);
32
33 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
34 return err;
35 }
36
37 in = fopen(fname, "rb");
38 if (in == NULL) {
39 return CRYPT_FILE_NOTFOUND;
40 }
41
42 err = hash_filehandle(hash, in, out, outlen);
43 if (fclose(in) != 0) {
44 return CRYPT_ERROR;
45 }
46
47 return err;
48 }
49 #endif /* #ifndef LTC_NO_FILE */
50
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
+0
-69
libtom-src/hashes/helper/hash_filehandle.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 #ifndef LTC_NO_FILE
13 /**
14 @file hash_filehandle.c
15 Hash open files, Tom St Denis
16 */
17
18 /**
19 Hash data from an open file handle.
20 @param hash The index of the hash you want to use
21 @param in The FILE* handle of the file you want to hash
22 @param out [out] The destination of the digest
23 @param outlen [in/out] The max size and resulting size of the digest
24 @result CRYPT_OK if successful
25 */
26 int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen)
27 {
28 hash_state md;
29 unsigned char buf[512];
30 size_t x;
31 int err;
32
33 LTC_ARGCHK(out != NULL);
34 LTC_ARGCHK(outlen != NULL);
35 LTC_ARGCHK(in != NULL);
36
37 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
38 return err;
39 }
40
41 if (*outlen < hash_descriptor[hash].hashsize) {
42 *outlen = hash_descriptor[hash].hashsize;
43 return CRYPT_BUFFER_OVERFLOW;
44 }
45 if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) {
46 return err;
47 }
48
49 *outlen = hash_descriptor[hash].hashsize;
50 do {
51 x = fread(buf, 1, sizeof(buf), in);
52 if ((err = hash_descriptor[hash].process(&md, buf, x)) != CRYPT_OK) {
53 return err;
54 }
55 } while (x == sizeof(buf));
56 err = hash_descriptor[hash].done(&md, out);
57
58 #ifdef LTC_CLEAN_STACK
59 zeromem(buf, sizeof(buf));
60 #endif
61 return err;
62 }
63 #endif /* #ifndef LTC_NO_FILE */
64
65
66 /* $Source$ */
67 /* $Revision$ */
68 /* $Date$ */
+0
-69
libtom-src/hashes/helper/hash_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hash_memory.c
14 Hash memory helper, Tom St Denis
15 */
16
17 /**
18 Hash a block of memory and store the digest.
19 @param hash The index of the hash you wish to use
20 @param in The data you wish to hash
21 @param inlen The length of the data to hash (octets)
22 @param out [out] Where to store the digest
23 @param outlen [in/out] Max size and resulting size of the digest
24 @return CRYPT_OK if successful
25 */
26 int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
27 {
28 hash_state *md;
29 int err;
30
31 LTC_ARGCHK(in != NULL);
32 LTC_ARGCHK(out != NULL);
33 LTC_ARGCHK(outlen != NULL);
34
35 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
36 return err;
37 }
38
39 if (*outlen < hash_descriptor[hash].hashsize) {
40 *outlen = hash_descriptor[hash].hashsize;
41 return CRYPT_BUFFER_OVERFLOW;
42 }
43
44 md = XMALLOC(sizeof(hash_state));
45 if (md == NULL) {
46 return CRYPT_MEM;
47 }
48
49 if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
50 goto LBL_ERR;
51 }
52 if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) {
53 goto LBL_ERR;
54 }
55 err = hash_descriptor[hash].done(md, out);
56 *outlen = hash_descriptor[hash].hashsize;
57 LBL_ERR:
58 #ifdef LTC_CLEAN_STACK
59 zeromem(md, sizeof(hash_state));
60 #endif
61 XFREE(md);
62
63 return err;
64 }
65
66 /* $Source$ */
67 /* $Revision$ */
68 /* $Date$ */
+0
-87
libtom-src/hashes/helper/hash_memory_multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12 /**
13 @file hash_memory_multi.c
14 Hash (multiple buffers) memory helper, Tom St Denis
15 */
16
17 /**
18 Hash multiple (non-adjacent) blocks of memory at once.
19 @param hash The index of the hash you wish to use
20 @param out [out] Where to store the digest
21 @param outlen [in/out] Max size and resulting size of the digest
22 @param in The data you wish to hash
23 @param inlen The length of the data to hash (octets)
24 @param ... tuples of (data,len) pairs to hash, terminated with a (NULL,x) (x=don't care)
25 @return CRYPT_OK if successful
26 */
27 int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
28 const unsigned char *in, unsigned long inlen, ...)
29 {
30 hash_state *md;
31 int err;
32 va_list args;
33 const unsigned char *curptr;
34 unsigned long curlen;
35
36 LTC_ARGCHK(in != NULL);
37 LTC_ARGCHK(out != NULL);
38 LTC_ARGCHK(outlen != NULL);
39
40 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
41 return err;
42 }
43
44 if (*outlen < hash_descriptor[hash].hashsize) {
45 *outlen = hash_descriptor[hash].hashsize;
46 return CRYPT_BUFFER_OVERFLOW;
47 }
48
49 md = XMALLOC(sizeof(hash_state));
50 if (md == NULL) {
51 return CRYPT_MEM;
52 }
53
54 if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57
58 va_start(args, inlen);
59 curptr = in;
60 curlen = inlen;
61 for (;;) {
62 /* process buf */
63 if ((err = hash_descriptor[hash].process(md, curptr, curlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 /* step to next */
67 curptr = va_arg(args, const unsigned char*);
68 if (curptr == NULL) {
69 break;
70 }
71 curlen = va_arg(args, unsigned long);
72 }
73 err = hash_descriptor[hash].done(md, out);
74 *outlen = hash_descriptor[hash].hashsize;
75 LBL_ERR:
76 #ifdef LTC_CLEAN_STACK
77 zeromem(md, sizeof(hash_state));
78 #endif
79 XFREE(md);
80 va_end(args);
81 return err;
82 }
83
84 /* $Source$ */
85 /* $Revision$ */
86 /* $Date$ */
+0
-251
libtom-src/hashes/md2.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param md2.c
14 LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis
15 */
16
17 #ifdef LTC_MD2
18
19 const struct ltc_hash_descriptor md2_desc =
20 {
21 "md2",
22 7,
23 16,
24 16,
25
26 /* OID */
27 { 1, 2, 840, 113549, 2, 2, },
28 6,
29
30 &md2_init,
31 &md2_process,
32 &md2_done,
33 &md2_test,
34 NULL
35 };
36
37 static const unsigned char PI_SUBST[256] = {
38 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
39 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
40 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
41 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
42 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
43 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
44 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
45 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
46 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
47 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
48 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
49 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
50 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
51 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
52 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
53 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
54 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
55 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
56 };
57
58 /* adds 16 bytes to the checksum */
59 static void md2_update_chksum(hash_state *md)
60 {
61 int j;
62 unsigned char L;
63 L = md->md2.chksum[15];
64 for (j = 0; j < 16; j++) {
65
66 /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say
67 otherwise.
68 */
69 L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255);
70 }
71 }
72
73 static void md2_compress(hash_state *md)
74 {
75 int j, k;
76 unsigned char t;
77
78 /* copy block */
79 for (j = 0; j < 16; j++) {
80 md->md2.X[16+j] = md->md2.buf[j];
81 md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j];
82 }
83
84 t = (unsigned char)0;
85
86 /* do 18 rounds */
87 for (j = 0; j < 18; j++) {
88 for (k = 0; k < 48; k++) {
89 t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]);
90 }
91 t = (t + (unsigned char)j) & 255;
92 }
93 }
94
95 /**
96 Initialize the hash state
97 @param md The hash state you wish to initialize
98 @return CRYPT_OK if successful
99 */
100 int md2_init(hash_state *md)
101 {
102 LTC_ARGCHK(md != NULL);
103
104 /* LTC_MD2 uses a zero'ed state... */
105 zeromem(md->md2.X, sizeof(md->md2.X));
106 zeromem(md->md2.chksum, sizeof(md->md2.chksum));
107 zeromem(md->md2.buf, sizeof(md->md2.buf));
108 md->md2.curlen = 0;
109 return CRYPT_OK;
110 }
111
112 /**
113 Process a block of memory though the hash
114 @param md The hash state
115 @param in The data to hash
116 @param inlen The length of the data (octets)
117 @return CRYPT_OK if successful
118 */
119 int md2_process(hash_state *md, const unsigned char *in, unsigned long inlen)
120 {
121 unsigned long n;
122 LTC_ARGCHK(md != NULL);
123 LTC_ARGCHK(in != NULL);
124 if (md-> md2 .curlen > sizeof(md-> md2 .buf)) {
125 return CRYPT_INVALID_ARG;
126 }
127 while (inlen > 0) {
128 n = MIN(inlen, (16 - md->md2.curlen));
129 XMEMCPY(md->md2.buf + md->md2.curlen, in, (size_t)n);
130 md->md2.curlen += n;
131 in += n;
132 inlen -= n;
133
134 /* is 16 bytes full? */
135 if (md->md2.curlen == 16) {
136 md2_compress(md);
137 md2_update_chksum(md);
138 md->md2.curlen = 0;
139 }
140 }
141 return CRYPT_OK;
142 }
143
144 /**
145 Terminate the hash to get the digest
146 @param md The hash state
147 @param out [out] The destination of the hash (16 bytes)
148 @return CRYPT_OK if successful
149 */
150 int md2_done(hash_state * md, unsigned char *out)
151 {
152 unsigned long i, k;
153
154 LTC_ARGCHK(md != NULL);
155 LTC_ARGCHK(out != NULL);
156
157 if (md->md2.curlen >= sizeof(md->md2.buf)) {
158 return CRYPT_INVALID_ARG;
159 }
160
161
162 /* pad the message */
163 k = 16 - md->md2.curlen;
164 for (i = md->md2.curlen; i < 16; i++) {
165 md->md2.buf[i] = (unsigned char)k;
166 }
167
168 /* hash and update */
169 md2_compress(md);
170 md2_update_chksum(md);
171
172 /* hash checksum */
173 XMEMCPY(md->md2.buf, md->md2.chksum, 16);
174 md2_compress(md);
175
176 /* output is lower 16 bytes of X */
177 XMEMCPY(out, md->md2.X, 16);
178
179 #ifdef LTC_CLEAN_STACK
180 zeromem(md, sizeof(hash_state));
181 #endif
182 return CRYPT_OK;
183 }
184
185 /**
186 Self-test the hash
187 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
188 */
189 int md2_test(void)
190 {
191 #ifndef LTC_TEST
192 return CRYPT_NOP;
193 #else
194 static const struct {
195 char *msg;
196 unsigned char md[16];
197 } tests[] = {
198 { "",
199 {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
200 0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73
201 }
202 },
203 { "a",
204 {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
205 0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1
206 }
207 },
208 { "message digest",
209 {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
210 0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0
211 }
212 },
213 { "abcdefghijklmnopqrstuvwxyz",
214 {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
215 0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b
216 }
217 },
218 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
219 {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
220 0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd
221 }
222 },
223 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
224 {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
225 0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8
226 }
227 }
228 };
229 int i;
230 hash_state md;
231 unsigned char buf[16];
232
233 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
234 md2_init(&md);
235 md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
236 md2_done(&md, buf);
237 if (XMEMCMP(buf, tests[i].md, 16) != 0) {
238 return CRYPT_FAIL_TESTVECTOR;
239 }
240 }
241 return CRYPT_OK;
242 #endif
243 }
244
245 #endif
246
247
248 /* $Source$ */
249 /* $Revision$ */
250 /* $Date$ */
+0
-307
libtom-src/hashes/md4.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param md4.c
14 Submitted by Dobes Vandermeer (dobes@smartt.com)
15 */
16
17 #ifdef LTC_MD4
18
19 const struct ltc_hash_descriptor md4_desc =
20 {
21 "md4",
22 6,
23 16,
24 64,
25
26 /* OID */
27 { 1, 2, 840, 113549, 2, 4, },
28 6,
29
30 &md4_init,
31 &md4_process,
32 &md4_done,
33 &md4_test,
34 NULL
35 };
36
37 #define S11 3
38 #define S12 7
39 #define S13 11
40 #define S14 19
41 #define S21 3
42 #define S22 5
43 #define S23 9
44 #define S24 13
45 #define S31 3
46 #define S32 9
47 #define S33 11
48 #define S34 15
49
50 /* F, G and H are basic LTC_MD4 functions. */
51 #define F(x, y, z) (z ^ (x & (y ^ z)))
52 #define G(x, y, z) ((x & y) | (z & (x | y)))
53 #define H(x, y, z) ((x) ^ (y) ^ (z))
54
55 /* ROTATE_LEFT rotates x left n bits. */
56 #define ROTATE_LEFT(x, n) ROLc(x, n)
57
58 /* FF, GG and HH are transformations for rounds 1, 2 and 3 */
59 /* Rotation is separate from addition to prevent recomputation */
60
61 #define FF(a, b, c, d, x, s) { \
62 (a) += F ((b), (c), (d)) + (x); \
63 (a) = ROTATE_LEFT ((a), (s)); \
64 }
65 #define GG(a, b, c, d, x, s) { \
66 (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \
67 (a) = ROTATE_LEFT ((a), (s)); \
68 }
69 #define HH(a, b, c, d, x, s) { \
70 (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
71 (a) = ROTATE_LEFT ((a), (s)); \
72 }
73
74 #ifdef LTC_CLEAN_STACK
75 static int _md4_compress(hash_state *md, unsigned char *buf)
76 #else
77 static int md4_compress(hash_state *md, unsigned char *buf)
78 #endif
79 {
80 ulong32 x[16], a, b, c, d;
81 int i;
82
83 /* copy state */
84 a = md->md4.state[0];
85 b = md->md4.state[1];
86 c = md->md4.state[2];
87 d = md->md4.state[3];
88
89 /* copy the state into 512-bits into W[0..15] */
90 for (i = 0; i < 16; i++) {
91 LOAD32L(x[i], buf + (4*i));
92 }
93
94 /* Round 1 */
95 FF (a, b, c, d, x[ 0], S11); /* 1 */
96 FF (d, a, b, c, x[ 1], S12); /* 2 */
97 FF (c, d, a, b, x[ 2], S13); /* 3 */
98 FF (b, c, d, a, x[ 3], S14); /* 4 */
99 FF (a, b, c, d, x[ 4], S11); /* 5 */
100 FF (d, a, b, c, x[ 5], S12); /* 6 */
101 FF (c, d, a, b, x[ 6], S13); /* 7 */
102 FF (b, c, d, a, x[ 7], S14); /* 8 */
103 FF (a, b, c, d, x[ 8], S11); /* 9 */
104 FF (d, a, b, c, x[ 9], S12); /* 10 */
105 FF (c, d, a, b, x[10], S13); /* 11 */
106 FF (b, c, d, a, x[11], S14); /* 12 */
107 FF (a, b, c, d, x[12], S11); /* 13 */
108 FF (d, a, b, c, x[13], S12); /* 14 */
109 FF (c, d, a, b, x[14], S13); /* 15 */
110 FF (b, c, d, a, x[15], S14); /* 16 */
111
112 /* Round 2 */
113 GG (a, b, c, d, x[ 0], S21); /* 17 */
114 GG (d, a, b, c, x[ 4], S22); /* 18 */
115 GG (c, d, a, b, x[ 8], S23); /* 19 */
116 GG (b, c, d, a, x[12], S24); /* 20 */
117 GG (a, b, c, d, x[ 1], S21); /* 21 */
118 GG (d, a, b, c, x[ 5], S22); /* 22 */
119 GG (c, d, a, b, x[ 9], S23); /* 23 */
120 GG (b, c, d, a, x[13], S24); /* 24 */
121 GG (a, b, c, d, x[ 2], S21); /* 25 */
122 GG (d, a, b, c, x[ 6], S22); /* 26 */
123 GG (c, d, a, b, x[10], S23); /* 27 */
124 GG (b, c, d, a, x[14], S24); /* 28 */
125 GG (a, b, c, d, x[ 3], S21); /* 29 */
126 GG (d, a, b, c, x[ 7], S22); /* 30 */
127 GG (c, d, a, b, x[11], S23); /* 31 */
128 GG (b, c, d, a, x[15], S24); /* 32 */
129
130 /* Round 3 */
131 HH (a, b, c, d, x[ 0], S31); /* 33 */
132 HH (d, a, b, c, x[ 8], S32); /* 34 */
133 HH (c, d, a, b, x[ 4], S33); /* 35 */
134 HH (b, c, d, a, x[12], S34); /* 36 */
135 HH (a, b, c, d, x[ 2], S31); /* 37 */
136 HH (d, a, b, c, x[10], S32); /* 38 */
137 HH (c, d, a, b, x[ 6], S33); /* 39 */
138 HH (b, c, d, a, x[14], S34); /* 40 */
139 HH (a, b, c, d, x[ 1], S31); /* 41 */
140 HH (d, a, b, c, x[ 9], S32); /* 42 */
141 HH (c, d, a, b, x[ 5], S33); /* 43 */
142 HH (b, c, d, a, x[13], S34); /* 44 */
143 HH (a, b, c, d, x[ 3], S31); /* 45 */
144 HH (d, a, b, c, x[11], S32); /* 46 */
145 HH (c, d, a, b, x[ 7], S33); /* 47 */
146 HH (b, c, d, a, x[15], S34); /* 48 */
147
148
149 /* Update our state */
150 md->md4.state[0] = md->md4.state[0] + a;
151 md->md4.state[1] = md->md4.state[1] + b;
152 md->md4.state[2] = md->md4.state[2] + c;
153 md->md4.state[3] = md->md4.state[3] + d;
154
155 return CRYPT_OK;
156 }
157
158 #ifdef LTC_CLEAN_STACK
159 static int md4_compress(hash_state *md, unsigned char *buf)
160 {
161 int err;
162 err = _md4_compress(md, buf);
163 burn_stack(sizeof(ulong32) * 20 + sizeof(int));
164 return err;
165 }
166 #endif
167
168 /**
169 Initialize the hash state
170 @param md The hash state you wish to initialize
171 @return CRYPT_OK if successful
172 */
173 int md4_init(hash_state * md)
174 {
175 LTC_ARGCHK(md != NULL);
176 md->md4.state[0] = 0x67452301UL;
177 md->md4.state[1] = 0xefcdab89UL;
178 md->md4.state[2] = 0x98badcfeUL;
179 md->md4.state[3] = 0x10325476UL;
180 md->md4.length = 0;
181 md->md4.curlen = 0;
182 return CRYPT_OK;
183 }
184
185 /**
186 Process a block of memory though the hash
187 @param md The hash state
188 @param in The data to hash
189 @param inlen The length of the data (octets)
190 @return CRYPT_OK if successful
191 */
192 HASH_PROCESS(md4_process, md4_compress, md4, 64)
193
194 /**
195 Terminate the hash to get the digest
196 @param md The hash state
197 @param out [out] The destination of the hash (16 bytes)
198 @return CRYPT_OK if successful
199 */
200 int md4_done(hash_state * md, unsigned char *out)
201 {
202 int i;
203
204 LTC_ARGCHK(md != NULL);
205 LTC_ARGCHK(out != NULL);
206
207 if (md->md4.curlen >= sizeof(md->md4.buf)) {
208 return CRYPT_INVALID_ARG;
209 }
210
211 /* increase the length of the message */
212 md->md4.length += md->md4.curlen * 8;
213
214 /* append the '1' bit */
215 md->md4.buf[md->md4.curlen++] = (unsigned char)0x80;
216
217 /* if the length is currently above 56 bytes we append zeros
218 * then compress. Then we can fall back to padding zeros and length
219 * encoding like normal.
220 */
221 if (md->md4.curlen > 56) {
222 while (md->md4.curlen < 64) {
223 md->md4.buf[md->md4.curlen++] = (unsigned char)0;
224 }
225 md4_compress(md, md->md4.buf);
226 md->md4.curlen = 0;
227 }
228
229 /* pad upto 56 bytes of zeroes */
230 while (md->md4.curlen < 56) {
231 md->md4.buf[md->md4.curlen++] = (unsigned char)0;
232 }
233
234 /* store length */
235 STORE64L(md->md4.length, md->md4.buf+56);
236 md4_compress(md, md->md4.buf);
237
238 /* copy output */
239 for (i = 0; i < 4; i++) {
240 STORE32L(md->md4.state[i], out+(4*i));
241 }
242 #ifdef LTC_CLEAN_STACK
243 zeromem(md, sizeof(hash_state));
244 #endif
245 return CRYPT_OK;
246 }
247
248 /**
249 Self-test the hash
250 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
251 */
252 int md4_test(void)
253 {
254 #ifndef LTC_TEST
255 return CRYPT_NOP;
256 #else
257 static const struct md4_test_case {
258 char *input;
259 unsigned char digest[16];
260 } cases[] = {
261 { "",
262 {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
263 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} },
264 { "a",
265 {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
266 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} },
267 { "abc",
268 {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
269 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} },
270 { "message digest",
271 {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
272 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} },
273 { "abcdefghijklmnopqrstuvwxyz",
274 {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
275 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} },
276 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
277 {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
278 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} },
279 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
280 {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
281 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} },
282 };
283 int i;
284 hash_state md;
285 unsigned char digest[16];
286
287 for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
288 md4_init(&md);
289 md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input));
290 md4_done(&md, digest);
291 if (XMEMCMP(digest, cases[i].digest, 16) != 0) {
292 return CRYPT_FAIL_TESTVECTOR;
293 }
294
295 }
296 return CRYPT_OK;
297 #endif
298 }
299
300 #endif
301
302
303
304 /* $Source$ */
305 /* $Revision$ */
306 /* $Date$ */
+0
-368
libtom-src/hashes/md5.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12
13 /**
14 @file md5.c
15 LTC_MD5 hash function by Tom St Denis
16 */
17
18 #ifdef LTC_MD5
19
20 const struct ltc_hash_descriptor md5_desc =
21 {
22 "md5",
23 3,
24 16,
25 64,
26
27 /* OID */
28 { 1, 2, 840, 113549, 2, 5, },
29 6,
30
31 &md5_init,
32 &md5_process,
33 &md5_done,
34 &md5_test,
35 NULL
36 };
37
38 #define F(x,y,z) (z ^ (x & (y ^ z)))
39 #define G(x,y,z) (y ^ (z & (y ^ x)))
40 #define H(x,y,z) (x^y^z)
41 #define I(x,y,z) (y^(x|(~z)))
42
43 #ifdef LTC_SMALL_CODE
44
45 #define FF(a,b,c,d,M,s,t) \
46 a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
47
48 #define GG(a,b,c,d,M,s,t) \
49 a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
50
51 #define HH(a,b,c,d,M,s,t) \
52 a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
53
54 #define II(a,b,c,d,M,s,t) \
55 a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
56
57 static const unsigned char Worder[64] = {
58 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
59 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
60 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
61 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
62 };
63
64 static const unsigned char Rorder[64] = {
65 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
66 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
67 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
68 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
69 };
70
71 static const ulong32 Korder[64] = {
72 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
73 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
74 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
75 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
76 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
77 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
78 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
79 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
80 };
81
82 #else
83
84 #define FF(a,b,c,d,M,s,t) \
85 a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
86
87 #define GG(a,b,c,d,M,s,t) \
88 a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
89
90 #define HH(a,b,c,d,M,s,t) \
91 a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
92
93 #define II(a,b,c,d,M,s,t) \
94 a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
95
96
97 #endif
98
99 #ifdef LTC_CLEAN_STACK
100 static int _md5_compress(hash_state *md, unsigned char *buf)
101 #else
102 static int md5_compress(hash_state *md, unsigned char *buf)
103 #endif
104 {
105 ulong32 i, W[16], a, b, c, d;
106 #ifdef LTC_SMALL_CODE
107 ulong32 t;
108 #endif
109
110 /* copy the state into 512-bits into W[0..15] */
111 for (i = 0; i < 16; i++) {
112 LOAD32L(W[i], buf + (4*i));
113 }
114
115 /* copy state */
116 a = md->md5.state[0];
117 b = md->md5.state[1];
118 c = md->md5.state[2];
119 d = md->md5.state[3];
120
121 #ifdef LTC_SMALL_CODE
122 for (i = 0; i < 16; ++i) {
123 FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
124 t = d; d = c; c = b; b = a; a = t;
125 }
126
127 for (; i < 32; ++i) {
128 GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
129 t = d; d = c; c = b; b = a; a = t;
130 }
131
132 for (; i < 48; ++i) {
133 HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
134 t = d; d = c; c = b; b = a; a = t;
135 }
136
137 for (; i < 64; ++i) {
138 II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
139 t = d; d = c; c = b; b = a; a = t;
140 }
141
142 #else
143 FF(a,b,c,d,W[0],7,0xd76aa478UL)
144 FF(d,a,b,c,W[1],12,0xe8c7b756UL)
145 FF(c,d,a,b,W[2],17,0x242070dbUL)
146 FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
147 FF(a,b,c,d,W[4],7,0xf57c0fafUL)
148 FF(d,a,b,c,W[5],12,0x4787c62aUL)
149 FF(c,d,a,b,W[6],17,0xa8304613UL)
150 FF(b,c,d,a,W[7],22,0xfd469501UL)
151 FF(a,b,c,d,W[8],7,0x698098d8UL)
152 FF(d,a,b,c,W[9],12,0x8b44f7afUL)
153 FF(c,d,a,b,W[10],17,0xffff5bb1UL)
154 FF(b,c,d,a,W[11],22,0x895cd7beUL)
155 FF(a,b,c,d,W[12],7,0x6b901122UL)
156 FF(d,a,b,c,W[13],12,0xfd987193UL)
157 FF(c,d,a,b,W[14],17,0xa679438eUL)
158 FF(b,c,d,a,W[15],22,0x49b40821UL)
159 GG(a,b,c,d,W[1],5,0xf61e2562UL)
160 GG(d,a,b,c,W[6],9,0xc040b340UL)
161 GG(c,d,a,b,W[11],14,0x265e5a51UL)
162 GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
163 GG(a,b,c,d,W[5],5,0xd62f105dUL)
164 GG(d,a,b,c,W[10],9,0x02441453UL)
165 GG(c,d,a,b,W[15],14,0xd8a1e681UL)
166 GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
167 GG(a,b,c,d,W[9],5,0x21e1cde6UL)
168 GG(d,a,b,c,W[14],9,0xc33707d6UL)
169 GG(c,d,a,b,W[3],14,0xf4d50d87UL)
170 GG(b,c,d,a,W[8],20,0x455a14edUL)
171 GG(a,b,c,d,W[13],5,0xa9e3e905UL)
172 GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
173 GG(c,d,a,b,W[7],14,0x676f02d9UL)
174 GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
175 HH(a,b,c,d,W[5],4,0xfffa3942UL)
176 HH(d,a,b,c,W[8],11,0x8771f681UL)
177 HH(c,d,a,b,W[11],16,0x6d9d6122UL)
178 HH(b,c,d,a,W[14],23,0xfde5380cUL)
179 HH(a,b,c,d,W[1],4,0xa4beea44UL)
180 HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
181 HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
182 HH(b,c,d,a,W[10],23,0xbebfbc70UL)
183 HH(a,b,c,d,W[13],4,0x289b7ec6UL)
184 HH(d,a,b,c,W[0],11,0xeaa127faUL)
185 HH(c,d,a,b,W[3],16,0xd4ef3085UL)
186 HH(b,c,d,a,W[6],23,0x04881d05UL)
187 HH(a,b,c,d,W[9],4,0xd9d4d039UL)
188 HH(d,a,b,c,W[12],11,0xe6db99e5UL)
189 HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
190 HH(b,c,d,a,W[2],23,0xc4ac5665UL)
191 II(a,b,c,d,W[0],6,0xf4292244UL)
192 II(d,a,b,c,W[7],10,0x432aff97UL)
193 II(c,d,a,b,W[14],15,0xab9423a7UL)
194 II(b,c,d,a,W[5],21,0xfc93a039UL)
195 II(a,b,c,d,W[12],6,0x655b59c3UL)
196 II(d,a,b,c,W[3],10,0x8f0ccc92UL)
197 II(c,d,a,b,W[10],15,0xffeff47dUL)
198 II(b,c,d,a,W[1],21,0x85845dd1UL)
199 II(a,b,c,d,W[8],6,0x6fa87e4fUL)
200 II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
201 II(c,d,a,b,W[6],15,0xa3014314UL)
202 II(b,c,d,a,W[13],21,0x4e0811a1UL)
203 II(a,b,c,d,W[4],6,0xf7537e82UL)
204 II(d,a,b,c,W[11],10,0xbd3af235UL)
205 II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
206 II(b,c,d,a,W[9],21,0xeb86d391UL)
207 #endif
208
209 md->md5.state[0] = md->md5.state[0] + a;
210 md->md5.state[1] = md->md5.state[1] + b;
211 md->md5.state[2] = md->md5.state[2] + c;
212 md->md5.state[3] = md->md5.state[3] + d;
213
214 return CRYPT_OK;
215 }
216
217 #ifdef LTC_CLEAN_STACK
218 static int md5_compress(hash_state *md, unsigned char *buf)
219 {
220 int err;
221 err = _md5_compress(md, buf);
222 burn_stack(sizeof(ulong32) * 21);
223 return err;
224 }
225 #endif
226
227 /**
228 Initialize the hash state
229 @param md The hash state you wish to initialize
230 @return CRYPT_OK if successful
231 */
232 int md5_init(hash_state * md)
233 {
234 LTC_ARGCHK(md != NULL);
235 md->md5.state[0] = 0x67452301UL;
236 md->md5.state[1] = 0xefcdab89UL;
237 md->md5.state[2] = 0x98badcfeUL;
238 md->md5.state[3] = 0x10325476UL;
239 md->md5.curlen = 0;
240 md->md5.length = 0;
241 return CRYPT_OK;
242 }
243
244 /**
245 Process a block of memory though the hash
246 @param md The hash state
247 @param in The data to hash
248 @param inlen The length of the data (octets)
249 @return CRYPT_OK if successful
250 */
251 HASH_PROCESS(md5_process, md5_compress, md5, 64)
252
253 /**
254 Terminate the hash to get the digest
255 @param md The hash state
256 @param out [out] The destination of the hash (16 bytes)
257 @return CRYPT_OK if successful
258 */
259 int md5_done(hash_state * md, unsigned char *out)
260 {
261 int i;
262
263 LTC_ARGCHK(md != NULL);
264 LTC_ARGCHK(out != NULL);
265
266 if (md->md5.curlen >= sizeof(md->md5.buf)) {
267 return CRYPT_INVALID_ARG;
268 }
269
270
271 /* increase the length of the message */
272 md->md5.length += md->md5.curlen * 8;
273
274 /* append the '1' bit */
275 md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
276
277 /* if the length is currently above 56 bytes we append zeros
278 * then compress. Then we can fall back to padding zeros and length
279 * encoding like normal.
280 */
281 if (md->md5.curlen > 56) {
282 while (md->md5.curlen < 64) {
283 md->md5.buf[md->md5.curlen++] = (unsigned char)0;
284 }
285 md5_compress(md, md->md5.buf);
286 md->md5.curlen = 0;
287 }
288
289 /* pad upto 56 bytes of zeroes */
290 while (md->md5.curlen < 56) {
291 md->md5.buf[md->md5.curlen++] = (unsigned char)0;
292 }
293
294 /* store length */
295 STORE64L(md->md5.length, md->md5.buf+56);
296 md5_compress(md, md->md5.buf);
297
298 /* copy output */
299 for (i = 0; i < 4; i++) {
300 STORE32L(md->md5.state[i], out+(4*i));
301 }
302 #ifdef LTC_CLEAN_STACK
303 zeromem(md, sizeof(hash_state));
304 #endif
305 return CRYPT_OK;
306 }
307
308 /**
309 Self-test the hash
310 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
311 */
312 int md5_test(void)
313 {
314 #ifndef LTC_TEST
315 return CRYPT_NOP;
316 #else
317 static const struct {
318 char *msg;
319 unsigned char hash[16];
320 } tests[] = {
321 { "",
322 { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
323 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
324 { "a",
325 {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
326 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
327 { "abc",
328 { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
329 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
330 { "message digest",
331 { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
332 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
333 { "abcdefghijklmnopqrstuvwxyz",
334 { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
335 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
336 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
337 { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
338 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
339 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
340 { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
341 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
342 { NULL, { 0 } }
343 };
344
345 int i;
346 unsigned char tmp[16];
347 hash_state md;
348
349 for (i = 0; tests[i].msg != NULL; i++) {
350 md5_init(&md);
351 md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
352 md5_done(&md, tmp);
353 if (XMEMCMP(tmp, tests[i].hash, 16) != 0) {
354 return CRYPT_FAIL_TESTVECTOR;
355 }
356 }
357 return CRYPT_OK;
358 #endif
359 }
360
361 #endif
362
363
364
365 /* $Source$ */
366 /* $Revision$ */
367 /* $Date$ */
+0
-410
libtom-src/hashes/rmd128.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param rmd128.c
14 RMD128 Hash function
15 */
16
17 /* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
18 *
19 * This source has been radically overhauled to be portable and work within
20 * the LibTomCrypt API by Tom St Denis
21 */
22
23 #ifdef LTC_RIPEMD128
24
25 const struct ltc_hash_descriptor rmd128_desc =
26 {
27 "rmd128",
28 8,
29 16,
30 64,
31
32 /* OID */
33 { 1, 0, 10118, 3, 0, 50 },
34 6,
35
36 &rmd128_init,
37 &rmd128_process,
38 &rmd128_done,
39 &rmd128_test,
40 NULL
41 };
42
43 /* the four basic functions F(), G() and H() */
44 #define F(x, y, z) ((x) ^ (y) ^ (z))
45 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
46 #define H(x, y, z) (((x) | ~(y)) ^ (z))
47 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
48
49 /* the eight basic operations FF() through III() */
50 #define FF(a, b, c, d, x, s) \
51 (a) += F((b), (c), (d)) + (x);\
52 (a) = ROLc((a), (s));
53
54 #define GG(a, b, c, d, x, s) \
55 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
56 (a) = ROLc((a), (s));
57
58 #define HH(a, b, c, d, x, s) \
59 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
60 (a) = ROLc((a), (s));
61
62 #define II(a, b, c, d, x, s) \
63 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
64 (a) = ROLc((a), (s));
65
66 #define FFF(a, b, c, d, x, s) \
67 (a) += F((b), (c), (d)) + (x);\
68 (a) = ROLc((a), (s));
69
70 #define GGG(a, b, c, d, x, s) \
71 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
72 (a) = ROLc((a), (s));
73
74 #define HHH(a, b, c, d, x, s) \
75 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
76 (a) = ROLc((a), (s));
77
78 #define III(a, b, c, d, x, s) \
79 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
80 (a) = ROLc((a), (s));
81
82 #ifdef LTC_CLEAN_STACK
83 static int _rmd128_compress(hash_state *md, unsigned char *buf)
84 #else
85 static int rmd128_compress(hash_state *md, unsigned char *buf)
86 #endif
87 {
88 ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16];
89 int i;
90
91 /* load words X */
92 for (i = 0; i < 16; i++){
93 LOAD32L(X[i], buf + (4 * i));
94 }
95
96 /* load state */
97 aa = aaa = md->rmd128.state[0];
98 bb = bbb = md->rmd128.state[1];
99 cc = ccc = md->rmd128.state[2];
100 dd = ddd = md->rmd128.state[3];
101
102 /* round 1 */
103 FF(aa, bb, cc, dd, X[ 0], 11);
104 FF(dd, aa, bb, cc, X[ 1], 14);
105 FF(cc, dd, aa, bb, X[ 2], 15);
106 FF(bb, cc, dd, aa, X[ 3], 12);
107 FF(aa, bb, cc, dd, X[ 4], 5);
108 FF(dd, aa, bb, cc, X[ 5], 8);
109 FF(cc, dd, aa, bb, X[ 6], 7);
110 FF(bb, cc, dd, aa, X[ 7], 9);
111 FF(aa, bb, cc, dd, X[ 8], 11);
112 FF(dd, aa, bb, cc, X[ 9], 13);
113 FF(cc, dd, aa, bb, X[10], 14);
114 FF(bb, cc, dd, aa, X[11], 15);
115 FF(aa, bb, cc, dd, X[12], 6);
116 FF(dd, aa, bb, cc, X[13], 7);
117 FF(cc, dd, aa, bb, X[14], 9);
118 FF(bb, cc, dd, aa, X[15], 8);
119
120 /* round 2 */
121 GG(aa, bb, cc, dd, X[ 7], 7);
122 GG(dd, aa, bb, cc, X[ 4], 6);
123 GG(cc, dd, aa, bb, X[13], 8);
124 GG(bb, cc, dd, aa, X[ 1], 13);
125 GG(aa, bb, cc, dd, X[10], 11);
126 GG(dd, aa, bb, cc, X[ 6], 9);
127 GG(cc, dd, aa, bb, X[15], 7);
128 GG(bb, cc, dd, aa, X[ 3], 15);
129 GG(aa, bb, cc, dd, X[12], 7);
130 GG(dd, aa, bb, cc, X[ 0], 12);
131 GG(cc, dd, aa, bb, X[ 9], 15);
132 GG(bb, cc, dd, aa, X[ 5], 9);
133 GG(aa, bb, cc, dd, X[ 2], 11);
134 GG(dd, aa, bb, cc, X[14], 7);
135 GG(cc, dd, aa, bb, X[11], 13);
136 GG(bb, cc, dd, aa, X[ 8], 12);
137
138 /* round 3 */
139 HH(aa, bb, cc, dd, X[ 3], 11);
140 HH(dd, aa, bb, cc, X[10], 13);
141 HH(cc, dd, aa, bb, X[14], 6);
142 HH(bb, cc, dd, aa, X[ 4], 7);
143 HH(aa, bb, cc, dd, X[ 9], 14);
144 HH(dd, aa, bb, cc, X[15], 9);
145 HH(cc, dd, aa, bb, X[ 8], 13);
146 HH(bb, cc, dd, aa, X[ 1], 15);
147 HH(aa, bb, cc, dd, X[ 2], 14);
148 HH(dd, aa, bb, cc, X[ 7], 8);
149 HH(cc, dd, aa, bb, X[ 0], 13);
150 HH(bb, cc, dd, aa, X[ 6], 6);
151 HH(aa, bb, cc, dd, X[13], 5);
152 HH(dd, aa, bb, cc, X[11], 12);
153 HH(cc, dd, aa, bb, X[ 5], 7);
154 HH(bb, cc, dd, aa, X[12], 5);
155
156 /* round 4 */
157 II(aa, bb, cc, dd, X[ 1], 11);
158 II(dd, aa, bb, cc, X[ 9], 12);
159 II(cc, dd, aa, bb, X[11], 14);
160 II(bb, cc, dd, aa, X[10], 15);
161 II(aa, bb, cc, dd, X[ 0], 14);
162 II(dd, aa, bb, cc, X[ 8], 15);
163 II(cc, dd, aa, bb, X[12], 9);
164 II(bb, cc, dd, aa, X[ 4], 8);
165 II(aa, bb, cc, dd, X[13], 9);
166 II(dd, aa, bb, cc, X[ 3], 14);
167 II(cc, dd, aa, bb, X[ 7], 5);
168 II(bb, cc, dd, aa, X[15], 6);
169 II(aa, bb, cc, dd, X[14], 8);
170 II(dd, aa, bb, cc, X[ 5], 6);
171 II(cc, dd, aa, bb, X[ 6], 5);
172 II(bb, cc, dd, aa, X[ 2], 12);
173
174 /* parallel round 1 */
175 III(aaa, bbb, ccc, ddd, X[ 5], 8);
176 III(ddd, aaa, bbb, ccc, X[14], 9);
177 III(ccc, ddd, aaa, bbb, X[ 7], 9);
178 III(bbb, ccc, ddd, aaa, X[ 0], 11);
179 III(aaa, bbb, ccc, ddd, X[ 9], 13);
180 III(ddd, aaa, bbb, ccc, X[ 2], 15);
181 III(ccc, ddd, aaa, bbb, X[11], 15);
182 III(bbb, ccc, ddd, aaa, X[ 4], 5);
183 III(aaa, bbb, ccc, ddd, X[13], 7);
184 III(ddd, aaa, bbb, ccc, X[ 6], 7);
185 III(ccc, ddd, aaa, bbb, X[15], 8);
186 III(bbb, ccc, ddd, aaa, X[ 8], 11);
187 III(aaa, bbb, ccc, ddd, X[ 1], 14);
188 III(ddd, aaa, bbb, ccc, X[10], 14);
189 III(ccc, ddd, aaa, bbb, X[ 3], 12);
190 III(bbb, ccc, ddd, aaa, X[12], 6);
191
192 /* parallel round 2 */
193 HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
194 HHH(ddd, aaa, bbb, ccc, X[11], 13);
195 HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
196 HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
197 HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
198 HHH(ddd, aaa, bbb, ccc, X[13], 8);
199 HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
200 HHH(bbb, ccc, ddd, aaa, X[10], 11);
201 HHH(aaa, bbb, ccc, ddd, X[14], 7);
202 HHH(ddd, aaa, bbb, ccc, X[15], 7);
203 HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
204 HHH(bbb, ccc, ddd, aaa, X[12], 7);
205 HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
206 HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
207 HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
208 HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
209
210 /* parallel round 3 */
211 GGG(aaa, bbb, ccc, ddd, X[15], 9);
212 GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
213 GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
214 GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
215 GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
216 GGG(ddd, aaa, bbb, ccc, X[14], 6);
217 GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
218 GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
219 GGG(aaa, bbb, ccc, ddd, X[11], 12);
220 GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
221 GGG(ccc, ddd, aaa, bbb, X[12], 5);
222 GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
223 GGG(aaa, bbb, ccc, ddd, X[10], 13);
224 GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
225 GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
226 GGG(bbb, ccc, ddd, aaa, X[13], 5);
227
228 /* parallel round 4 */
229 FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
230 FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
231 FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
232 FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
233 FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
234 FFF(ddd, aaa, bbb, ccc, X[11], 14);
235 FFF(ccc, ddd, aaa, bbb, X[15], 6);
236 FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
237 FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
238 FFF(ddd, aaa, bbb, ccc, X[12], 9);
239 FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
240 FFF(bbb, ccc, ddd, aaa, X[13], 9);
241 FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
242 FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
243 FFF(ccc, ddd, aaa, bbb, X[10], 15);
244 FFF(bbb, ccc, ddd, aaa, X[14], 8);
245
246 /* combine results */
247 ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */
248 md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa;
249 md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb;
250 md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc;
251 md->rmd128.state[0] = ddd;
252
253 return CRYPT_OK;
254 }
255
256 #ifdef LTC_CLEAN_STACK
257 static int rmd128_compress(hash_state *md, unsigned char *buf)
258 {
259 int err;
260 err = _rmd128_compress(md, buf);
261 burn_stack(sizeof(ulong32) * 24 + sizeof(int));
262 return err;
263 }
264 #endif
265
266 /**
267 Initialize the hash state
268 @param md The hash state you wish to initialize
269 @return CRYPT_OK if successful
270 */
271 int rmd128_init(hash_state * md)
272 {
273 LTC_ARGCHK(md != NULL);
274 md->rmd128.state[0] = 0x67452301UL;
275 md->rmd128.state[1] = 0xefcdab89UL;
276 md->rmd128.state[2] = 0x98badcfeUL;
277 md->rmd128.state[3] = 0x10325476UL;
278 md->rmd128.curlen = 0;
279 md->rmd128.length = 0;
280 return CRYPT_OK;
281 }
282
283 /**
284 Process a block of memory though the hash
285 @param md The hash state
286 @param in The data to hash
287 @param inlen The length of the data (octets)
288 @return CRYPT_OK if successful
289 */
290 HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64)
291
292 /**
293 Terminate the hash to get the digest
294 @param md The hash state
295 @param out [out] The destination of the hash (16 bytes)
296 @return CRYPT_OK if successful
297 */
298 int rmd128_done(hash_state * md, unsigned char *out)
299 {
300 int i;
301
302 LTC_ARGCHK(md != NULL);
303 LTC_ARGCHK(out != NULL);
304
305 if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) {
306 return CRYPT_INVALID_ARG;
307 }
308
309
310 /* increase the length of the message */
311 md->rmd128.length += md->rmd128.curlen * 8;
312
313 /* append the '1' bit */
314 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80;
315
316 /* if the length is currently above 56 bytes we append zeros
317 * then compress. Then we can fall back to padding zeros and length
318 * encoding like normal.
319 */
320 if (md->rmd128.curlen > 56) {
321 while (md->rmd128.curlen < 64) {
322 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
323 }
324 rmd128_compress(md, md->rmd128.buf);
325 md->rmd128.curlen = 0;
326 }
327
328 /* pad upto 56 bytes of zeroes */
329 while (md->rmd128.curlen < 56) {
330 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
331 }
332
333 /* store length */
334 STORE64L(md->rmd128.length, md->rmd128.buf+56);
335 rmd128_compress(md, md->rmd128.buf);
336
337 /* copy output */
338 for (i = 0; i < 4; i++) {
339 STORE32L(md->rmd128.state[i], out+(4*i));
340 }
341 #ifdef LTC_CLEAN_STACK
342 zeromem(md, sizeof(hash_state));
343 #endif
344 return CRYPT_OK;
345 }
346
347 /**
348 Self-test the hash
349 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
350 */
351 int rmd128_test(void)
352 {
353 #ifndef LTC_TEST
354 return CRYPT_NOP;
355 #else
356 static const struct {
357 char *msg;
358 unsigned char md[16];
359 } tests[] = {
360 { "",
361 { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
362 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 }
363 },
364 { "a",
365 { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
366 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 }
367 },
368 { "abc",
369 { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
370 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 }
371 },
372 { "message digest",
373 { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
374 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 }
375 },
376 { "abcdefghijklmnopqrstuvwxyz",
377 { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
378 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e }
379 },
380 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
381 { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
382 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 }
383 }
384 };
385 int x;
386 unsigned char buf[16];
387 hash_state md;
388
389 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
390 rmd128_init(&md);
391 rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
392 rmd128_done(&md, buf);
393 if (XMEMCMP(buf, tests[x].md, 16) != 0) {
394 #if 0
395 printf("Failed test %d\n", x);
396 #endif
397 return CRYPT_FAIL_TESTVECTOR;
398 }
399 }
400 return CRYPT_OK;
401 #endif
402 }
403
404 #endif
405
406
407 /* $Source$ */
408 /* $Revision$ */
409 /* $Date$ */
+0
-469
libtom-src/hashes/rmd160.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rmd160.c
14 RMD160 hash function
15 */
16
17 /* Implementation of LTC_RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC
18 *
19 * This source has been radically overhauled to be portable and work within
20 * the LibTomCrypt API by Tom St Denis
21 */
22
23 #ifdef LTC_RIPEMD160
24
25 const struct ltc_hash_descriptor rmd160_desc =
26 {
27 "rmd160",
28 9,
29 20,
30 64,
31
32 /* OID */
33 { 1, 3, 36, 3, 2, 1, },
34 6,
35
36 &rmd160_init,
37 &rmd160_process,
38 &rmd160_done,
39 &rmd160_test,
40 NULL
41 };
42
43 /* the five basic functions F(), G() and H() */
44 #define F(x, y, z) ((x) ^ (y) ^ (z))
45 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
46 #define H(x, y, z) (((x) | ~(y)) ^ (z))
47 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
48 #define J(x, y, z) ((x) ^ ((y) | ~(z)))
49
50 /* the ten basic operations FF() through III() */
51 #define FF(a, b, c, d, e, x, s) \
52 (a) += F((b), (c), (d)) + (x);\
53 (a) = ROLc((a), (s)) + (e);\
54 (c) = ROLc((c), 10);
55
56 #define GG(a, b, c, d, e, x, s) \
57 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
58 (a) = ROLc((a), (s)) + (e);\
59 (c) = ROLc((c), 10);
60
61 #define HH(a, b, c, d, e, x, s) \
62 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
63 (a) = ROLc((a), (s)) + (e);\
64 (c) = ROLc((c), 10);
65
66 #define II(a, b, c, d, e, x, s) \
67 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
68 (a) = ROLc((a), (s)) + (e);\
69 (c) = ROLc((c), 10);
70
71 #define JJ(a, b, c, d, e, x, s) \
72 (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
73 (a) = ROLc((a), (s)) + (e);\
74 (c) = ROLc((c), 10);
75
76 #define FFF(a, b, c, d, e, x, s) \
77 (a) += F((b), (c), (d)) + (x);\
78 (a) = ROLc((a), (s)) + (e);\
79 (c) = ROLc((c), 10);
80
81 #define GGG(a, b, c, d, e, x, s) \
82 (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
83 (a) = ROLc((a), (s)) + (e);\
84 (c) = ROLc((c), 10);
85
86 #define HHH(a, b, c, d, e, x, s) \
87 (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
88 (a) = ROLc((a), (s)) + (e);\
89 (c) = ROLc((c), 10);
90
91 #define III(a, b, c, d, e, x, s) \
92 (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
93 (a) = ROLc((a), (s)) + (e);\
94 (c) = ROLc((c), 10);
95
96 #define JJJ(a, b, c, d, e, x, s) \
97 (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
98 (a) = ROLc((a), (s)) + (e);\
99 (c) = ROLc((c), 10);
100
101
102 #ifdef LTC_CLEAN_STACK
103 static int _rmd160_compress(hash_state *md, unsigned char *buf)
104 #else
105 static int rmd160_compress(hash_state *md, unsigned char *buf)
106 #endif
107 {
108 ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16];
109 int i;
110
111 /* load words X */
112 for (i = 0; i < 16; i++){
113 LOAD32L(X[i], buf + (4 * i));
114 }
115
116 /* load state */
117 aa = aaa = md->rmd160.state[0];
118 bb = bbb = md->rmd160.state[1];
119 cc = ccc = md->rmd160.state[2];
120 dd = ddd = md->rmd160.state[3];
121 ee = eee = md->rmd160.state[4];
122
123 /* round 1 */
124 FF(aa, bb, cc, dd, ee, X[ 0], 11);
125 FF(ee, aa, bb, cc, dd, X[ 1], 14);
126 FF(dd, ee, aa, bb, cc, X[ 2], 15);
127 FF(cc, dd, ee, aa, bb, X[ 3], 12);
128 FF(bb, cc, dd, ee, aa, X[ 4], 5);
129 FF(aa, bb, cc, dd, ee, X[ 5], 8);
130 FF(ee, aa, bb, cc, dd, X[ 6], 7);
131 FF(dd, ee, aa, bb, cc, X[ 7], 9);
132 FF(cc, dd, ee, aa, bb, X[ 8], 11);
133 FF(bb, cc, dd, ee, aa, X[ 9], 13);
134 FF(aa, bb, cc, dd, ee, X[10], 14);
135 FF(ee, aa, bb, cc, dd, X[11], 15);
136 FF(dd, ee, aa, bb, cc, X[12], 6);
137 FF(cc, dd, ee, aa, bb, X[13], 7);
138 FF(bb, cc, dd, ee, aa, X[14], 9);
139 FF(aa, bb, cc, dd, ee, X[15], 8);
140
141 /* round 2 */
142 GG(ee, aa, bb, cc, dd, X[ 7], 7);
143 GG(dd, ee, aa, bb, cc, X[ 4], 6);
144 GG(cc, dd, ee, aa, bb, X[13], 8);
145 GG(bb, cc, dd, ee, aa, X[ 1], 13);
146 GG(aa, bb, cc, dd, ee, X[10], 11);
147 GG(ee, aa, bb, cc, dd, X[ 6], 9);
148 GG(dd, ee, aa, bb, cc, X[15], 7);
149 GG(cc, dd, ee, aa, bb, X[ 3], 15);
150 GG(bb, cc, dd, ee, aa, X[12], 7);
151 GG(aa, bb, cc, dd, ee, X[ 0], 12);
152 GG(ee, aa, bb, cc, dd, X[ 9], 15);
153 GG(dd, ee, aa, bb, cc, X[ 5], 9);
154 GG(cc, dd, ee, aa, bb, X[ 2], 11);
155 GG(bb, cc, dd, ee, aa, X[14], 7);
156 GG(aa, bb, cc, dd, ee, X[11], 13);
157 GG(ee, aa, bb, cc, dd, X[ 8], 12);
158
159 /* round 3 */
160 HH(dd, ee, aa, bb, cc, X[ 3], 11);
161 HH(cc, dd, ee, aa, bb, X[10], 13);
162 HH(bb, cc, dd, ee, aa, X[14], 6);
163 HH(aa, bb, cc, dd, ee, X[ 4], 7);
164 HH(ee, aa, bb, cc, dd, X[ 9], 14);
165 HH(dd, ee, aa, bb, cc, X[15], 9);
166 HH(cc, dd, ee, aa, bb, X[ 8], 13);
167 HH(bb, cc, dd, ee, aa, X[ 1], 15);
168 HH(aa, bb, cc, dd, ee, X[ 2], 14);
169 HH(ee, aa, bb, cc, dd, X[ 7], 8);
170 HH(dd, ee, aa, bb, cc, X[ 0], 13);
171 HH(cc, dd, ee, aa, bb, X[ 6], 6);
172 HH(bb, cc, dd, ee, aa, X[13], 5);
173 HH(aa, bb, cc, dd, ee, X[11], 12);
174 HH(ee, aa, bb, cc, dd, X[ 5], 7);
175 HH(dd, ee, aa, bb, cc, X[12], 5);
176
177 /* round 4 */
178 II(cc, dd, ee, aa, bb, X[ 1], 11);
179 II(bb, cc, dd, ee, aa, X[ 9], 12);
180 II(aa, bb, cc, dd, ee, X[11], 14);
181 II(ee, aa, bb, cc, dd, X[10], 15);
182 II(dd, ee, aa, bb, cc, X[ 0], 14);
183 II(cc, dd, ee, aa, bb, X[ 8], 15);
184 II(bb, cc, dd, ee, aa, X[12], 9);
185 II(aa, bb, cc, dd, ee, X[ 4], 8);
186 II(ee, aa, bb, cc, dd, X[13], 9);
187 II(dd, ee, aa, bb, cc, X[ 3], 14);
188 II(cc, dd, ee, aa, bb, X[ 7], 5);
189 II(bb, cc, dd, ee, aa, X[15], 6);
190 II(aa, bb, cc, dd, ee, X[14], 8);
191 II(ee, aa, bb, cc, dd, X[ 5], 6);
192 II(dd, ee, aa, bb, cc, X[ 6], 5);
193 II(cc, dd, ee, aa, bb, X[ 2], 12);
194
195 /* round 5 */
196 JJ(bb, cc, dd, ee, aa, X[ 4], 9);
197 JJ(aa, bb, cc, dd, ee, X[ 0], 15);
198 JJ(ee, aa, bb, cc, dd, X[ 5], 5);
199 JJ(dd, ee, aa, bb, cc, X[ 9], 11);
200 JJ(cc, dd, ee, aa, bb, X[ 7], 6);
201 JJ(bb, cc, dd, ee, aa, X[12], 8);
202 JJ(aa, bb, cc, dd, ee, X[ 2], 13);
203 JJ(ee, aa, bb, cc, dd, X[10], 12);
204 JJ(dd, ee, aa, bb, cc, X[14], 5);
205 JJ(cc, dd, ee, aa, bb, X[ 1], 12);
206 JJ(bb, cc, dd, ee, aa, X[ 3], 13);
207 JJ(aa, bb, cc, dd, ee, X[ 8], 14);
208 JJ(ee, aa, bb, cc, dd, X[11], 11);
209 JJ(dd, ee, aa, bb, cc, X[ 6], 8);
210 JJ(cc, dd, ee, aa, bb, X[15], 5);
211 JJ(bb, cc, dd, ee, aa, X[13], 6);
212
213 /* parallel round 1 */
214 JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
215 JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
216 JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
217 JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
218 JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
219 JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
220 JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
221 JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
222 JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
223 JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
224 JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
225 JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
226 JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
227 JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
228 JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
229 JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
230
231 /* parallel round 2 */
232 III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
233 III(ddd, eee, aaa, bbb, ccc, X[11], 13);
234 III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
235 III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
236 III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
237 III(eee, aaa, bbb, ccc, ddd, X[13], 8);
238 III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
239 III(ccc, ddd, eee, aaa, bbb, X[10], 11);
240 III(bbb, ccc, ddd, eee, aaa, X[14], 7);
241 III(aaa, bbb, ccc, ddd, eee, X[15], 7);
242 III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
243 III(ddd, eee, aaa, bbb, ccc, X[12], 7);
244 III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
245 III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
246 III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
247 III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
248
249 /* parallel round 3 */
250 HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
251 HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
252 HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
253 HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
254 HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
255 HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
256 HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
257 HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
258 HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
259 HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
260 HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
261 HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
262 HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
263 HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
264 HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
265 HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
266
267 /* parallel round 4 */
268 GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
269 GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
270 GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
271 GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
272 GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
273 GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
274 GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
275 GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
276 GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
277 GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
278 GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
279 GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
280 GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
281 GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
282 GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
283 GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
284
285 /* parallel round 5 */
286 FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
287 FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
288 FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
289 FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
290 FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
291 FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
292 FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
293 FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
294 FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
295 FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
296 FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
297 FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
298 FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
299 FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
300 FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
301 FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
302
303 /* combine results */
304 ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */
305 md->rmd160.state[1] = md->rmd160.state[2] + dd + eee;
306 md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa;
307 md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb;
308 md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc;
309 md->rmd160.state[0] = ddd;
310
311 return CRYPT_OK;
312 }
313
314 #ifdef LTC_CLEAN_STACK
315 static int rmd160_compress(hash_state *md, unsigned char *buf)
316 {
317 int err;
318 err = _rmd160_compress(md, buf);
319 burn_stack(sizeof(ulong32) * 26 + sizeof(int));
320 return err;
321 }
322 #endif
323
324 /**
325 Initialize the hash state
326 @param md The hash state you wish to initialize
327 @return CRYPT_OK if successful
328 */
329 int rmd160_init(hash_state * md)
330 {
331 LTC_ARGCHK(md != NULL);
332 md->rmd160.state[0] = 0x67452301UL;
333 md->rmd160.state[1] = 0xefcdab89UL;
334 md->rmd160.state[2] = 0x98badcfeUL;
335 md->rmd160.state[3] = 0x10325476UL;
336 md->rmd160.state[4] = 0xc3d2e1f0UL;
337 md->rmd160.curlen = 0;
338 md->rmd160.length = 0;
339 return CRYPT_OK;
340 }
341
342 /**
343 Process a block of memory though the hash
344 @param md The hash state
345 @param in The data to hash
346 @param inlen The length of the data (octets)
347 @return CRYPT_OK if successful
348 */
349 HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64)
350
351 /**
352 Terminate the hash to get the digest
353 @param md The hash state
354 @param out [out] The destination of the hash (20 bytes)
355 @return CRYPT_OK if successful
356 */
357 int rmd160_done(hash_state * md, unsigned char *out)
358 {
359 int i;
360
361 LTC_ARGCHK(md != NULL);
362 LTC_ARGCHK(out != NULL);
363
364 if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) {
365 return CRYPT_INVALID_ARG;
366 }
367
368
369 /* increase the length of the message */
370 md->rmd160.length += md->rmd160.curlen * 8;
371
372 /* append the '1' bit */
373 md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80;
374
375 /* if the length is currently above 56 bytes we append zeros
376 * then compress. Then we can fall back to padding zeros and length
377 * encoding like normal.
378 */
379 if (md->rmd160.curlen > 56) {
380 while (md->rmd160.curlen < 64) {
381 md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
382 }
383 rmd160_compress(md, md->rmd160.buf);
384 md->rmd160.curlen = 0;
385 }
386
387 /* pad upto 56 bytes of zeroes */
388 while (md->rmd160.curlen < 56) {
389 md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
390 }
391
392 /* store length */
393 STORE64L(md->rmd160.length, md->rmd160.buf+56);
394 rmd160_compress(md, md->rmd160.buf);
395
396 /* copy output */
397 for (i = 0; i < 5; i++) {
398 STORE32L(md->rmd160.state[i], out+(4*i));
399 }
400 #ifdef LTC_CLEAN_STACK
401 zeromem(md, sizeof(hash_state));
402 #endif
403 return CRYPT_OK;
404 }
405
406 /**
407 Self-test the hash
408 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
409 */
410 int rmd160_test(void)
411 {
412 #ifndef LTC_TEST
413 return CRYPT_NOP;
414 #else
415 static const struct {
416 char *msg;
417 unsigned char md[20];
418 } tests[] = {
419 { "",
420 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
421 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }
422 },
423 { "a",
424 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
425 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }
426 },
427 { "abc",
428 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
429 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }
430 },
431 { "message digest",
432 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
433 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }
434 },
435 { "abcdefghijklmnopqrstuvwxyz",
436 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
437 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }
438 },
439 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
440 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
441 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }
442 }
443 };
444 int x;
445 unsigned char buf[20];
446 hash_state md;
447
448 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
449 rmd160_init(&md);
450 rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
451 rmd160_done(&md, buf);
452 if (XMEMCMP(buf, tests[x].md, 20) != 0) {
453 #if 0
454 printf("Failed test %d\n", x);
455 #endif
456 return CRYPT_FAIL_TESTVECTOR;
457 }
458 }
459 return CRYPT_OK;
460 #endif
461 }
462
463 #endif
464
465
466 /* $Source$ */
467 /* $Revision$ */
468 /* $Date$ */
+0
-431
libtom-src/hashes/rmd256.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param rmd256.c
14 RLTC_MD256 Hash function
15 */
16
17 #ifdef LTC_RIPEMD256
18
19 const struct ltc_hash_descriptor rmd256_desc =
20 {
21 "rmd256",
22 8,
23 32,
24 64,
25
26 /* OID */
27 { 1, 3, 36, 3, 2, 3 },
28 6,
29
30 &rmd256_init,
31 &rmd256_process,
32 &rmd256_done,
33 &rmd256_test,
34 NULL
35 };
36
37 /* the four basic functions F(), G() and H() */
38 #define F(x, y, z) ((x) ^ (y) ^ (z))
39 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
40 #define H(x, y, z) (((x) | ~(y)) ^ (z))
41 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
42
43 /* the eight basic operations FF() through III() */
44 #define FF(a, b, c, d, x, s) \
45 (a) += F((b), (c), (d)) + (x);\
46 (a) = ROLc((a), (s));
47
48 #define GG(a, b, c, d, x, s) \
49 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
50 (a) = ROLc((a), (s));
51
52 #define HH(a, b, c, d, x, s) \
53 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
54 (a) = ROLc((a), (s));
55
56 #define II(a, b, c, d, x, s) \
57 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
58 (a) = ROLc((a), (s));
59
60 #define FFF(a, b, c, d, x, s) \
61 (a) += F((b), (c), (d)) + (x);\
62 (a) = ROLc((a), (s));
63
64 #define GGG(a, b, c, d, x, s) \
65 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
66 (a) = ROLc((a), (s));
67
68 #define HHH(a, b, c, d, x, s) \
69 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
70 (a) = ROLc((a), (s));
71
72 #define III(a, b, c, d, x, s) \
73 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
74 (a) = ROLc((a), (s));
75
76 #ifdef LTC_CLEAN_STACK
77 static int _rmd256_compress(hash_state *md, unsigned char *buf)
78 #else
79 static int rmd256_compress(hash_state *md, unsigned char *buf)
80 #endif
81 {
82 ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16];
83 int i;
84
85 /* load words X */
86 for (i = 0; i < 16; i++){
87 LOAD32L(X[i], buf + (4 * i));
88 }
89
90 /* load state */
91 aa = md->rmd256.state[0];
92 bb = md->rmd256.state[1];
93 cc = md->rmd256.state[2];
94 dd = md->rmd256.state[3];
95 aaa = md->rmd256.state[4];
96 bbb = md->rmd256.state[5];
97 ccc = md->rmd256.state[6];
98 ddd = md->rmd256.state[7];
99
100 /* round 1 */
101 FF(aa, bb, cc, dd, X[ 0], 11);
102 FF(dd, aa, bb, cc, X[ 1], 14);
103 FF(cc, dd, aa, bb, X[ 2], 15);
104 FF(bb, cc, dd, aa, X[ 3], 12);
105 FF(aa, bb, cc, dd, X[ 4], 5);
106 FF(dd, aa, bb, cc, X[ 5], 8);
107 FF(cc, dd, aa, bb, X[ 6], 7);
108 FF(bb, cc, dd, aa, X[ 7], 9);
109 FF(aa, bb, cc, dd, X[ 8], 11);
110 FF(dd, aa, bb, cc, X[ 9], 13);
111 FF(cc, dd, aa, bb, X[10], 14);
112 FF(bb, cc, dd, aa, X[11], 15);
113 FF(aa, bb, cc, dd, X[12], 6);
114 FF(dd, aa, bb, cc, X[13], 7);
115 FF(cc, dd, aa, bb, X[14], 9);
116 FF(bb, cc, dd, aa, X[15], 8);
117
118 /* parallel round 1 */
119 III(aaa, bbb, ccc, ddd, X[ 5], 8);
120 III(ddd, aaa, bbb, ccc, X[14], 9);
121 III(ccc, ddd, aaa, bbb, X[ 7], 9);
122 III(bbb, ccc, ddd, aaa, X[ 0], 11);
123 III(aaa, bbb, ccc, ddd, X[ 9], 13);
124 III(ddd, aaa, bbb, ccc, X[ 2], 15);
125 III(ccc, ddd, aaa, bbb, X[11], 15);
126 III(bbb, ccc, ddd, aaa, X[ 4], 5);
127 III(aaa, bbb, ccc, ddd, X[13], 7);
128 III(ddd, aaa, bbb, ccc, X[ 6], 7);
129 III(ccc, ddd, aaa, bbb, X[15], 8);
130 III(bbb, ccc, ddd, aaa, X[ 8], 11);
131 III(aaa, bbb, ccc, ddd, X[ 1], 14);
132 III(ddd, aaa, bbb, ccc, X[10], 14);
133 III(ccc, ddd, aaa, bbb, X[ 3], 12);
134 III(bbb, ccc, ddd, aaa, X[12], 6);
135
136 tmp = aa; aa = aaa; aaa = tmp;
137
138 /* round 2 */
139 GG(aa, bb, cc, dd, X[ 7], 7);
140 GG(dd, aa, bb, cc, X[ 4], 6);
141 GG(cc, dd, aa, bb, X[13], 8);
142 GG(bb, cc, dd, aa, X[ 1], 13);
143 GG(aa, bb, cc, dd, X[10], 11);
144 GG(dd, aa, bb, cc, X[ 6], 9);
145 GG(cc, dd, aa, bb, X[15], 7);
146 GG(bb, cc, dd, aa, X[ 3], 15);
147 GG(aa, bb, cc, dd, X[12], 7);
148 GG(dd, aa, bb, cc, X[ 0], 12);
149 GG(cc, dd, aa, bb, X[ 9], 15);
150 GG(bb, cc, dd, aa, X[ 5], 9);
151 GG(aa, bb, cc, dd, X[ 2], 11);
152 GG(dd, aa, bb, cc, X[14], 7);
153 GG(cc, dd, aa, bb, X[11], 13);
154 GG(bb, cc, dd, aa, X[ 8], 12);
155
156 /* parallel round 2 */
157 HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
158 HHH(ddd, aaa, bbb, ccc, X[11], 13);
159 HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
160 HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
161 HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
162 HHH(ddd, aaa, bbb, ccc, X[13], 8);
163 HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
164 HHH(bbb, ccc, ddd, aaa, X[10], 11);
165 HHH(aaa, bbb, ccc, ddd, X[14], 7);
166 HHH(ddd, aaa, bbb, ccc, X[15], 7);
167 HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
168 HHH(bbb, ccc, ddd, aaa, X[12], 7);
169 HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
170 HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
171 HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
172 HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
173
174 tmp = bb; bb = bbb; bbb = tmp;
175
176 /* round 3 */
177 HH(aa, bb, cc, dd, X[ 3], 11);
178 HH(dd, aa, bb, cc, X[10], 13);
179 HH(cc, dd, aa, bb, X[14], 6);
180 HH(bb, cc, dd, aa, X[ 4], 7);
181 HH(aa, bb, cc, dd, X[ 9], 14);
182 HH(dd, aa, bb, cc, X[15], 9);
183 HH(cc, dd, aa, bb, X[ 8], 13);
184 HH(bb, cc, dd, aa, X[ 1], 15);
185 HH(aa, bb, cc, dd, X[ 2], 14);
186 HH(dd, aa, bb, cc, X[ 7], 8);
187 HH(cc, dd, aa, bb, X[ 0], 13);
188 HH(bb, cc, dd, aa, X[ 6], 6);
189 HH(aa, bb, cc, dd, X[13], 5);
190 HH(dd, aa, bb, cc, X[11], 12);
191 HH(cc, dd, aa, bb, X[ 5], 7);
192 HH(bb, cc, dd, aa, X[12], 5);
193
194 /* parallel round 3 */
195 GGG(aaa, bbb, ccc, ddd, X[15], 9);
196 GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
197 GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
198 GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
199 GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
200 GGG(ddd, aaa, bbb, ccc, X[14], 6);
201 GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
202 GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
203 GGG(aaa, bbb, ccc, ddd, X[11], 12);
204 GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
205 GGG(ccc, ddd, aaa, bbb, X[12], 5);
206 GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
207 GGG(aaa, bbb, ccc, ddd, X[10], 13);
208 GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
209 GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
210 GGG(bbb, ccc, ddd, aaa, X[13], 5);
211
212 tmp = cc; cc = ccc; ccc = tmp;
213
214 /* round 4 */
215 II(aa, bb, cc, dd, X[ 1], 11);
216 II(dd, aa, bb, cc, X[ 9], 12);
217 II(cc, dd, aa, bb, X[11], 14);
218 II(bb, cc, dd, aa, X[10], 15);
219 II(aa, bb, cc, dd, X[ 0], 14);
220 II(dd, aa, bb, cc, X[ 8], 15);
221 II(cc, dd, aa, bb, X[12], 9);
222 II(bb, cc, dd, aa, X[ 4], 8);
223 II(aa, bb, cc, dd, X[13], 9);
224 II(dd, aa, bb, cc, X[ 3], 14);
225 II(cc, dd, aa, bb, X[ 7], 5);
226 II(bb, cc, dd, aa, X[15], 6);
227 II(aa, bb, cc, dd, X[14], 8);
228 II(dd, aa, bb, cc, X[ 5], 6);
229 II(cc, dd, aa, bb, X[ 6], 5);
230 II(bb, cc, dd, aa, X[ 2], 12);
231
232 /* parallel round 4 */
233 FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
234 FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
235 FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
236 FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
237 FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
238 FFF(ddd, aaa, bbb, ccc, X[11], 14);
239 FFF(ccc, ddd, aaa, bbb, X[15], 6);
240 FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
241 FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
242 FFF(ddd, aaa, bbb, ccc, X[12], 9);
243 FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
244 FFF(bbb, ccc, ddd, aaa, X[13], 9);
245 FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
246 FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
247 FFF(ccc, ddd, aaa, bbb, X[10], 15);
248 FFF(bbb, ccc, ddd, aaa, X[14], 8);
249
250 tmp = dd; dd = ddd; ddd = tmp;
251
252 /* combine results */
253 md->rmd256.state[0] += aa;
254 md->rmd256.state[1] += bb;
255 md->rmd256.state[2] += cc;
256 md->rmd256.state[3] += dd;
257 md->rmd256.state[4] += aaa;
258 md->rmd256.state[5] += bbb;
259 md->rmd256.state[6] += ccc;
260 md->rmd256.state[7] += ddd;
261
262 return CRYPT_OK;
263 }
264
265 #ifdef LTC_CLEAN_STACK
266 static int rmd256_compress(hash_state *md, unsigned char *buf)
267 {
268 int err;
269 err = _rmd256_compress(md, buf);
270 burn_stack(sizeof(ulong32) * 25 + sizeof(int));
271 return err;
272 }
273 #endif
274
275 /**
276 Initialize the hash state
277 @param md The hash state you wish to initialize
278 @return CRYPT_OK if successful
279 */
280 int rmd256_init(hash_state * md)
281 {
282 LTC_ARGCHK(md != NULL);
283 md->rmd256.state[0] = 0x67452301UL;
284 md->rmd256.state[1] = 0xefcdab89UL;
285 md->rmd256.state[2] = 0x98badcfeUL;
286 md->rmd256.state[3] = 0x10325476UL;
287 md->rmd256.state[4] = 0x76543210UL;
288 md->rmd256.state[5] = 0xfedcba98UL;
289 md->rmd256.state[6] = 0x89abcdefUL;
290 md->rmd256.state[7] = 0x01234567UL;
291 md->rmd256.curlen = 0;
292 md->rmd256.length = 0;
293 return CRYPT_OK;
294 }
295
296 /**
297 Process a block of memory though the hash
298 @param md The hash state
299 @param in The data to hash
300 @param inlen The length of the data (octets)
301 @return CRYPT_OK if successful
302 */
303 HASH_PROCESS(rmd256_process, rmd256_compress, rmd256, 64)
304
305 /**
306 Terminate the hash to get the digest
307 @param md The hash state
308 @param out [out] The destination of the hash (16 bytes)
309 @return CRYPT_OK if successful
310 */
311 int rmd256_done(hash_state * md, unsigned char *out)
312 {
313 int i;
314
315 LTC_ARGCHK(md != NULL);
316 LTC_ARGCHK(out != NULL);
317
318 if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) {
319 return CRYPT_INVALID_ARG;
320 }
321
322
323 /* increase the length of the message */
324 md->rmd256.length += md->rmd256.curlen * 8;
325
326 /* append the '1' bit */
327 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80;
328
329 /* if the length is currently above 56 bytes we append zeros
330 * then compress. Then we can fall back to padding zeros and length
331 * encoding like normal.
332 */
333 if (md->rmd256.curlen > 56) {
334 while (md->rmd256.curlen < 64) {
335 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
336 }
337 rmd256_compress(md, md->rmd256.buf);
338 md->rmd256.curlen = 0;
339 }
340
341 /* pad upto 56 bytes of zeroes */
342 while (md->rmd256.curlen < 56) {
343 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
344 }
345
346 /* store length */
347 STORE64L(md->rmd256.length, md->rmd256.buf+56);
348 rmd256_compress(md, md->rmd256.buf);
349
350 /* copy output */
351 for (i = 0; i < 8; i++) {
352 STORE32L(md->rmd256.state[i], out+(4*i));
353 }
354 #ifdef LTC_CLEAN_STACK
355 zeromem(md, sizeof(hash_state));
356 #endif
357 return CRYPT_OK;
358 }
359
360 /**
361 Self-test the hash
362 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
363 */
364 int rmd256_test(void)
365 {
366 #ifndef LTC_TEST
367 return CRYPT_NOP;
368 #else
369 static const struct {
370 char *msg;
371 unsigned char md[32];
372 } tests[] = {
373 { "",
374 { 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18,
375 0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a,
376 0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63,
377 0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d }
378 },
379 { "a",
380 { 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9,
381 0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c,
382 0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf,
383 0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 }
384 },
385 { "abc",
386 { 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb,
387 0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1,
388 0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e,
389 0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 }
390 },
391 { "message digest",
392 { 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a,
393 0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90,
394 0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55,
395 0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e }
396 },
397 { "abcdefghijklmnopqrstuvwxyz",
398 { 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16,
399 0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc,
400 0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87,
401 0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 }
402 },
403 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
404 { 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20,
405 0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f,
406 0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1,
407 0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 }
408 }
409 };
410 int x;
411 unsigned char buf[32];
412 hash_state md;
413
414 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
415 rmd256_init(&md);
416 rmd256_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
417 rmd256_done(&md, buf);
418 if (XMEMCMP(buf, tests[x].md, 32) != 0) {
419 #if 0
420 printf("Failed test %d\n", x);
421 #endif
422 return CRYPT_FAIL_TESTVECTOR;
423 }
424 }
425 return CRYPT_OK;
426 #endif
427 }
428
429 #endif
430
+0
-495
libtom-src/hashes/rmd320.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rmd320.c
14 RMD320 hash function
15 */
16
17 #ifdef LTC_RIPEMD320
18
19 const struct ltc_hash_descriptor rmd320_desc =
20 {
21 "rmd320",
22 9,
23 40,
24 64,
25
26 /* OID */
27 { 0 },
28 0,
29
30 &rmd320_init,
31 &rmd320_process,
32 &rmd320_done,
33 &rmd320_test,
34 NULL
35 };
36
37 /* the five basic functions F(), G() and H() */
38 #define F(x, y, z) ((x) ^ (y) ^ (z))
39 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
40 #define H(x, y, z) (((x) | ~(y)) ^ (z))
41 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
42 #define J(x, y, z) ((x) ^ ((y) | ~(z)))
43
44 /* the ten basic operations FF() through III() */
45 #define FF(a, b, c, d, e, x, s) \
46 (a) += F((b), (c), (d)) + (x);\
47 (a) = ROLc((a), (s)) + (e);\
48 (c) = ROLc((c), 10);
49
50 #define GG(a, b, c, d, e, x, s) \
51 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
52 (a) = ROLc((a), (s)) + (e);\
53 (c) = ROLc((c), 10);
54
55 #define HH(a, b, c, d, e, x, s) \
56 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
57 (a) = ROLc((a), (s)) + (e);\
58 (c) = ROLc((c), 10);
59
60 #define II(a, b, c, d, e, x, s) \
61 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
62 (a) = ROLc((a), (s)) + (e);\
63 (c) = ROLc((c), 10);
64
65 #define JJ(a, b, c, d, e, x, s) \
66 (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
67 (a) = ROLc((a), (s)) + (e);\
68 (c) = ROLc((c), 10);
69
70 #define FFF(a, b, c, d, e, x, s) \
71 (a) += F((b), (c), (d)) + (x);\
72 (a) = ROLc((a), (s)) + (e);\
73 (c) = ROLc((c), 10);
74
75 #define GGG(a, b, c, d, e, x, s) \
76 (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
77 (a) = ROLc((a), (s)) + (e);\
78 (c) = ROLc((c), 10);
79
80 #define HHH(a, b, c, d, e, x, s) \
81 (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
82 (a) = ROLc((a), (s)) + (e);\
83 (c) = ROLc((c), 10);
84
85 #define III(a, b, c, d, e, x, s) \
86 (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
87 (a) = ROLc((a), (s)) + (e);\
88 (c) = ROLc((c), 10);
89
90 #define JJJ(a, b, c, d, e, x, s) \
91 (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
92 (a) = ROLc((a), (s)) + (e);\
93 (c) = ROLc((c), 10);
94
95
96 #ifdef LTC_CLEAN_STACK
97 static int _rmd320_compress(hash_state *md, unsigned char *buf)
98 #else
99 static int rmd320_compress(hash_state *md, unsigned char *buf)
100 #endif
101 {
102 ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16];
103 int i;
104
105 /* load words X */
106 for (i = 0; i < 16; i++){
107 LOAD32L(X[i], buf + (4 * i));
108 }
109
110 /* load state */
111 aa = md->rmd320.state[0];
112 bb = md->rmd320.state[1];
113 cc = md->rmd320.state[2];
114 dd = md->rmd320.state[3];
115 ee = md->rmd320.state[4];
116 aaa = md->rmd320.state[5];
117 bbb = md->rmd320.state[6];
118 ccc = md->rmd320.state[7];
119 ddd = md->rmd320.state[8];
120 eee = md->rmd320.state[9];
121
122 /* round 1 */
123 FF(aa, bb, cc, dd, ee, X[ 0], 11);
124 FF(ee, aa, bb, cc, dd, X[ 1], 14);
125 FF(dd, ee, aa, bb, cc, X[ 2], 15);
126 FF(cc, dd, ee, aa, bb, X[ 3], 12);
127 FF(bb, cc, dd, ee, aa, X[ 4], 5);
128 FF(aa, bb, cc, dd, ee, X[ 5], 8);
129 FF(ee, aa, bb, cc, dd, X[ 6], 7);
130 FF(dd, ee, aa, bb, cc, X[ 7], 9);
131 FF(cc, dd, ee, aa, bb, X[ 8], 11);
132 FF(bb, cc, dd, ee, aa, X[ 9], 13);
133 FF(aa, bb, cc, dd, ee, X[10], 14);
134 FF(ee, aa, bb, cc, dd, X[11], 15);
135 FF(dd, ee, aa, bb, cc, X[12], 6);
136 FF(cc, dd, ee, aa, bb, X[13], 7);
137 FF(bb, cc, dd, ee, aa, X[14], 9);
138 FF(aa, bb, cc, dd, ee, X[15], 8);
139
140 /* parallel round 1 */
141 JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
142 JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
143 JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
144 JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
145 JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
146 JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
147 JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
148 JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
149 JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
150 JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
151 JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
152 JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
153 JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
154 JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
155 JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
156 JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
157
158 tmp = aa; aa = aaa; aaa = tmp;
159
160 /* round 2 */
161 GG(ee, aa, bb, cc, dd, X[ 7], 7);
162 GG(dd, ee, aa, bb, cc, X[ 4], 6);
163 GG(cc, dd, ee, aa, bb, X[13], 8);
164 GG(bb, cc, dd, ee, aa, X[ 1], 13);
165 GG(aa, bb, cc, dd, ee, X[10], 11);
166 GG(ee, aa, bb, cc, dd, X[ 6], 9);
167 GG(dd, ee, aa, bb, cc, X[15], 7);
168 GG(cc, dd, ee, aa, bb, X[ 3], 15);
169 GG(bb, cc, dd, ee, aa, X[12], 7);
170 GG(aa, bb, cc, dd, ee, X[ 0], 12);
171 GG(ee, aa, bb, cc, dd, X[ 9], 15);
172 GG(dd, ee, aa, bb, cc, X[ 5], 9);
173 GG(cc, dd, ee, aa, bb, X[ 2], 11);
174 GG(bb, cc, dd, ee, aa, X[14], 7);
175 GG(aa, bb, cc, dd, ee, X[11], 13);
176 GG(ee, aa, bb, cc, dd, X[ 8], 12);
177
178 /* parallel round 2 */
179 III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
180 III(ddd, eee, aaa, bbb, ccc, X[11], 13);
181 III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
182 III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
183 III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
184 III(eee, aaa, bbb, ccc, ddd, X[13], 8);
185 III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
186 III(ccc, ddd, eee, aaa, bbb, X[10], 11);
187 III(bbb, ccc, ddd, eee, aaa, X[14], 7);
188 III(aaa, bbb, ccc, ddd, eee, X[15], 7);
189 III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
190 III(ddd, eee, aaa, bbb, ccc, X[12], 7);
191 III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
192 III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
193 III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
194 III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
195
196 tmp = bb; bb = bbb; bbb = tmp;
197
198 /* round 3 */
199 HH(dd, ee, aa, bb, cc, X[ 3], 11);
200 HH(cc, dd, ee, aa, bb, X[10], 13);
201 HH(bb, cc, dd, ee, aa, X[14], 6);
202 HH(aa, bb, cc, dd, ee, X[ 4], 7);
203 HH(ee, aa, bb, cc, dd, X[ 9], 14);
204 HH(dd, ee, aa, bb, cc, X[15], 9);
205 HH(cc, dd, ee, aa, bb, X[ 8], 13);
206 HH(bb, cc, dd, ee, aa, X[ 1], 15);
207 HH(aa, bb, cc, dd, ee, X[ 2], 14);
208 HH(ee, aa, bb, cc, dd, X[ 7], 8);
209 HH(dd, ee, aa, bb, cc, X[ 0], 13);
210 HH(cc, dd, ee, aa, bb, X[ 6], 6);
211 HH(bb, cc, dd, ee, aa, X[13], 5);
212 HH(aa, bb, cc, dd, ee, X[11], 12);
213 HH(ee, aa, bb, cc, dd, X[ 5], 7);
214 HH(dd, ee, aa, bb, cc, X[12], 5);
215
216 /* parallel round 3 */
217 HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
218 HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
219 HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
220 HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
221 HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
222 HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
223 HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
224 HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
225 HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
226 HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
227 HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
228 HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
229 HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
230 HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
231 HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
232 HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
233
234 tmp = cc; cc = ccc; ccc = tmp;
235
236 /* round 4 */
237 II(cc, dd, ee, aa, bb, X[ 1], 11);
238 II(bb, cc, dd, ee, aa, X[ 9], 12);
239 II(aa, bb, cc, dd, ee, X[11], 14);
240 II(ee, aa, bb, cc, dd, X[10], 15);
241 II(dd, ee, aa, bb, cc, X[ 0], 14);
242 II(cc, dd, ee, aa, bb, X[ 8], 15);
243 II(bb, cc, dd, ee, aa, X[12], 9);
244 II(aa, bb, cc, dd, ee, X[ 4], 8);
245 II(ee, aa, bb, cc, dd, X[13], 9);
246 II(dd, ee, aa, bb, cc, X[ 3], 14);
247 II(cc, dd, ee, aa, bb, X[ 7], 5);
248 II(bb, cc, dd, ee, aa, X[15], 6);
249 II(aa, bb, cc, dd, ee, X[14], 8);
250 II(ee, aa, bb, cc, dd, X[ 5], 6);
251 II(dd, ee, aa, bb, cc, X[ 6], 5);
252 II(cc, dd, ee, aa, bb, X[ 2], 12);
253
254 /* parallel round 4 */
255 GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
256 GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
257 GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
258 GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
259 GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
260 GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
261 GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
262 GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
263 GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
264 GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
265 GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
266 GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
267 GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
268 GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
269 GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
270 GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
271
272 tmp = dd; dd = ddd; ddd = tmp;
273
274 /* round 5 */
275 JJ(bb, cc, dd, ee, aa, X[ 4], 9);
276 JJ(aa, bb, cc, dd, ee, X[ 0], 15);
277 JJ(ee, aa, bb, cc, dd, X[ 5], 5);
278 JJ(dd, ee, aa, bb, cc, X[ 9], 11);
279 JJ(cc, dd, ee, aa, bb, X[ 7], 6);
280 JJ(bb, cc, dd, ee, aa, X[12], 8);
281 JJ(aa, bb, cc, dd, ee, X[ 2], 13);
282 JJ(ee, aa, bb, cc, dd, X[10], 12);
283 JJ(dd, ee, aa, bb, cc, X[14], 5);
284 JJ(cc, dd, ee, aa, bb, X[ 1], 12);
285 JJ(bb, cc, dd, ee, aa, X[ 3], 13);
286 JJ(aa, bb, cc, dd, ee, X[ 8], 14);
287 JJ(ee, aa, bb, cc, dd, X[11], 11);
288 JJ(dd, ee, aa, bb, cc, X[ 6], 8);
289 JJ(cc, dd, ee, aa, bb, X[15], 5);
290 JJ(bb, cc, dd, ee, aa, X[13], 6);
291
292 /* parallel round 5 */
293 FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
294 FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
295 FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
296 FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
297 FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
298 FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
299 FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
300 FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
301 FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
302 FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
303 FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
304 FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
305 FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
306 FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
307 FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
308 FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
309
310 tmp = ee; ee = eee; eee = tmp;
311
312 /* combine results */
313 md->rmd320.state[0] += aa;
314 md->rmd320.state[1] += bb;
315 md->rmd320.state[2] += cc;
316 md->rmd320.state[3] += dd;
317 md->rmd320.state[4] += ee;
318 md->rmd320.state[5] += aaa;
319 md->rmd320.state[6] += bbb;
320 md->rmd320.state[7] += ccc;
321 md->rmd320.state[8] += ddd;
322 md->rmd320.state[9] += eee;
323
324 return CRYPT_OK;
325 }
326
327 #ifdef LTC_CLEAN_STACK
328 static int rmd320_compress(hash_state *md, unsigned char *buf)
329 {
330 int err;
331 err = _rmd320_compress(md, buf);
332 burn_stack(sizeof(ulong32) * 27 + sizeof(int));
333 return err;
334 }
335 #endif
336
337 /**
338 Initialize the hash state
339 @param md The hash state you wish to initialize
340 @return CRYPT_OK if successful
341 */
342 int rmd320_init(hash_state * md)
343 {
344 LTC_ARGCHK(md != NULL);
345 md->rmd320.state[0] = 0x67452301UL;
346 md->rmd320.state[1] = 0xefcdab89UL;
347 md->rmd320.state[2] = 0x98badcfeUL;
348 md->rmd320.state[3] = 0x10325476UL;
349 md->rmd320.state[4] = 0xc3d2e1f0UL;
350 md->rmd320.state[5] = 0x76543210UL;
351 md->rmd320.state[6] = 0xfedcba98UL;
352 md->rmd320.state[7] = 0x89abcdefUL;
353 md->rmd320.state[8] = 0x01234567UL;
354 md->rmd320.state[9] = 0x3c2d1e0fUL;
355 md->rmd320.curlen = 0;
356 md->rmd320.length = 0;
357 return CRYPT_OK;
358 }
359
360 /**
361 Process a block of memory though the hash
362 @param md The hash state
363 @param in The data to hash
364 @param inlen The length of the data (octets)
365 @return CRYPT_OK if successful
366 */
367 HASH_PROCESS(rmd320_process, rmd320_compress, rmd320, 64)
368
369 /**
370 Terminate the hash to get the digest
371 @param md The hash state
372 @param out [out] The destination of the hash (20 bytes)
373 @return CRYPT_OK if successful
374 */
375 int rmd320_done(hash_state * md, unsigned char *out)
376 {
377 int i;
378
379 LTC_ARGCHK(md != NULL);
380 LTC_ARGCHK(out != NULL);
381
382 if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) {
383 return CRYPT_INVALID_ARG;
384 }
385
386
387 /* increase the length of the message */
388 md->rmd320.length += md->rmd320.curlen * 8;
389
390 /* append the '1' bit */
391 md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80;
392
393 /* if the length is currently above 56 bytes we append zeros
394 * then compress. Then we can fall back to padding zeros and length
395 * encoding like normal.
396 */
397 if (md->rmd320.curlen > 56) {
398 while (md->rmd320.curlen < 64) {
399 md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
400 }
401 rmd320_compress(md, md->rmd320.buf);
402 md->rmd320.curlen = 0;
403 }
404
405 /* pad upto 56 bytes of zeroes */
406 while (md->rmd320.curlen < 56) {
407 md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
408 }
409
410 /* store length */
411 STORE64L(md->rmd320.length, md->rmd320.buf+56);
412 rmd320_compress(md, md->rmd320.buf);
413
414 /* copy output */
415 for (i = 0; i < 10; i++) {
416 STORE32L(md->rmd320.state[i], out+(4*i));
417 }
418 #ifdef LTC_CLEAN_STACK
419 zeromem(md, sizeof(hash_state));
420 #endif
421 return CRYPT_OK;
422 }
423
424 /**
425 Self-test the hash
426 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
427 */
428 int rmd320_test(void)
429 {
430 #ifndef LTC_TEST
431 return CRYPT_NOP;
432 #else
433 static const struct {
434 char *msg;
435 unsigned char md[40];
436 } tests[] = {
437 { "",
438 { 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1,
439 0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25,
440 0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e,
441 0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 }
442 },
443 { "a",
444 { 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5,
445 0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57,
446 0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54,
447 0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d }
448 },
449 { "abc",
450 { 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d,
451 0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08,
452 0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74,
453 0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d }
454 },
455 { "message digest",
456 { 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68,
457 0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa,
458 0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d,
459 0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 }
460 },
461 { "abcdefghijklmnopqrstuvwxyz",
462 { 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93,
463 0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4,
464 0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed,
465 0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 }
466 },
467 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
468 { 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4,
469 0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59,
470 0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b,
471 0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac }
472 }
473 };
474 int x;
475 unsigned char buf[40];
476 hash_state md;
477
478 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
479 rmd320_init(&md);
480 rmd320_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
481 rmd320_done(&md, buf);
482 if (XMEMCMP(buf, tests[x].md, 40) != 0) {
483 #if 0
484 printf("Failed test %d\n", x);
485 #endif
486 return CRYPT_FAIL_TESTVECTOR;
487 }
488 }
489 return CRYPT_OK;
490 #endif
491 }
492
493 #endif
494
+0
-288
libtom-src/hashes/sha1.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file sha1.c
14 LTC_SHA1 code by Tom St Denis
15 */
16
17
18 #ifdef LTC_SHA1
19
20 const struct ltc_hash_descriptor sha1_desc =
21 {
22 "sha1",
23 2,
24 20,
25 64,
26
27 /* OID */
28 { 1, 3, 14, 3, 2, 26, },
29 6,
30
31 &sha1_init,
32 &sha1_process,
33 &sha1_done,
34 &sha1_test,
35 NULL
36 };
37
38 #define F0(x,y,z) (z ^ (x & (y ^ z)))
39 #define F1(x,y,z) (x ^ y ^ z)
40 #define F2(x,y,z) ((x & y) | (z & (x | y)))
41 #define F3(x,y,z) (x ^ y ^ z)
42
43 #ifdef LTC_CLEAN_STACK
44 static int _sha1_compress(hash_state *md, unsigned char *buf)
45 #else
46 static int sha1_compress(hash_state *md, unsigned char *buf)
47 #endif
48 {
49 ulong32 a,b,c,d,e,W[80],i;
50 #ifdef LTC_SMALL_CODE
51 ulong32 t;
52 #endif
53
54 /* copy the state into 512-bits into W[0..15] */
55 for (i = 0; i < 16; i++) {
56 LOAD32H(W[i], buf + (4*i));
57 }
58
59 /* copy state */
60 a = md->sha1.state[0];
61 b = md->sha1.state[1];
62 c = md->sha1.state[2];
63 d = md->sha1.state[3];
64 e = md->sha1.state[4];
65
66 /* expand it */
67 for (i = 16; i < 80; i++) {
68 W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
69 }
70
71 /* compress */
72 /* round one */
73 #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
74 #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
75 #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
76 #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
77
78 #ifdef LTC_SMALL_CODE
79
80 for (i = 0; i < 20; ) {
81 FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
82 }
83
84 for (; i < 40; ) {
85 FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
86 }
87
88 for (; i < 60; ) {
89 FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
90 }
91
92 for (; i < 80; ) {
93 FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
94 }
95
96 #else
97
98 for (i = 0; i < 20; ) {
99 FF0(a,b,c,d,e,i++);
100 FF0(e,a,b,c,d,i++);
101 FF0(d,e,a,b,c,i++);
102 FF0(c,d,e,a,b,i++);
103 FF0(b,c,d,e,a,i++);
104 }
105
106 /* round two */
107 for (; i < 40; ) {
108 FF1(a,b,c,d,e,i++);
109 FF1(e,a,b,c,d,i++);
110 FF1(d,e,a,b,c,i++);
111 FF1(c,d,e,a,b,i++);
112 FF1(b,c,d,e,a,i++);
113 }
114
115 /* round three */
116 for (; i < 60; ) {
117 FF2(a,b,c,d,e,i++);
118 FF2(e,a,b,c,d,i++);
119 FF2(d,e,a,b,c,i++);
120 FF2(c,d,e,a,b,i++);
121 FF2(b,c,d,e,a,i++);
122 }
123
124 /* round four */
125 for (; i < 80; ) {
126 FF3(a,b,c,d,e,i++);
127 FF3(e,a,b,c,d,i++);
128 FF3(d,e,a,b,c,i++);
129 FF3(c,d,e,a,b,i++);
130 FF3(b,c,d,e,a,i++);
131 }
132 #endif
133
134 #undef FF0
135 #undef FF1
136 #undef FF2
137 #undef FF3
138
139 /* store */
140 md->sha1.state[0] = md->sha1.state[0] + a;
141 md->sha1.state[1] = md->sha1.state[1] + b;
142 md->sha1.state[2] = md->sha1.state[2] + c;
143 md->sha1.state[3] = md->sha1.state[3] + d;
144 md->sha1.state[4] = md->sha1.state[4] + e;
145
146 return CRYPT_OK;
147 }
148
149 #ifdef LTC_CLEAN_STACK
150 static int sha1_compress(hash_state *md, unsigned char *buf)
151 {
152 int err;
153 err = _sha1_compress(md, buf);
154 burn_stack(sizeof(ulong32) * 87);
155 return err;
156 }
157 #endif
158
159 /**
160 Initialize the hash state
161 @param md The hash state you wish to initialize
162 @return CRYPT_OK if successful
163 */
164 int sha1_init(hash_state * md)
165 {
166 LTC_ARGCHK(md != NULL);
167 md->sha1.state[0] = 0x67452301UL;
168 md->sha1.state[1] = 0xefcdab89UL;
169 md->sha1.state[2] = 0x98badcfeUL;
170 md->sha1.state[3] = 0x10325476UL;
171 md->sha1.state[4] = 0xc3d2e1f0UL;
172 md->sha1.curlen = 0;
173 md->sha1.length = 0;
174 return CRYPT_OK;
175 }
176
177 /**
178 Process a block of memory though the hash
179 @param md The hash state
180 @param in The data to hash
181 @param inlen The length of the data (octets)
182 @return CRYPT_OK if successful
183 */
184 HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
185
186 /**
187 Terminate the hash to get the digest
188 @param md The hash state
189 @param out [out] The destination of the hash (20 bytes)
190 @return CRYPT_OK if successful
191 */
192 int sha1_done(hash_state * md, unsigned char *out)
193 {
194 int i;
195
196 LTC_ARGCHK(md != NULL);
197 LTC_ARGCHK(out != NULL);
198
199 if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
200 return CRYPT_INVALID_ARG;
201 }
202
203 /* increase the length of the message */
204 md->sha1.length += md->sha1.curlen * 8;
205
206 /* append the '1' bit */
207 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
208
209 /* if the length is currently above 56 bytes we append zeros
210 * then compress. Then we can fall back to padding zeros and length
211 * encoding like normal.
212 */
213 if (md->sha1.curlen > 56) {
214 while (md->sha1.curlen < 64) {
215 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
216 }
217 sha1_compress(md, md->sha1.buf);
218 md->sha1.curlen = 0;
219 }
220
221 /* pad upto 56 bytes of zeroes */
222 while (md->sha1.curlen < 56) {
223 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
224 }
225
226 /* store length */
227 STORE64H(md->sha1.length, md->sha1.buf+56);
228 sha1_compress(md, md->sha1.buf);
229
230 /* copy output */
231 for (i = 0; i < 5; i++) {
232 STORE32H(md->sha1.state[i], out+(4*i));
233 }
234 #ifdef LTC_CLEAN_STACK
235 zeromem(md, sizeof(hash_state));
236 #endif
237 return CRYPT_OK;
238 }
239
240 /**
241 Self-test the hash
242 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
243 */
244 int sha1_test(void)
245 {
246 #ifndef LTC_TEST
247 return CRYPT_NOP;
248 #else
249 static const struct {
250 char *msg;
251 unsigned char hash[20];
252 } tests[] = {
253 { "abc",
254 { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
255 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
256 0x9c, 0xd0, 0xd8, 0x9d }
257 },
258 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
259 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
260 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
261 0xE5, 0x46, 0x70, 0xF1 }
262 }
263 };
264
265 int i;
266 unsigned char tmp[20];
267 hash_state md;
268
269 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
270 sha1_init(&md);
271 sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
272 sha1_done(&md, tmp);
273 if (XMEMCMP(tmp, tests[i].hash, 20) != 0) {
274 return CRYPT_FAIL_TESTVECTOR;
275 }
276 }
277 return CRYPT_OK;
278 #endif
279 }
280
281 #endif
282
283
284
285 /* $Source$ */
286 /* $Revision$ */
287 /* $Date$ */
+0
-125
libtom-src/hashes/sha2/sha224.c.inc less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @param sha224.c
12 LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis)
13 */
14
15 const struct ltc_hash_descriptor sha224_desc =
16 {
17 "sha224",
18 10,
19 28,
20 64,
21
22 /* OID */
23 { 2, 16, 840, 1, 101, 3, 4, 2, 4, },
24 9,
25
26 &sha224_init,
27 &sha256_process,
28 &sha224_done,
29 &sha224_test,
30 NULL
31 };
32
33 /* init the sha256 er... sha224 state ;-) */
34 /**
35 Initialize the hash state
36 @param md The hash state you wish to initialize
37 @return CRYPT_OK if successful
38 */
39 int sha224_init(hash_state * md)
40 {
41 LTC_ARGCHK(md != NULL);
42
43 md->sha256.curlen = 0;
44 md->sha256.length = 0;
45 md->sha256.state[0] = 0xc1059ed8UL;
46 md->sha256.state[1] = 0x367cd507UL;
47 md->sha256.state[2] = 0x3070dd17UL;
48 md->sha256.state[3] = 0xf70e5939UL;
49 md->sha256.state[4] = 0xffc00b31UL;
50 md->sha256.state[5] = 0x68581511UL;
51 md->sha256.state[6] = 0x64f98fa7UL;
52 md->sha256.state[7] = 0xbefa4fa4UL;
53 return CRYPT_OK;
54 }
55
56 /**
57 Terminate the hash to get the digest
58 @param md The hash state
59 @param out [out] The destination of the hash (28 bytes)
60 @return CRYPT_OK if successful
61 */
62 int sha224_done(hash_state * md, unsigned char *out)
63 {
64 unsigned char buf[32];
65 int err;
66
67 LTC_ARGCHK(md != NULL);
68 LTC_ARGCHK(out != NULL);
69
70 err = sha256_done(md, buf);
71 XMEMCPY(out, buf, 28);
72 #ifdef LTC_CLEAN_STACK
73 zeromem(buf, sizeof(buf));
74 #endif
75 return err;
76 }
77
78 /**
79 Self-test the hash
80 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
81 */
82 int sha224_test(void)
83 {
84 #ifndef LTC_TEST
85 return CRYPT_NOP;
86 #else
87 static const struct {
88 char *msg;
89 unsigned char hash[28];
90 } tests[] = {
91 { "abc",
92 { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8,
93 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2,
94 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd,
95 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 }
96 },
97 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
98 { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
99 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
100 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
101 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
102 },
103 };
104
105 int i;
106 unsigned char tmp[28];
107 hash_state md;
108
109 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
110 sha224_init(&md);
111 sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
112 sha224_done(&md, tmp);
113 if (XMEMCMP(tmp, tests[i].hash, 28) != 0) {
114 return CRYPT_FAIL_TESTVECTOR;
115 }
116 }
117 return CRYPT_OK;
118 #endif
119 }
120
121
122 /* $Source$ */
123 /* $Revision$ */
124 /* $Date$ */
+0
-340
libtom-src/hashes/sha2/sha256.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file sha256.c
14 LTC_SHA256 by Tom St Denis
15 */
16
17 #ifdef LTC_SHA256
18
19 const struct ltc_hash_descriptor sha256_desc =
20 {
21 "sha256",
22 0,
23 32,
24 64,
25
26 /* OID */
27 { 2, 16, 840, 1, 101, 3, 4, 2, 1, },
28 9,
29
30 &sha256_init,
31 &sha256_process,
32 &sha256_done,
33 &sha256_test,
34 NULL
35 };
36
37 #ifdef LTC_SMALL_CODE
38 /* the K array */
39 static const ulong32 K[64] = {
40 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
41 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
42 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
43 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
44 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
45 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
46 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
47 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
48 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
49 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
50 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
51 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
52 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
53 };
54 #endif
55
56 /* Various logical functions */
57 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
58 #define Maj(x,y,z) (((x | y) & z) | (x & y))
59 #define S(x, n) RORc((x),(n))
60 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
61 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
62 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
63 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
64 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
65
66 /* compress 512-bits */
67 #ifdef LTC_CLEAN_STACK
68 static int _sha256_compress(hash_state * md, unsigned char *buf)
69 #else
70 static int sha256_compress(hash_state * md, unsigned char *buf)
71 #endif
72 {
73 ulong32 S[8], W[64], t0, t1;
74 #ifdef LTC_SMALL_CODE
75 ulong32 t;
76 #endif
77 int i;
78
79 /* copy state into S */
80 for (i = 0; i < 8; i++) {
81 S[i] = md->sha256.state[i];
82 }
83
84 /* copy the state into 512-bits into W[0..15] */
85 for (i = 0; i < 16; i++) {
86 LOAD32H(W[i], buf + (4*i));
87 }
88
89 /* fill W[16..63] */
90 for (i = 16; i < 64; i++) {
91 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
92 }
93
94 /* Compress */
95 #ifdef LTC_SMALL_CODE
96 #define RND(a,b,c,d,e,f,g,h,i) \
97 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
98 t1 = Sigma0(a) + Maj(a, b, c); \
99 d += t0; \
100 h = t0 + t1;
101
102 for (i = 0; i < 64; ++i) {
103 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
104 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
105 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
106 }
107 #else
108 #define RND(a,b,c,d,e,f,g,h,i,ki) \
109 t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
110 t1 = Sigma0(a) + Maj(a, b, c); \
111 d += t0; \
112 h = t0 + t1;
113
114 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
115 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
116 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
117 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
118 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
119 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
120 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
121 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
122 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
123 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
124 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
125 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
126 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
127 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
128 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
129 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
130 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
131 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
132 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
133 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
134 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
135 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
136 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
137 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
138 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
139 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
140 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
141 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
142 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
143 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
144 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
145 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
146 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
147 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
148 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
149 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
150 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
151 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
152 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
153 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
154 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
155 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
156 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
157 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
158 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
159 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
160 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
161 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
162 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
163 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
164 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
165 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
166 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
167 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
168 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
169 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
170 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
171 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
172 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
173 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
174 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
175 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
176 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
177 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
178
179 #undef RND
180
181 #endif
182
183 /* feedback */
184 for (i = 0; i < 8; i++) {
185 md->sha256.state[i] = md->sha256.state[i] + S[i];
186 }
187 return CRYPT_OK;
188 }
189
190 #ifdef LTC_CLEAN_STACK
191 static int sha256_compress(hash_state * md, unsigned char *buf)
192 {
193 int err;
194 err = _sha256_compress(md, buf);
195 burn_stack(sizeof(ulong32) * 74);
196 return err;
197 }
198 #endif
199
200 /**
201 Initialize the hash state
202 @param md The hash state you wish to initialize
203 @return CRYPT_OK if successful
204 */
205 int sha256_init(hash_state * md)
206 {
207 LTC_ARGCHK(md != NULL);
208
209 md->sha256.curlen = 0;
210 md->sha256.length = 0;
211 md->sha256.state[0] = 0x6A09E667UL;
212 md->sha256.state[1] = 0xBB67AE85UL;
213 md->sha256.state[2] = 0x3C6EF372UL;
214 md->sha256.state[3] = 0xA54FF53AUL;
215 md->sha256.state[4] = 0x510E527FUL;
216 md->sha256.state[5] = 0x9B05688CUL;
217 md->sha256.state[6] = 0x1F83D9ABUL;
218 md->sha256.state[7] = 0x5BE0CD19UL;
219 return CRYPT_OK;
220 }
221
222 /**
223 Process a block of memory though the hash
224 @param md The hash state
225 @param in The data to hash
226 @param inlen The length of the data (octets)
227 @return CRYPT_OK if successful
228 */
229 HASH_PROCESS(sha256_process, sha256_compress, sha256, 64)
230
231 /**
232 Terminate the hash to get the digest
233 @param md The hash state
234 @param out [out] The destination of the hash (32 bytes)
235 @return CRYPT_OK if successful
236 */
237 int sha256_done(hash_state * md, unsigned char *out)
238 {
239 int i;
240
241 LTC_ARGCHK(md != NULL);
242 LTC_ARGCHK(out != NULL);
243
244 if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
245 return CRYPT_INVALID_ARG;
246 }
247
248
249 /* increase the length of the message */
250 md->sha256.length += md->sha256.curlen * 8;
251
252 /* append the '1' bit */
253 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
254
255 /* if the length is currently above 56 bytes we append zeros
256 * then compress. Then we can fall back to padding zeros and length
257 * encoding like normal.
258 */
259 if (md->sha256.curlen > 56) {
260 while (md->sha256.curlen < 64) {
261 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
262 }
263 sha256_compress(md, md->sha256.buf);
264 md->sha256.curlen = 0;
265 }
266
267 /* pad upto 56 bytes of zeroes */
268 while (md->sha256.curlen < 56) {
269 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
270 }
271
272 /* store length */
273 STORE64H(md->sha256.length, md->sha256.buf+56);
274 sha256_compress(md, md->sha256.buf);
275
276 /* copy output */
277 for (i = 0; i < 8; i++) {
278 STORE32H(md->sha256.state[i], out+(4*i));
279 }
280 #ifdef LTC_CLEAN_STACK
281 zeromem(md, sizeof(hash_state));
282 #endif
283 return CRYPT_OK;
284 }
285
286 /**
287 Self-test the hash
288 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
289 */
290 int sha256_test(void)
291 {
292 #ifndef LTC_TEST
293 return CRYPT_NOP;
294 #else
295 static const struct {
296 char *msg;
297 unsigned char hash[32];
298 } tests[] = {
299 { "abc",
300 { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
301 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
302 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
303 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
304 },
305 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
306 { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
307 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
308 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
309 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
310 },
311 };
312
313 int i;
314 unsigned char tmp[32];
315 hash_state md;
316
317 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
318 sha256_init(&md);
319 sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
320 sha256_done(&md, tmp);
321 if (XMEMCMP(tmp, tests[i].hash, 32) != 0) {
322 return CRYPT_FAIL_TESTVECTOR;
323 }
324 }
325 return CRYPT_OK;
326 #endif
327 }
328
329 #ifdef LTC_SHA224
330 #include "sha224.c.inc"
331 #endif
332
333 #endif
334
335
336
337 /* $Source$ */
338 /* $Revision$ */
339 /* $Date$ */
+0
-135
libtom-src/hashes/sha2/sha384.c.inc less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @param sha384.c
12 LTC_SHA384 hash included in sha512.c, Tom St Denis
13 */
14
15 const struct ltc_hash_descriptor sha384_desc =
16 {
17 "sha384",
18 4,
19 48,
20 128,
21
22 /* OID */
23 { 2, 16, 840, 1, 101, 3, 4, 2, 2, },
24 9,
25
26 &sha384_init,
27 &sha512_process,
28 &sha384_done,
29 &sha384_test,
30 NULL
31 };
32
33 /**
34 Initialize the hash state
35 @param md The hash state you wish to initialize
36 @return CRYPT_OK if successful
37 */
38 int sha384_init(hash_state * md)
39 {
40 LTC_ARGCHK(md != NULL);
41
42 md->sha512.curlen = 0;
43 md->sha512.length = 0;
44 md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8);
45 md->sha512.state[1] = CONST64(0x629a292a367cd507);
46 md->sha512.state[2] = CONST64(0x9159015a3070dd17);
47 md->sha512.state[3] = CONST64(0x152fecd8f70e5939);
48 md->sha512.state[4] = CONST64(0x67332667ffc00b31);
49 md->sha512.state[5] = CONST64(0x8eb44a8768581511);
50 md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7);
51 md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4);
52 return CRYPT_OK;
53 }
54
55 /**
56 Terminate the hash to get the digest
57 @param md The hash state
58 @param out [out] The destination of the hash (48 bytes)
59 @return CRYPT_OK if successful
60 */
61 int sha384_done(hash_state * md, unsigned char *out)
62 {
63 unsigned char buf[64];
64
65 LTC_ARGCHK(md != NULL);
66 LTC_ARGCHK(out != NULL);
67
68 if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
69 return CRYPT_INVALID_ARG;
70 }
71
72 sha512_done(md, buf);
73 XMEMCPY(out, buf, 48);
74 #ifdef LTC_CLEAN_STACK
75 zeromem(buf, sizeof(buf));
76 #endif
77 return CRYPT_OK;
78 }
79
80 /**
81 Self-test the hash
82 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
83 */
84 int sha384_test(void)
85 {
86 #ifndef LTC_TEST
87 return CRYPT_NOP;
88 #else
89 static const struct {
90 char *msg;
91 unsigned char hash[48];
92 } tests[] = {
93 { "abc",
94 { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
95 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
96 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
97 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
98 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
99 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
100 },
101 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
102 { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
103 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
104 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
105 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
106 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
107 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }
108 },
109 };
110
111 int i;
112 unsigned char tmp[48];
113 hash_state md;
114
115 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
116 sha384_init(&md);
117 sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
118 sha384_done(&md, tmp);
119 if (XMEMCMP(tmp, tests[i].hash, 48) != 0) {
120 return CRYPT_FAIL_TESTVECTOR;
121 }
122 }
123 return CRYPT_OK;
124 #endif
125 }
126
127
128
129
130
131
132 /* $Source$ */
133 /* $Revision$ */
134 /* $Date$ */
+0
-319
libtom-src/hashes/sha2/sha512.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param sha512.c
14 LTC_SHA512 by Tom St Denis
15 */
16
17 #ifdef LTC_SHA512
18
19 const struct ltc_hash_descriptor sha512_desc =
20 {
21 "sha512",
22 5,
23 64,
24 128,
25
26 /* OID */
27 { 2, 16, 840, 1, 101, 3, 4, 2, 3, },
28 9,
29
30 &sha512_init,
31 &sha512_process,
32 &sha512_done,
33 &sha512_test,
34 NULL
35 };
36
37 /* the K array */
38 static const ulong64 K[80] = {
39 CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
40 CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
41 CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
42 CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
43 CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
44 CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
45 CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
46 CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
47 CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
48 CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
49 CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
50 CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
51 CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
52 CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
53 CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
54 CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
55 CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
56 CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
57 CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
58 CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
59 CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
60 CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
61 CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
62 CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
63 CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
64 CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
65 CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
66 CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
67 CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
68 CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
69 CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
70 CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
71 CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
72 CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
73 CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
74 CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
75 CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
76 CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
77 CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
78 CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
79 };
80
81 /* Various logical functions */
82 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
83 #define Maj(x,y,z) (((x | y) & z) | (x & y))
84 #define S(x, n) ROR64c(x, n)
85 #define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
86 #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
87 #define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
88 #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
89 #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
90
91 /* compress 1024-bits */
92 #ifdef LTC_CLEAN_STACK
93 static int _sha512_compress(hash_state * md, unsigned char *buf)
94 #else
95 static int sha512_compress(hash_state * md, unsigned char *buf)
96 #endif
97 {
98 ulong64 S[8], W[80], t0, t1;
99 int i;
100
101 /* copy state into S */
102 for (i = 0; i < 8; i++) {
103 S[i] = md->sha512.state[i];
104 }
105
106 /* copy the state into 1024-bits into W[0..15] */
107 for (i = 0; i < 16; i++) {
108 LOAD64H(W[i], buf + (8*i));
109 }
110
111 /* fill W[16..79] */
112 for (i = 16; i < 80; i++) {
113 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
114 }
115
116 /* Compress */
117 #ifdef LTC_SMALL_CODE
118 for (i = 0; i < 80; i++) {
119 t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
120 t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
121 S[7] = S[6];
122 S[6] = S[5];
123 S[5] = S[4];
124 S[4] = S[3] + t0;
125 S[3] = S[2];
126 S[2] = S[1];
127 S[1] = S[0];
128 S[0] = t0 + t1;
129 }
130 #else
131 #define RND(a,b,c,d,e,f,g,h,i) \
132 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
133 t1 = Sigma0(a) + Maj(a, b, c); \
134 d += t0; \
135 h = t0 + t1;
136
137 for (i = 0; i < 80; i += 8) {
138 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
139 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
140 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
141 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
142 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
143 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
144 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
145 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
146 }
147 #endif
148
149
150 /* feedback */
151 for (i = 0; i < 8; i++) {
152 md->sha512.state[i] = md->sha512.state[i] + S[i];
153 }
154
155 return CRYPT_OK;
156 }
157
158 /* compress 1024-bits */
159 #ifdef LTC_CLEAN_STACK
160 static int sha512_compress(hash_state * md, unsigned char *buf)
161 {
162 int err;
163 err = _sha512_compress(md, buf);
164 burn_stack(sizeof(ulong64) * 90 + sizeof(int));
165 return err;
166 }
167 #endif
168
169 /**
170 Initialize the hash state
171 @param md The hash state you wish to initialize
172 @return CRYPT_OK if successful
173 */
174 int sha512_init(hash_state * md)
175 {
176 LTC_ARGCHK(md != NULL);
177 md->sha512.curlen = 0;
178 md->sha512.length = 0;
179 md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
180 md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
181 md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
182 md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
183 md->sha512.state[4] = CONST64(0x510e527fade682d1);
184 md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
185 md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
186 md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
187 return CRYPT_OK;
188 }
189
190 /**
191 Process a block of memory though the hash
192 @param md The hash state
193 @param in The data to hash
194 @param inlen The length of the data (octets)
195 @return CRYPT_OK if successful
196 */
197 HASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
198
199 /**
200 Terminate the hash to get the digest
201 @param md The hash state
202 @param out [out] The destination of the hash (64 bytes)
203 @return CRYPT_OK if successful
204 */
205 int sha512_done(hash_state * md, unsigned char *out)
206 {
207 int i;
208
209 LTC_ARGCHK(md != NULL);
210 LTC_ARGCHK(out != NULL);
211
212 if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
213 return CRYPT_INVALID_ARG;
214 }
215
216 /* increase the length of the message */
217 md->sha512.length += md->sha512.curlen * CONST64(8);
218
219 /* append the '1' bit */
220 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
221
222 /* if the length is currently above 112 bytes we append zeros
223 * then compress. Then we can fall back to padding zeros and length
224 * encoding like normal.
225 */
226 if (md->sha512.curlen > 112) {
227 while (md->sha512.curlen < 128) {
228 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
229 }
230 sha512_compress(md, md->sha512.buf);
231 md->sha512.curlen = 0;
232 }
233
234 /* pad upto 120 bytes of zeroes
235 * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
236 * > 2^64 bits of data... :-)
237 */
238 while (md->sha512.curlen < 120) {
239 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
240 }
241
242 /* store length */
243 STORE64H(md->sha512.length, md->sha512.buf+120);
244 sha512_compress(md, md->sha512.buf);
245
246 /* copy output */
247 for (i = 0; i < 8; i++) {
248 STORE64H(md->sha512.state[i], out+(8*i));
249 }
250 #ifdef LTC_CLEAN_STACK
251 zeromem(md, sizeof(hash_state));
252 #endif
253 return CRYPT_OK;
254 }
255
256 /**
257 Self-test the hash
258 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
259 */
260 int sha512_test(void)
261 {
262 #ifndef LTC_TEST
263 return CRYPT_NOP;
264 #else
265 static const struct {
266 char *msg;
267 unsigned char hash[64];
268 } tests[] = {
269 { "abc",
270 { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
271 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
272 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
273 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
274 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
275 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
276 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
277 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
278 },
279 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
280 { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
281 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
282 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
283 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
284 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
285 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
286 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
287 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
288 },
289 };
290
291 int i;
292 unsigned char tmp[64];
293 hash_state md;
294
295 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
296 sha512_init(&md);
297 sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
298 sha512_done(&md, tmp);
299 if (XMEMCMP(tmp, tests[i].hash, 64) != 0) {
300 return CRYPT_FAIL_TESTVECTOR;
301 }
302 }
303 return CRYPT_OK;
304 #endif
305 }
306
307 #ifdef LTC_SHA384
308 #include "sha384.c.inc"
309 #endif
310
311 #endif
312
313
314
315
316 /* $Source$ */
317 /* $Revision$ */
318 /* $Date$ */
+0
-814
libtom-src/hashes/tiger.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #include "tomcrypt.h"
12
13 /**
14 @file tiger.c
15 Tiger hash function, Tom St Denis
16 */
17
18 #ifdef LTC_TIGER
19
20 const struct ltc_hash_descriptor tiger_desc =
21 {
22 "tiger",
23 1,
24 24,
25 64,
26
27 /* OID */
28 { 1, 3, 6, 1, 4, 1, 11591, 12, 2, },
29 9,
30
31 &tiger_init,
32 &tiger_process,
33 &tiger_done,
34 &tiger_test,
35 NULL
36 };
37
38 #define t1 (table)
39 #define t2 (table+256)
40 #define t3 (table+256*2)
41 #define t4 (table+256*3)
42
43 static const ulong64 table[4*256] = {
44 CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */,
45 CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */,
46 CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */,
47 CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */,
48 CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */,
49 CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */,
50 CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */,
51 CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */,
52 CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */,
53 CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */,
54 CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */,
55 CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */,
56 CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */,
57 CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */,
58 CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */,
59 CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */,
60 CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */,
61 CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */,
62 CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */,
63 CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */,
64 CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */,
65 CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */,
66 CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */,
67 CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */,
68 CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */,
69 CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */,
70 CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */,
71 CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */,
72 CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */,
73 CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */,
74 CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */,
75 CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */,
76 CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */,
77 CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */,
78 CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */,
79 CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */,
80 CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */,
81 CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */,
82 CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */,
83 CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */,
84 CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */,
85 CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */,
86 CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */,
87 CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */,
88 CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */,
89 CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */,
90 CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */,
91 CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */,
92 CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */,
93 CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */,
94 CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */,
95 CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */,
96 CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */,
97 CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */,
98 CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */,
99 CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */,
100 CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */,
101 CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */,
102 CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */,
103 CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */,
104 CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */,
105 CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */,
106 CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */,
107 CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */,
108 CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */,
109 CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */,
110 CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */,
111 CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */,
112 CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */,
113 CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */,
114 CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */,
115 CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */,
116 CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */,
117 CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */,
118 CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */,
119 CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */,
120 CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */,
121 CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */,
122 CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */,
123 CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */,
124 CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */,
125 CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */,
126 CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */,
127 CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */,
128 CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */,
129 CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */,
130 CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */,
131 CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */,
132 CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */,
133 CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */,
134 CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */,
135 CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */,
136 CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */,
137 CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */,
138 CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */,
139 CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */,
140 CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */,
141 CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */,
142 CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */,
143 CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */,
144 CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */,
145 CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */,
146 CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */,
147 CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */,
148 CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */,
149 CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */,
150 CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */,
151 CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */,
152 CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */,
153 CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */,
154 CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */,
155 CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */,
156 CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */,
157 CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */,
158 CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */,
159 CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */,
160 CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */,
161 CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */,
162 CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */,
163 CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */,
164 CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */,
165 CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */,
166 CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */,
167 CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */,
168 CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */,
169 CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */,
170 CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */,
171 CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */,
172 CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */,
173 CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */,
174 CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */,
175 CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */,
176 CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */,
177 CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */,
178 CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */,
179 CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */,
180 CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */,
181 CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */,
182 CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */,
183 CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */,
184 CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */,
185 CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */,
186 CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */,
187 CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */,
188 CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */,
189 CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */,
190 CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */,
191 CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */,
192 CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */,
193 CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */,
194 CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */,
195 CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */,
196 CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */,
197 CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */,
198 CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */,
199 CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */,
200 CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */,
201 CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */,
202 CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */,
203 CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */,
204 CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */,
205 CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */,
206 CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */,
207 CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */,
208 CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */,
209 CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */,
210 CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */,
211 CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */,
212 CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */,
213 CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */,
214 CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */,
215 CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */,
216 CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */,
217 CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */,
218 CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */,
219 CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */,
220 CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */,
221 CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */,
222 CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */,
223 CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */,
224 CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */,
225 CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */,
226 CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */,
227 CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */,
228 CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */,
229 CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */,
230 CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */,
231 CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */,
232 CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */,
233 CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */,
234 CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */,
235 CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */,
236 CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */,
237 CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */,
238 CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */,
239 CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */,
240 CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */,
241 CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */,
242 CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */,
243 CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */,
244 CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */,
245 CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */,
246 CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */,
247 CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */,
248 CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */,
249 CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */,
250 CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */,
251 CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */,
252 CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */,
253 CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */,
254 CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */,
255 CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */,
256 CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */,
257 CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */,
258 CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */,
259 CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */,
260 CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */,
261 CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */,
262 CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */,
263 CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */,
264 CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */,
265 CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */,
266 CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */,
267 CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */,
268 CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */,
269 CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */,
270 CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */,
271 CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */,
272 CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */,
273 CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */,
274 CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */,
275 CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */,
276 CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */,
277 CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */,
278 CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */,
279 CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */,
280 CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */,
281 CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */,
282 CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */,
283 CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */,
284 CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */,
285 CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */,
286 CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */,
287 CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */,
288 CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */,
289 CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */,
290 CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */,
291 CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */,
292 CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */,
293 CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */,
294 CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */,
295 CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */,
296 CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */,
297 CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */,
298 CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */,
299 CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */,
300 CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */,
301 CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */,
302 CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */,
303 CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */,
304 CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */,
305 CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */,
306 CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */,
307 CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */,
308 CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */,
309 CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */,
310 CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */,
311 CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */,
312 CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */,
313 CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */,
314 CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */,
315 CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */,
316 CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */,
317 CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */,
318 CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */,
319 CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */,
320 CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */,
321 CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */,
322 CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */,
323 CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */,
324 CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */,
325 CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */,
326 CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */,
327 CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */,
328 CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */,
329 CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */,
330 CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */,
331 CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */,
332 CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */,
333 CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */,
334 CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */,
335 CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */,
336 CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */,
337 CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */,
338 CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */,
339 CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */,
340 CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */,
341 CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */,
342 CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */,
343 CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */,
344 CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */,
345 CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */,
346 CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */,
347 CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */,
348 CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */,
349 CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */,
350 CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */,
351 CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */,
352 CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */,
353 CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */,
354 CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */,
355 CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */,
356 CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */,
357 CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */,
358 CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */,
359 CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */,
360 CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */,
361 CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */,
362 CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */,
363 CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */,
364 CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */,
365 CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */,
366 CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */,
367 CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */,
368 CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */,
369 CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */,
370 CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */,
371 CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */,
372 CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */,
373 CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */,
374 CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */,
375 CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */,
376 CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */,
377 CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */,
378 CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */,
379 CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */,
380 CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */,
381 CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */,
382 CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */,
383 CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */,
384 CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */,
385 CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */,
386 CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */,
387 CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */,
388 CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */,
389 CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */,
390 CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */,
391 CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */,
392 CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */,
393 CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */,
394 CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */,
395 CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */,
396 CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */,
397 CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */,
398 CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */,
399 CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */,
400 CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */,
401 CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */,
402 CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */,
403 CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */,
404 CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */,
405 CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */,
406 CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */,
407 CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */,
408 CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */,
409 CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */,
410 CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */,
411 CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */,
412 CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */,
413 CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */,
414 CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */,
415 CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */,
416 CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */,
417 CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */,
418 CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */,
419 CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */,
420 CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */,
421 CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */,
422 CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */,
423 CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */,
424 CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */,
425 CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */,
426 CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */,
427 CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */,
428 CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */,
429 CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */,
430 CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */,
431 CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */,
432 CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */,
433 CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */,
434 CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */,
435 CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */,
436 CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */,
437 CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */,
438 CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */,
439 CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */,
440 CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */,
441 CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */,
442 CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */,
443 CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */,
444 CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */,
445 CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */,
446 CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */,
447 CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */,
448 CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */,
449 CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */,
450 CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */,
451 CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */,
452 CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */,
453 CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */,
454 CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */,
455 CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */,
456 CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */,
457 CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */,
458 CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */,
459 CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */,
460 CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */,
461 CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */,
462 CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */,
463 CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */,
464 CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */,
465 CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */,
466 CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */,
467 CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */,
468 CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */,
469 CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */,
470 CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */,
471 CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */,
472 CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */,
473 CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */,
474 CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */,
475 CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */,
476 CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */,
477 CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */,
478 CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */,
479 CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */,
480 CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */,
481 CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */,
482 CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */,
483 CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */,
484 CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */,
485 CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */,
486 CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */,
487 CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */,
488 CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */,
489 CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */,
490 CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */,
491 CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */,
492 CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */,
493 CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */,
494 CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */,
495 CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */,
496 CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */,
497 CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */,
498 CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */,
499 CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */,
500 CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */,
501 CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */,
502 CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */,
503 CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */,
504 CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */,
505 CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */,
506 CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */,
507 CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */,
508 CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */,
509 CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */,
510 CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */,
511 CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */,
512 CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */,
513 CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */,
514 CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */,
515 CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */,
516 CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */,
517 CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */,
518 CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */,
519 CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */,
520 CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */,
521 CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */,
522 CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */,
523 CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */,
524 CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */,
525 CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */,
526 CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */,
527 CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */,
528 CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */,
529 CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */,
530 CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */,
531 CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */,
532 CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */,
533 CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */,
534 CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */,
535 CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */,
536 CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */,
537 CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */,
538 CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */,
539 CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */,
540 CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */,
541 CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */,
542 CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */,
543 CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */,
544 CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */,
545 CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */,
546 CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */,
547 CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */,
548 CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */,
549 CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */,
550 CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */,
551 CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */,
552 CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */,
553 CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */,
554 CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */,
555 CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */};
556
557 #ifdef _MSC_VER
558 #define INLINE __inline
559 #else
560 #define INLINE
561 #endif
562
563 /* one round of the hash function */
564 INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul)
565 {
566 ulong64 tmp;
567 tmp = (*c ^= x);
568 *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)];
569 tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]);
570 switch (mul) {
571 case 5: *b = (tmp << 2) + tmp; break;
572 case 7: *b = (tmp << 3) - tmp; break;
573 case 9: *b = (tmp << 3) + tmp; break;
574 }
575 }
576
577 /* one complete pass */
578 static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul)
579 {
580 tiger_round(a,b,c,x[0],mul);
581 tiger_round(b,c,a,x[1],mul);
582 tiger_round(c,a,b,x[2],mul);
583 tiger_round(a,b,c,x[3],mul);
584 tiger_round(b,c,a,x[4],mul);
585 tiger_round(c,a,b,x[5],mul);
586 tiger_round(a,b,c,x[6],mul);
587 tiger_round(b,c,a,x[7],mul);
588 }
589
590 /* The key mixing schedule */
591 static void key_schedule(ulong64 *x)
592 {
593 x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5);
594 x[1] ^= x[0];
595 x[2] += x[1];
596 x[3] -= x[2] ^ ((~x[1])<<19);
597 x[4] ^= x[3];
598 x[5] += x[4];
599 x[6] -= x[5] ^ ((~x[4])>>23);
600 x[7] ^= x[6];
601 x[0] += x[7];
602 x[1] -= x[0] ^ ((~x[7])<<19);
603 x[2] ^= x[1];
604 x[3] += x[2];
605 x[4] -= x[3] ^ ((~x[2])>>23);
606 x[5] ^= x[4];
607 x[6] += x[5];
608 x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF);
609 }
610
611 #ifdef LTC_CLEAN_STACK
612 static int _tiger_compress(hash_state *md, unsigned char *buf)
613 #else
614 static int tiger_compress(hash_state *md, unsigned char *buf)
615 #endif
616 {
617 ulong64 a, b, c, x[8];
618 unsigned long i;
619
620 /* load words */
621 for (i = 0; i < 8; i++) {
622 LOAD64L(x[i],&buf[8*i]);
623 }
624 a = md->tiger.state[0];
625 b = md->tiger.state[1];
626 c = md->tiger.state[2];
627
628 pass(&a,&b,&c,x,5);
629 key_schedule(x);
630 pass(&c,&a,&b,x,7);
631 key_schedule(x);
632 pass(&b,&c,&a,x,9);
633
634 /* store state */
635 md->tiger.state[0] = a ^ md->tiger.state[0];
636 md->tiger.state[1] = b - md->tiger.state[1];
637 md->tiger.state[2] = c + md->tiger.state[2];
638
639 return CRYPT_OK;
640 }
641
642 #ifdef LTC_CLEAN_STACK
643 static int tiger_compress(hash_state *md, unsigned char *buf)
644 {
645 int err;
646 err = _tiger_compress(md, buf);
647 burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long));
648 return err;
649 }
650 #endif
651
652 /**
653 Initialize the hash state
654 @param md The hash state you wish to initialize
655 @return CRYPT_OK if successful
656 */
657 int tiger_init(hash_state *md)
658 {
659 LTC_ARGCHK(md != NULL);
660 md->tiger.state[0] = CONST64(0x0123456789ABCDEF);
661 md->tiger.state[1] = CONST64(0xFEDCBA9876543210);
662 md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187);
663 md->tiger.curlen = 0;
664 md->tiger.length = 0;
665 return CRYPT_OK;
666 }
667
668 /**
669 Process a block of memory though the hash
670 @param md The hash state
671 @param in The data to hash
672 @param inlen The length of the data (octets)
673 @return CRYPT_OK if successful
674 */
675 HASH_PROCESS(tiger_process, tiger_compress, tiger, 64)
676
677 /**
678 Terminate the hash to get the digest
679 @param md The hash state
680 @param out [out] The destination of the hash (24 bytes)
681 @return CRYPT_OK if successful
682 */
683 int tiger_done(hash_state * md, unsigned char *out)
684 {
685 LTC_ARGCHK(md != NULL);
686 LTC_ARGCHK(out != NULL);
687
688 if (md->tiger.curlen >= sizeof(md->tiger.buf)) {
689 return CRYPT_INVALID_ARG;
690 }
691
692 /* increase the length of the message */
693 md->tiger.length += md->tiger.curlen * 8;
694
695 /* append the '1' bit */
696 md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01;
697
698 /* if the length is currently above 56 bytes we append zeros
699 * then compress. Then we can fall back to padding zeros and length
700 * encoding like normal. */
701 if (md->tiger.curlen > 56) {
702 while (md->tiger.curlen < 64) {
703 md->tiger.buf[md->tiger.curlen++] = (unsigned char)0;
704 }
705 tiger_compress(md, md->tiger.buf);
706 md->tiger.curlen = 0;
707 }
708
709 /* pad upto 56 bytes of zeroes */
710 while (md->tiger.curlen < 56) {
711 md->tiger.buf[md->tiger.curlen++] = (unsigned char)0;
712 }
713
714 /* store length */
715 STORE64L(md->tiger.length, md->tiger.buf+56);
716 tiger_compress(md, md->tiger.buf);
717
718 /* copy output */
719 STORE64L(md->tiger.state[0], &out[0]);
720 STORE64L(md->tiger.state[1], &out[8]);
721 STORE64L(md->tiger.state[2], &out[16]);
722 #ifdef LTC_CLEAN_STACK
723 zeromem(md, sizeof(hash_state));
724 #endif
725
726 return CRYPT_OK;
727 }
728
729 /**
730 Self-test the hash
731 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
732 */
733 int tiger_test(void)
734 {
735 #ifndef LTC_TEST
736 return CRYPT_NOP;
737 #else
738 static const struct {
739 char *msg;
740 unsigned char hash[24];
741 } tests[] = {
742 { "",
743 { 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24,
744 0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16,
745 0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 }
746 },
747 { "abc",
748 { 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2,
749 0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52,
750 0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 }
751 },
752 { "Tiger",
753 { 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f,
754 0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27,
755 0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 }
756 },
757 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
758 { 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87,
759 0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47,
760 0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 }
761 },
762 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
763 { 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00,
764 0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76,
765 0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 }
766 },
767 };
768
769 int i;
770 unsigned char tmp[24];
771 hash_state md;
772
773 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
774 tiger_init(&md);
775 tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
776 tiger_done(&md, tmp);
777 if (XMEMCMP(tmp, tests[i].hash, 24) != 0) {
778 return CRYPT_FAIL_TESTVECTOR;
779 }
780 }
781 return CRYPT_OK;
782 #endif
783 }
784
785 #endif
786
787 /*
788 Hash of "":
789 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
790 Hash of "abc":
791 F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
792 Hash of "Tiger":
793 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
794 Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
795 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
796 Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789":
797 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
798 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham":
799 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
800 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.":
801 EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
802 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.":
803 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
804 Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
805 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
806 */
807
808
809
810
811 /* $Source$ */
812 /* $Revision$ */
813 /* $Date$ */
+0
-314
libtom-src/hashes/whirl/whirl.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file whirl.c
13 LTC_WHIRLPOOL (using their new sbox) hash function by Tom St Denis
14 */
15
16 #include "tomcrypt.h"
17
18 #ifdef LTC_WHIRLPOOL
19
20 const struct ltc_hash_descriptor whirlpool_desc =
21 {
22 "whirlpool",
23 11,
24 64,
25 64,
26
27 /* OID */
28 { 1, 0, 10118, 3, 0, 55 },
29 6,
30
31 &whirlpool_init,
32 &whirlpool_process,
33 &whirlpool_done,
34 &whirlpool_test,
35 NULL
36 };
37
38 /* the sboxes */
39 #include "whirltab.c.inc"
40
41 /* get a_{i,j} */
42 #define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
43
44 /* shortcut macro to perform three functions at once */
45 #define theta_pi_gamma(a, i) \
46 SB0(GB(a, i-0, 7)) ^ \
47 SB1(GB(a, i-1, 6)) ^ \
48 SB2(GB(a, i-2, 5)) ^ \
49 SB3(GB(a, i-3, 4)) ^ \
50 SB4(GB(a, i-4, 3)) ^ \
51 SB5(GB(a, i-5, 2)) ^ \
52 SB6(GB(a, i-6, 1)) ^ \
53 SB7(GB(a, i-7, 0))
54
55 #ifdef LTC_CLEAN_STACK
56 static int _whirlpool_compress(hash_state *md, unsigned char *buf)
57 #else
58 static int whirlpool_compress(hash_state *md, unsigned char *buf)
59 #endif
60 {
61 ulong64 K[2][8], T[3][8];
62 int x, y;
63
64 /* load the block/state */
65 for (x = 0; x < 8; x++) {
66 K[0][x] = md->whirlpool.state[x];
67
68 LOAD64H(T[0][x], buf + (8 * x));
69 T[2][x] = T[0][x];
70 T[0][x] ^= K[0][x];
71 }
72
73 /* do rounds 1..10 */
74 for (x = 0; x < 10; x += 2) {
75 /* odd round */
76 /* apply main transform to K[0] into K[1] */
77 for (y = 0; y < 8; y++) {
78 K[1][y] = theta_pi_gamma(K[0], y);
79 }
80 /* xor the constant */
81 K[1][0] ^= cont[x];
82
83 /* apply main transform to T[0] into T[1] */
84 for (y = 0; y < 8; y++) {
85 T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y];
86 }
87
88 /* even round */
89 /* apply main transform to K[1] into K[0] */
90 for (y = 0; y < 8; y++) {
91 K[0][y] = theta_pi_gamma(K[1], y);
92 }
93 /* xor the constant */
94 K[0][0] ^= cont[x+1];
95
96 /* apply main transform to T[1] into T[0] */
97 for (y = 0; y < 8; y++) {
98 T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y];
99 }
100 }
101
102 /* store state */
103 for (x = 0; x < 8; x++) {
104 md->whirlpool.state[x] ^= T[0][x] ^ T[2][x];
105 }
106
107 return CRYPT_OK;
108 }
109
110
111 #ifdef LTC_CLEAN_STACK
112 static int whirlpool_compress(hash_state *md, unsigned char *buf)
113 {
114 int err;
115 err = _whirlpool_compress(md, buf);
116 burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int)));
117 return err;
118 }
119 #endif
120
121
122 /**
123 Initialize the hash state
124 @param md The hash state you wish to initialize
125 @return CRYPT_OK if successful
126 */
127 int whirlpool_init(hash_state * md)
128 {
129 LTC_ARGCHK(md != NULL);
130 zeromem(&md->whirlpool, sizeof(md->whirlpool));
131 return CRYPT_OK;
132 }
133
134 /**
135 Process a block of memory though the hash
136 @param md The hash state
137 @param in The data to hash
138 @param inlen The length of the data (octets)
139 @return CRYPT_OK if successful
140 */
141 HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64)
142
143 /**
144 Terminate the hash to get the digest
145 @param md The hash state
146 @param out [out] The destination of the hash (64 bytes)
147 @return CRYPT_OK if successful
148 */
149 int whirlpool_done(hash_state * md, unsigned char *out)
150 {
151 int i;
152
153 LTC_ARGCHK(md != NULL);
154 LTC_ARGCHK(out != NULL);
155
156 if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) {
157 return CRYPT_INVALID_ARG;
158 }
159
160 /* increase the length of the message */
161 md->whirlpool.length += md->whirlpool.curlen * 8;
162
163 /* append the '1' bit */
164 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80;
165
166 /* if the length is currently above 32 bytes we append zeros
167 * then compress. Then we can fall back to padding zeros and length
168 * encoding like normal.
169 */
170 if (md->whirlpool.curlen > 32) {
171 while (md->whirlpool.curlen < 64) {
172 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
173 }
174 whirlpool_compress(md, md->whirlpool.buf);
175 md->whirlpool.curlen = 0;
176 }
177
178 /* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths) */
179 while (md->whirlpool.curlen < 56) {
180 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
181 }
182
183 /* store length */
184 STORE64H(md->whirlpool.length, md->whirlpool.buf+56);
185 whirlpool_compress(md, md->whirlpool.buf);
186
187 /* copy output */
188 for (i = 0; i < 8; i++) {
189 STORE64H(md->whirlpool.state[i], out+(8*i));
190 }
191 #ifdef LTC_CLEAN_STACK
192 zeromem(md, sizeof(*md));
193 #endif
194 return CRYPT_OK;
195 }
196
197 /**
198 Self-test the hash
199 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
200 */
201 int whirlpool_test(void)
202 {
203 #ifndef LTC_TEST
204 return CRYPT_NOP;
205 #else
206 static const struct {
207 int len;
208 unsigned char msg[128], hash[64];
209 } tests[] = {
210
211 /* NULL Message */
212 {
213 0,
214 { 0x00 },
215 { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26,
216 0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7,
217 0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57,
218 0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 }
219 },
220
221
222 /* 448-bits of 0 bits */
223 {
224
225 56,
226 { 0x00 },
227 { 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03,
228 0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70,
229 0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61,
230 0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 }
231 },
232
233 /* 520-bits of 0 bits */
234 {
235 65,
236 { 0x00 },
237 { 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D,
238 0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4,
239 0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF,
240 0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 }
241 },
242
243 /* 512-bits, leading set */
244 {
245 64,
246 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
250 { 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A,
251 0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94,
252 0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6,
253 0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB }
254 },
255
256 /* 512-bits, leading set of second byte */
257 {
258 64,
259 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
263 { 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E,
264 0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F,
265 0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35,
266 0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 }
267 },
268
269 /* 512-bits, leading set of last byte */
270 {
271 64,
272 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
276 { 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6,
277 0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F,
278 0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B,
279 0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 }
280 },
281
282 };
283
284 int i;
285 unsigned char tmp[64];
286 hash_state md;
287
288 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
289 whirlpool_init(&md);
290 whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len);
291 whirlpool_done(&md, tmp);
292 if (XMEMCMP(tmp, tests[i].hash, 64) != 0) {
293 #if 0
294 printf("\nFailed test %d\n", i);
295 for (i = 0; i < 64; ) {
296 printf("%02x ", tmp[i]);
297 if (!(++i & 15)) printf("\n");
298 }
299 #endif
300 return CRYPT_FAIL_TESTVECTOR;
301 }
302 }
303 return CRYPT_OK;
304 #endif
305 }
306
307
308 #endif
309
310
311 /* $Source$ */
312 /* $Revision$ */
313 /* $Date$ */
+0
-583
libtom-src/hashes/whirl/whirltab.c.inc less more
0 /**
1 @file whirltab.c
2 LTC_WHIRLPOOL tables, Tom St Denis
3 */
4 static const ulong64 sbox0[] = {
5 CONST64(0x18186018c07830d8), CONST64(0x23238c2305af4626), CONST64(0xc6c63fc67ef991b8), CONST64(0xe8e887e8136fcdfb),
6 CONST64(0x878726874ca113cb), CONST64(0xb8b8dab8a9626d11), CONST64(0x0101040108050209), CONST64(0x4f4f214f426e9e0d),
7 CONST64(0x3636d836adee6c9b), CONST64(0xa6a6a2a6590451ff), CONST64(0xd2d26fd2debdb90c), CONST64(0xf5f5f3f5fb06f70e),
8 CONST64(0x7979f979ef80f296), CONST64(0x6f6fa16f5fcede30), CONST64(0x91917e91fcef3f6d), CONST64(0x52525552aa07a4f8),
9 CONST64(0x60609d6027fdc047), CONST64(0xbcbccabc89766535), CONST64(0x9b9b569baccd2b37), CONST64(0x8e8e028e048c018a),
10 CONST64(0xa3a3b6a371155bd2), CONST64(0x0c0c300c603c186c), CONST64(0x7b7bf17bff8af684), CONST64(0x3535d435b5e16a80),
11 CONST64(0x1d1d741de8693af5), CONST64(0xe0e0a7e05347ddb3), CONST64(0xd7d77bd7f6acb321), CONST64(0xc2c22fc25eed999c),
12 CONST64(0x2e2eb82e6d965c43), CONST64(0x4b4b314b627a9629), CONST64(0xfefedffea321e15d), CONST64(0x575741578216aed5),
13 CONST64(0x15155415a8412abd), CONST64(0x7777c1779fb6eee8), CONST64(0x3737dc37a5eb6e92), CONST64(0xe5e5b3e57b56d79e),
14 CONST64(0x9f9f469f8cd92313), CONST64(0xf0f0e7f0d317fd23), CONST64(0x4a4a354a6a7f9420), CONST64(0xdada4fda9e95a944),
15 CONST64(0x58587d58fa25b0a2), CONST64(0xc9c903c906ca8fcf), CONST64(0x2929a429558d527c), CONST64(0x0a0a280a5022145a),
16 CONST64(0xb1b1feb1e14f7f50), CONST64(0xa0a0baa0691a5dc9), CONST64(0x6b6bb16b7fdad614), CONST64(0x85852e855cab17d9),
17 CONST64(0xbdbdcebd8173673c), CONST64(0x5d5d695dd234ba8f), CONST64(0x1010401080502090), CONST64(0xf4f4f7f4f303f507),
18 CONST64(0xcbcb0bcb16c08bdd), CONST64(0x3e3ef83eedc67cd3), CONST64(0x0505140528110a2d), CONST64(0x676781671fe6ce78),
19 CONST64(0xe4e4b7e47353d597), CONST64(0x27279c2725bb4e02), CONST64(0x4141194132588273), CONST64(0x8b8b168b2c9d0ba7),
20 CONST64(0xa7a7a6a7510153f6), CONST64(0x7d7de97dcf94fab2), CONST64(0x95956e95dcfb3749), CONST64(0xd8d847d88e9fad56),
21 CONST64(0xfbfbcbfb8b30eb70), CONST64(0xeeee9fee2371c1cd), CONST64(0x7c7ced7cc791f8bb), CONST64(0x6666856617e3cc71),
22 CONST64(0xdddd53dda68ea77b), CONST64(0x17175c17b84b2eaf), CONST64(0x4747014702468e45), CONST64(0x9e9e429e84dc211a),
23 CONST64(0xcaca0fca1ec589d4), CONST64(0x2d2db42d75995a58), CONST64(0xbfbfc6bf9179632e), CONST64(0x07071c07381b0e3f),
24 CONST64(0xadad8ead012347ac), CONST64(0x5a5a755aea2fb4b0), CONST64(0x838336836cb51bef), CONST64(0x3333cc3385ff66b6),
25 CONST64(0x636391633ff2c65c), CONST64(0x02020802100a0412), CONST64(0xaaaa92aa39384993), CONST64(0x7171d971afa8e2de),
26 CONST64(0xc8c807c80ecf8dc6), CONST64(0x19196419c87d32d1), CONST64(0x494939497270923b), CONST64(0xd9d943d9869aaf5f),
27 CONST64(0xf2f2eff2c31df931), CONST64(0xe3e3abe34b48dba8), CONST64(0x5b5b715be22ab6b9), CONST64(0x88881a8834920dbc),
28 CONST64(0x9a9a529aa4c8293e), CONST64(0x262698262dbe4c0b), CONST64(0x3232c8328dfa64bf), CONST64(0xb0b0fab0e94a7d59),
29 CONST64(0xe9e983e91b6acff2), CONST64(0x0f0f3c0f78331e77), CONST64(0xd5d573d5e6a6b733), CONST64(0x80803a8074ba1df4),
30 CONST64(0xbebec2be997c6127), CONST64(0xcdcd13cd26de87eb), CONST64(0x3434d034bde46889), CONST64(0x48483d487a759032),
31 CONST64(0xffffdbffab24e354), CONST64(0x7a7af57af78ff48d), CONST64(0x90907a90f4ea3d64), CONST64(0x5f5f615fc23ebe9d),
32 CONST64(0x202080201da0403d), CONST64(0x6868bd6867d5d00f), CONST64(0x1a1a681ad07234ca), CONST64(0xaeae82ae192c41b7),
33 CONST64(0xb4b4eab4c95e757d), CONST64(0x54544d549a19a8ce), CONST64(0x93937693ece53b7f), CONST64(0x222288220daa442f),
34 CONST64(0x64648d6407e9c863), CONST64(0xf1f1e3f1db12ff2a), CONST64(0x7373d173bfa2e6cc), CONST64(0x12124812905a2482),
35 CONST64(0x40401d403a5d807a), CONST64(0x0808200840281048), CONST64(0xc3c32bc356e89b95), CONST64(0xecec97ec337bc5df),
36 CONST64(0xdbdb4bdb9690ab4d), CONST64(0xa1a1bea1611f5fc0), CONST64(0x8d8d0e8d1c830791), CONST64(0x3d3df43df5c97ac8),
37 CONST64(0x97976697ccf1335b), CONST64(0x0000000000000000), CONST64(0xcfcf1bcf36d483f9), CONST64(0x2b2bac2b4587566e),
38 CONST64(0x7676c57697b3ece1), CONST64(0x8282328264b019e6), CONST64(0xd6d67fd6fea9b128), CONST64(0x1b1b6c1bd87736c3),
39 CONST64(0xb5b5eeb5c15b7774), CONST64(0xafaf86af112943be), CONST64(0x6a6ab56a77dfd41d), CONST64(0x50505d50ba0da0ea),
40 CONST64(0x45450945124c8a57), CONST64(0xf3f3ebf3cb18fb38), CONST64(0x3030c0309df060ad), CONST64(0xefef9bef2b74c3c4),
41 CONST64(0x3f3ffc3fe5c37eda), CONST64(0x55554955921caac7), CONST64(0xa2a2b2a2791059db), CONST64(0xeaea8fea0365c9e9),
42 CONST64(0x656589650fecca6a), CONST64(0xbabad2bab9686903), CONST64(0x2f2fbc2f65935e4a), CONST64(0xc0c027c04ee79d8e),
43 CONST64(0xdede5fdebe81a160), CONST64(0x1c1c701ce06c38fc), CONST64(0xfdfdd3fdbb2ee746), CONST64(0x4d4d294d52649a1f),
44 CONST64(0x92927292e4e03976), CONST64(0x7575c9758fbceafa), CONST64(0x06061806301e0c36), CONST64(0x8a8a128a249809ae),
45 CONST64(0xb2b2f2b2f940794b), CONST64(0xe6e6bfe66359d185), CONST64(0x0e0e380e70361c7e), CONST64(0x1f1f7c1ff8633ee7),
46 CONST64(0x6262956237f7c455), CONST64(0xd4d477d4eea3b53a), CONST64(0xa8a89aa829324d81), CONST64(0x96966296c4f43152),
47 CONST64(0xf9f9c3f99b3aef62), CONST64(0xc5c533c566f697a3), CONST64(0x2525942535b14a10), CONST64(0x59597959f220b2ab),
48 CONST64(0x84842a8454ae15d0), CONST64(0x7272d572b7a7e4c5), CONST64(0x3939e439d5dd72ec), CONST64(0x4c4c2d4c5a619816),
49 CONST64(0x5e5e655eca3bbc94), CONST64(0x7878fd78e785f09f), CONST64(0x3838e038ddd870e5), CONST64(0x8c8c0a8c14860598),
50 CONST64(0xd1d163d1c6b2bf17), CONST64(0xa5a5aea5410b57e4), CONST64(0xe2e2afe2434dd9a1), CONST64(0x616199612ff8c24e),
51 CONST64(0xb3b3f6b3f1457b42), CONST64(0x2121842115a54234), CONST64(0x9c9c4a9c94d62508), CONST64(0x1e1e781ef0663cee),
52 CONST64(0x4343114322528661), CONST64(0xc7c73bc776fc93b1), CONST64(0xfcfcd7fcb32be54f), CONST64(0x0404100420140824),
53 CONST64(0x51515951b208a2e3), CONST64(0x99995e99bcc72f25), CONST64(0x6d6da96d4fc4da22), CONST64(0x0d0d340d68391a65),
54 CONST64(0xfafacffa8335e979), CONST64(0xdfdf5bdfb684a369), CONST64(0x7e7ee57ed79bfca9), CONST64(0x242490243db44819),
55 CONST64(0x3b3bec3bc5d776fe), CONST64(0xabab96ab313d4b9a), CONST64(0xcece1fce3ed181f0), CONST64(0x1111441188552299),
56 CONST64(0x8f8f068f0c890383), CONST64(0x4e4e254e4a6b9c04), CONST64(0xb7b7e6b7d1517366), CONST64(0xebeb8beb0b60cbe0),
57 CONST64(0x3c3cf03cfdcc78c1), CONST64(0x81813e817cbf1ffd), CONST64(0x94946a94d4fe3540), CONST64(0xf7f7fbf7eb0cf31c),
58 CONST64(0xb9b9deb9a1676f18), CONST64(0x13134c13985f268b), CONST64(0x2c2cb02c7d9c5851), CONST64(0xd3d36bd3d6b8bb05),
59 CONST64(0xe7e7bbe76b5cd38c), CONST64(0x6e6ea56e57cbdc39), CONST64(0xc4c437c46ef395aa), CONST64(0x03030c03180f061b),
60 CONST64(0x565645568a13acdc), CONST64(0x44440d441a49885e), CONST64(0x7f7fe17fdf9efea0), CONST64(0xa9a99ea921374f88),
61 CONST64(0x2a2aa82a4d825467), CONST64(0xbbbbd6bbb16d6b0a), CONST64(0xc1c123c146e29f87), CONST64(0x53535153a202a6f1),
62 CONST64(0xdcdc57dcae8ba572), CONST64(0x0b0b2c0b58271653), CONST64(0x9d9d4e9d9cd32701), CONST64(0x6c6cad6c47c1d82b),
63 CONST64(0x3131c43195f562a4), CONST64(0x7474cd7487b9e8f3), CONST64(0xf6f6fff6e309f115), CONST64(0x464605460a438c4c),
64 CONST64(0xacac8aac092645a5), CONST64(0x89891e893c970fb5), CONST64(0x14145014a04428b4), CONST64(0xe1e1a3e15b42dfba),
65 CONST64(0x16165816b04e2ca6), CONST64(0x3a3ae83acdd274f7), CONST64(0x6969b9696fd0d206), CONST64(0x09092409482d1241),
66 CONST64(0x7070dd70a7ade0d7), CONST64(0xb6b6e2b6d954716f), CONST64(0xd0d067d0ceb7bd1e), CONST64(0xeded93ed3b7ec7d6),
67 CONST64(0xcccc17cc2edb85e2), CONST64(0x424215422a578468), CONST64(0x98985a98b4c22d2c), CONST64(0xa4a4aaa4490e55ed),
68 CONST64(0x2828a0285d885075), CONST64(0x5c5c6d5cda31b886), CONST64(0xf8f8c7f8933fed6b), CONST64(0x8686228644a411c2)
69 };
70
71 #ifdef LTC_SMALL_CODE
72
73 #define SB0(x) sbox0[x]
74 #define SB1(x) ROR64c(sbox0[x], 8)
75 #define SB2(x) ROR64c(sbox0[x], 16)
76 #define SB3(x) ROR64c(sbox0[x], 24)
77 #define SB4(x) ROR64c(sbox0[x], 32)
78 #define SB5(x) ROR64c(sbox0[x], 40)
79 #define SB6(x) ROR64c(sbox0[x], 48)
80 #define SB7(x) ROR64c(sbox0[x], 56)
81
82 #else
83
84 #define SB0(x) sbox0[x]
85 #define SB1(x) sbox1[x]
86 #define SB2(x) sbox2[x]
87 #define SB3(x) sbox3[x]
88 #define SB4(x) sbox4[x]
89 #define SB5(x) sbox5[x]
90 #define SB6(x) sbox6[x]
91 #define SB7(x) sbox7[x]
92
93
94 static const ulong64 sbox1[] = {
95 CONST64(0xd818186018c07830), CONST64(0x2623238c2305af46), CONST64(0xb8c6c63fc67ef991), CONST64(0xfbe8e887e8136fcd),
96 CONST64(0xcb878726874ca113), CONST64(0x11b8b8dab8a9626d), CONST64(0x0901010401080502), CONST64(0x0d4f4f214f426e9e),
97 CONST64(0x9b3636d836adee6c), CONST64(0xffa6a6a2a6590451), CONST64(0x0cd2d26fd2debdb9), CONST64(0x0ef5f5f3f5fb06f7),
98 CONST64(0x967979f979ef80f2), CONST64(0x306f6fa16f5fcede), CONST64(0x6d91917e91fcef3f), CONST64(0xf852525552aa07a4),
99 CONST64(0x4760609d6027fdc0), CONST64(0x35bcbccabc897665), CONST64(0x379b9b569baccd2b), CONST64(0x8a8e8e028e048c01),
100 CONST64(0xd2a3a3b6a371155b), CONST64(0x6c0c0c300c603c18), CONST64(0x847b7bf17bff8af6), CONST64(0x803535d435b5e16a),
101 CONST64(0xf51d1d741de8693a), CONST64(0xb3e0e0a7e05347dd), CONST64(0x21d7d77bd7f6acb3), CONST64(0x9cc2c22fc25eed99),
102 CONST64(0x432e2eb82e6d965c), CONST64(0x294b4b314b627a96), CONST64(0x5dfefedffea321e1), CONST64(0xd5575741578216ae),
103 CONST64(0xbd15155415a8412a), CONST64(0xe87777c1779fb6ee), CONST64(0x923737dc37a5eb6e), CONST64(0x9ee5e5b3e57b56d7),
104 CONST64(0x139f9f469f8cd923), CONST64(0x23f0f0e7f0d317fd), CONST64(0x204a4a354a6a7f94), CONST64(0x44dada4fda9e95a9),
105 CONST64(0xa258587d58fa25b0), CONST64(0xcfc9c903c906ca8f), CONST64(0x7c2929a429558d52), CONST64(0x5a0a0a280a502214),
106 CONST64(0x50b1b1feb1e14f7f), CONST64(0xc9a0a0baa0691a5d), CONST64(0x146b6bb16b7fdad6), CONST64(0xd985852e855cab17),
107 CONST64(0x3cbdbdcebd817367), CONST64(0x8f5d5d695dd234ba), CONST64(0x9010104010805020), CONST64(0x07f4f4f7f4f303f5),
108 CONST64(0xddcbcb0bcb16c08b), CONST64(0xd33e3ef83eedc67c), CONST64(0x2d0505140528110a), CONST64(0x78676781671fe6ce),
109 CONST64(0x97e4e4b7e47353d5), CONST64(0x0227279c2725bb4e), CONST64(0x7341411941325882), CONST64(0xa78b8b168b2c9d0b),
110 CONST64(0xf6a7a7a6a7510153), CONST64(0xb27d7de97dcf94fa), CONST64(0x4995956e95dcfb37), CONST64(0x56d8d847d88e9fad),
111 CONST64(0x70fbfbcbfb8b30eb), CONST64(0xcdeeee9fee2371c1), CONST64(0xbb7c7ced7cc791f8), CONST64(0x716666856617e3cc),
112 CONST64(0x7bdddd53dda68ea7), CONST64(0xaf17175c17b84b2e), CONST64(0x454747014702468e), CONST64(0x1a9e9e429e84dc21),
113 CONST64(0xd4caca0fca1ec589), CONST64(0x582d2db42d75995a), CONST64(0x2ebfbfc6bf917963), CONST64(0x3f07071c07381b0e),
114 CONST64(0xacadad8ead012347), CONST64(0xb05a5a755aea2fb4), CONST64(0xef838336836cb51b), CONST64(0xb63333cc3385ff66),
115 CONST64(0x5c636391633ff2c6), CONST64(0x1202020802100a04), CONST64(0x93aaaa92aa393849), CONST64(0xde7171d971afa8e2),
116 CONST64(0xc6c8c807c80ecf8d), CONST64(0xd119196419c87d32), CONST64(0x3b49493949727092), CONST64(0x5fd9d943d9869aaf),
117 CONST64(0x31f2f2eff2c31df9), CONST64(0xa8e3e3abe34b48db), CONST64(0xb95b5b715be22ab6), CONST64(0xbc88881a8834920d),
118 CONST64(0x3e9a9a529aa4c829), CONST64(0x0b262698262dbe4c), CONST64(0xbf3232c8328dfa64), CONST64(0x59b0b0fab0e94a7d),
119 CONST64(0xf2e9e983e91b6acf), CONST64(0x770f0f3c0f78331e), CONST64(0x33d5d573d5e6a6b7), CONST64(0xf480803a8074ba1d),
120 CONST64(0x27bebec2be997c61), CONST64(0xebcdcd13cd26de87), CONST64(0x893434d034bde468), CONST64(0x3248483d487a7590),
121 CONST64(0x54ffffdbffab24e3), CONST64(0x8d7a7af57af78ff4), CONST64(0x6490907a90f4ea3d), CONST64(0x9d5f5f615fc23ebe),
122 CONST64(0x3d202080201da040), CONST64(0x0f6868bd6867d5d0), CONST64(0xca1a1a681ad07234), CONST64(0xb7aeae82ae192c41),
123 CONST64(0x7db4b4eab4c95e75), CONST64(0xce54544d549a19a8), CONST64(0x7f93937693ece53b), CONST64(0x2f222288220daa44),
124 CONST64(0x6364648d6407e9c8), CONST64(0x2af1f1e3f1db12ff), CONST64(0xcc7373d173bfa2e6), CONST64(0x8212124812905a24),
125 CONST64(0x7a40401d403a5d80), CONST64(0x4808082008402810), CONST64(0x95c3c32bc356e89b), CONST64(0xdfecec97ec337bc5),
126 CONST64(0x4ddbdb4bdb9690ab), CONST64(0xc0a1a1bea1611f5f), CONST64(0x918d8d0e8d1c8307), CONST64(0xc83d3df43df5c97a),
127 CONST64(0x5b97976697ccf133), CONST64(0x0000000000000000), CONST64(0xf9cfcf1bcf36d483), CONST64(0x6e2b2bac2b458756),
128 CONST64(0xe17676c57697b3ec), CONST64(0xe68282328264b019), CONST64(0x28d6d67fd6fea9b1), CONST64(0xc31b1b6c1bd87736),
129 CONST64(0x74b5b5eeb5c15b77), CONST64(0xbeafaf86af112943), CONST64(0x1d6a6ab56a77dfd4), CONST64(0xea50505d50ba0da0),
130 CONST64(0x5745450945124c8a), CONST64(0x38f3f3ebf3cb18fb), CONST64(0xad3030c0309df060), CONST64(0xc4efef9bef2b74c3),
131 CONST64(0xda3f3ffc3fe5c37e), CONST64(0xc755554955921caa), CONST64(0xdba2a2b2a2791059), CONST64(0xe9eaea8fea0365c9),
132 CONST64(0x6a656589650fecca), CONST64(0x03babad2bab96869), CONST64(0x4a2f2fbc2f65935e), CONST64(0x8ec0c027c04ee79d),
133 CONST64(0x60dede5fdebe81a1), CONST64(0xfc1c1c701ce06c38), CONST64(0x46fdfdd3fdbb2ee7), CONST64(0x1f4d4d294d52649a),
134 CONST64(0x7692927292e4e039), CONST64(0xfa7575c9758fbcea), CONST64(0x3606061806301e0c), CONST64(0xae8a8a128a249809),
135 CONST64(0x4bb2b2f2b2f94079), CONST64(0x85e6e6bfe66359d1), CONST64(0x7e0e0e380e70361c), CONST64(0xe71f1f7c1ff8633e),
136 CONST64(0x556262956237f7c4), CONST64(0x3ad4d477d4eea3b5), CONST64(0x81a8a89aa829324d), CONST64(0x5296966296c4f431),
137 CONST64(0x62f9f9c3f99b3aef), CONST64(0xa3c5c533c566f697), CONST64(0x102525942535b14a), CONST64(0xab59597959f220b2),
138 CONST64(0xd084842a8454ae15), CONST64(0xc57272d572b7a7e4), CONST64(0xec3939e439d5dd72), CONST64(0x164c4c2d4c5a6198),
139 CONST64(0x945e5e655eca3bbc), CONST64(0x9f7878fd78e785f0), CONST64(0xe53838e038ddd870), CONST64(0x988c8c0a8c148605),
140 CONST64(0x17d1d163d1c6b2bf), CONST64(0xe4a5a5aea5410b57), CONST64(0xa1e2e2afe2434dd9), CONST64(0x4e616199612ff8c2),
141 CONST64(0x42b3b3f6b3f1457b), CONST64(0x342121842115a542), CONST64(0x089c9c4a9c94d625), CONST64(0xee1e1e781ef0663c),
142 CONST64(0x6143431143225286), CONST64(0xb1c7c73bc776fc93), CONST64(0x4ffcfcd7fcb32be5), CONST64(0x2404041004201408),
143 CONST64(0xe351515951b208a2), CONST64(0x2599995e99bcc72f), CONST64(0x226d6da96d4fc4da), CONST64(0x650d0d340d68391a),
144 CONST64(0x79fafacffa8335e9), CONST64(0x69dfdf5bdfb684a3), CONST64(0xa97e7ee57ed79bfc), CONST64(0x19242490243db448),
145 CONST64(0xfe3b3bec3bc5d776), CONST64(0x9aabab96ab313d4b), CONST64(0xf0cece1fce3ed181), CONST64(0x9911114411885522),
146 CONST64(0x838f8f068f0c8903), CONST64(0x044e4e254e4a6b9c), CONST64(0x66b7b7e6b7d15173), CONST64(0xe0ebeb8beb0b60cb),
147 CONST64(0xc13c3cf03cfdcc78), CONST64(0xfd81813e817cbf1f), CONST64(0x4094946a94d4fe35), CONST64(0x1cf7f7fbf7eb0cf3),
148 CONST64(0x18b9b9deb9a1676f), CONST64(0x8b13134c13985f26), CONST64(0x512c2cb02c7d9c58), CONST64(0x05d3d36bd3d6b8bb),
149 CONST64(0x8ce7e7bbe76b5cd3), CONST64(0x396e6ea56e57cbdc), CONST64(0xaac4c437c46ef395), CONST64(0x1b03030c03180f06),
150 CONST64(0xdc565645568a13ac), CONST64(0x5e44440d441a4988), CONST64(0xa07f7fe17fdf9efe), CONST64(0x88a9a99ea921374f),
151 CONST64(0x672a2aa82a4d8254), CONST64(0x0abbbbd6bbb16d6b), CONST64(0x87c1c123c146e29f), CONST64(0xf153535153a202a6),
152 CONST64(0x72dcdc57dcae8ba5), CONST64(0x530b0b2c0b582716), CONST64(0x019d9d4e9d9cd327), CONST64(0x2b6c6cad6c47c1d8),
153 CONST64(0xa43131c43195f562), CONST64(0xf37474cd7487b9e8), CONST64(0x15f6f6fff6e309f1), CONST64(0x4c464605460a438c),
154 CONST64(0xa5acac8aac092645), CONST64(0xb589891e893c970f), CONST64(0xb414145014a04428), CONST64(0xbae1e1a3e15b42df),
155 CONST64(0xa616165816b04e2c), CONST64(0xf73a3ae83acdd274), CONST64(0x066969b9696fd0d2), CONST64(0x4109092409482d12),
156 CONST64(0xd77070dd70a7ade0), CONST64(0x6fb6b6e2b6d95471), CONST64(0x1ed0d067d0ceb7bd), CONST64(0xd6eded93ed3b7ec7),
157 CONST64(0xe2cccc17cc2edb85), CONST64(0x68424215422a5784), CONST64(0x2c98985a98b4c22d), CONST64(0xeda4a4aaa4490e55),
158 CONST64(0x752828a0285d8850), CONST64(0x865c5c6d5cda31b8), CONST64(0x6bf8f8c7f8933fed), CONST64(0xc28686228644a411)
159 };
160
161 static const ulong64 sbox2[] = {
162 CONST64(0x30d818186018c078), CONST64(0x462623238c2305af), CONST64(0x91b8c6c63fc67ef9), CONST64(0xcdfbe8e887e8136f),
163 CONST64(0x13cb878726874ca1), CONST64(0x6d11b8b8dab8a962), CONST64(0x0209010104010805), CONST64(0x9e0d4f4f214f426e),
164 CONST64(0x6c9b3636d836adee), CONST64(0x51ffa6a6a2a65904), CONST64(0xb90cd2d26fd2debd), CONST64(0xf70ef5f5f3f5fb06),
165 CONST64(0xf2967979f979ef80), CONST64(0xde306f6fa16f5fce), CONST64(0x3f6d91917e91fcef), CONST64(0xa4f852525552aa07),
166 CONST64(0xc04760609d6027fd), CONST64(0x6535bcbccabc8976), CONST64(0x2b379b9b569baccd), CONST64(0x018a8e8e028e048c),
167 CONST64(0x5bd2a3a3b6a37115), CONST64(0x186c0c0c300c603c), CONST64(0xf6847b7bf17bff8a), CONST64(0x6a803535d435b5e1),
168 CONST64(0x3af51d1d741de869), CONST64(0xddb3e0e0a7e05347), CONST64(0xb321d7d77bd7f6ac), CONST64(0x999cc2c22fc25eed),
169 CONST64(0x5c432e2eb82e6d96), CONST64(0x96294b4b314b627a), CONST64(0xe15dfefedffea321), CONST64(0xaed5575741578216),
170 CONST64(0x2abd15155415a841), CONST64(0xeee87777c1779fb6), CONST64(0x6e923737dc37a5eb), CONST64(0xd79ee5e5b3e57b56),
171 CONST64(0x23139f9f469f8cd9), CONST64(0xfd23f0f0e7f0d317), CONST64(0x94204a4a354a6a7f), CONST64(0xa944dada4fda9e95),
172 CONST64(0xb0a258587d58fa25), CONST64(0x8fcfc9c903c906ca), CONST64(0x527c2929a429558d), CONST64(0x145a0a0a280a5022),
173 CONST64(0x7f50b1b1feb1e14f), CONST64(0x5dc9a0a0baa0691a), CONST64(0xd6146b6bb16b7fda), CONST64(0x17d985852e855cab),
174 CONST64(0x673cbdbdcebd8173), CONST64(0xba8f5d5d695dd234), CONST64(0x2090101040108050), CONST64(0xf507f4f4f7f4f303),
175 CONST64(0x8bddcbcb0bcb16c0), CONST64(0x7cd33e3ef83eedc6), CONST64(0x0a2d050514052811), CONST64(0xce78676781671fe6),
176 CONST64(0xd597e4e4b7e47353), CONST64(0x4e0227279c2725bb), CONST64(0x8273414119413258), CONST64(0x0ba78b8b168b2c9d),
177 CONST64(0x53f6a7a7a6a75101), CONST64(0xfab27d7de97dcf94), CONST64(0x374995956e95dcfb), CONST64(0xad56d8d847d88e9f),
178 CONST64(0xeb70fbfbcbfb8b30), CONST64(0xc1cdeeee9fee2371), CONST64(0xf8bb7c7ced7cc791), CONST64(0xcc716666856617e3),
179 CONST64(0xa77bdddd53dda68e), CONST64(0x2eaf17175c17b84b), CONST64(0x8e45474701470246), CONST64(0x211a9e9e429e84dc),
180 CONST64(0x89d4caca0fca1ec5), CONST64(0x5a582d2db42d7599), CONST64(0x632ebfbfc6bf9179), CONST64(0x0e3f07071c07381b),
181 CONST64(0x47acadad8ead0123), CONST64(0xb4b05a5a755aea2f), CONST64(0x1bef838336836cb5), CONST64(0x66b63333cc3385ff),
182 CONST64(0xc65c636391633ff2), CONST64(0x041202020802100a), CONST64(0x4993aaaa92aa3938), CONST64(0xe2de7171d971afa8),
183 CONST64(0x8dc6c8c807c80ecf), CONST64(0x32d119196419c87d), CONST64(0x923b494939497270), CONST64(0xaf5fd9d943d9869a),
184 CONST64(0xf931f2f2eff2c31d), CONST64(0xdba8e3e3abe34b48), CONST64(0xb6b95b5b715be22a), CONST64(0x0dbc88881a883492),
185 CONST64(0x293e9a9a529aa4c8), CONST64(0x4c0b262698262dbe), CONST64(0x64bf3232c8328dfa), CONST64(0x7d59b0b0fab0e94a),
186 CONST64(0xcff2e9e983e91b6a), CONST64(0x1e770f0f3c0f7833), CONST64(0xb733d5d573d5e6a6), CONST64(0x1df480803a8074ba),
187 CONST64(0x6127bebec2be997c), CONST64(0x87ebcdcd13cd26de), CONST64(0x68893434d034bde4), CONST64(0x903248483d487a75),
188 CONST64(0xe354ffffdbffab24), CONST64(0xf48d7a7af57af78f), CONST64(0x3d6490907a90f4ea), CONST64(0xbe9d5f5f615fc23e),
189 CONST64(0x403d202080201da0), CONST64(0xd00f6868bd6867d5), CONST64(0x34ca1a1a681ad072), CONST64(0x41b7aeae82ae192c),
190 CONST64(0x757db4b4eab4c95e), CONST64(0xa8ce54544d549a19), CONST64(0x3b7f93937693ece5), CONST64(0x442f222288220daa),
191 CONST64(0xc86364648d6407e9), CONST64(0xff2af1f1e3f1db12), CONST64(0xe6cc7373d173bfa2), CONST64(0x248212124812905a),
192 CONST64(0x807a40401d403a5d), CONST64(0x1048080820084028), CONST64(0x9b95c3c32bc356e8), CONST64(0xc5dfecec97ec337b),
193 CONST64(0xab4ddbdb4bdb9690), CONST64(0x5fc0a1a1bea1611f), CONST64(0x07918d8d0e8d1c83), CONST64(0x7ac83d3df43df5c9),
194 CONST64(0x335b97976697ccf1), CONST64(0x0000000000000000), CONST64(0x83f9cfcf1bcf36d4), CONST64(0x566e2b2bac2b4587),
195 CONST64(0xece17676c57697b3), CONST64(0x19e68282328264b0), CONST64(0xb128d6d67fd6fea9), CONST64(0x36c31b1b6c1bd877),
196 CONST64(0x7774b5b5eeb5c15b), CONST64(0x43beafaf86af1129), CONST64(0xd41d6a6ab56a77df), CONST64(0xa0ea50505d50ba0d),
197 CONST64(0x8a5745450945124c), CONST64(0xfb38f3f3ebf3cb18), CONST64(0x60ad3030c0309df0), CONST64(0xc3c4efef9bef2b74),
198 CONST64(0x7eda3f3ffc3fe5c3), CONST64(0xaac755554955921c), CONST64(0x59dba2a2b2a27910), CONST64(0xc9e9eaea8fea0365),
199 CONST64(0xca6a656589650fec), CONST64(0x6903babad2bab968), CONST64(0x5e4a2f2fbc2f6593), CONST64(0x9d8ec0c027c04ee7),
200 CONST64(0xa160dede5fdebe81), CONST64(0x38fc1c1c701ce06c), CONST64(0xe746fdfdd3fdbb2e), CONST64(0x9a1f4d4d294d5264),
201 CONST64(0x397692927292e4e0), CONST64(0xeafa7575c9758fbc), CONST64(0x0c3606061806301e), CONST64(0x09ae8a8a128a2498),
202 CONST64(0x794bb2b2f2b2f940), CONST64(0xd185e6e6bfe66359), CONST64(0x1c7e0e0e380e7036), CONST64(0x3ee71f1f7c1ff863),
203 CONST64(0xc4556262956237f7), CONST64(0xb53ad4d477d4eea3), CONST64(0x4d81a8a89aa82932), CONST64(0x315296966296c4f4),
204 CONST64(0xef62f9f9c3f99b3a), CONST64(0x97a3c5c533c566f6), CONST64(0x4a102525942535b1), CONST64(0xb2ab59597959f220),
205 CONST64(0x15d084842a8454ae), CONST64(0xe4c57272d572b7a7), CONST64(0x72ec3939e439d5dd), CONST64(0x98164c4c2d4c5a61),
206 CONST64(0xbc945e5e655eca3b), CONST64(0xf09f7878fd78e785), CONST64(0x70e53838e038ddd8), CONST64(0x05988c8c0a8c1486),
207 CONST64(0xbf17d1d163d1c6b2), CONST64(0x57e4a5a5aea5410b), CONST64(0xd9a1e2e2afe2434d), CONST64(0xc24e616199612ff8),
208 CONST64(0x7b42b3b3f6b3f145), CONST64(0x42342121842115a5), CONST64(0x25089c9c4a9c94d6), CONST64(0x3cee1e1e781ef066),
209 CONST64(0x8661434311432252), CONST64(0x93b1c7c73bc776fc), CONST64(0xe54ffcfcd7fcb32b), CONST64(0x0824040410042014),
210 CONST64(0xa2e351515951b208), CONST64(0x2f2599995e99bcc7), CONST64(0xda226d6da96d4fc4), CONST64(0x1a650d0d340d6839),
211 CONST64(0xe979fafacffa8335), CONST64(0xa369dfdf5bdfb684), CONST64(0xfca97e7ee57ed79b), CONST64(0x4819242490243db4),
212 CONST64(0x76fe3b3bec3bc5d7), CONST64(0x4b9aabab96ab313d), CONST64(0x81f0cece1fce3ed1), CONST64(0x2299111144118855),
213 CONST64(0x03838f8f068f0c89), CONST64(0x9c044e4e254e4a6b), CONST64(0x7366b7b7e6b7d151), CONST64(0xcbe0ebeb8beb0b60),
214 CONST64(0x78c13c3cf03cfdcc), CONST64(0x1ffd81813e817cbf), CONST64(0x354094946a94d4fe), CONST64(0xf31cf7f7fbf7eb0c),
215 CONST64(0x6f18b9b9deb9a167), CONST64(0x268b13134c13985f), CONST64(0x58512c2cb02c7d9c), CONST64(0xbb05d3d36bd3d6b8),
216 CONST64(0xd38ce7e7bbe76b5c), CONST64(0xdc396e6ea56e57cb), CONST64(0x95aac4c437c46ef3), CONST64(0x061b03030c03180f),
217 CONST64(0xacdc565645568a13), CONST64(0x885e44440d441a49), CONST64(0xfea07f7fe17fdf9e), CONST64(0x4f88a9a99ea92137),
218 CONST64(0x54672a2aa82a4d82), CONST64(0x6b0abbbbd6bbb16d), CONST64(0x9f87c1c123c146e2), CONST64(0xa6f153535153a202),
219 CONST64(0xa572dcdc57dcae8b), CONST64(0x16530b0b2c0b5827), CONST64(0x27019d9d4e9d9cd3), CONST64(0xd82b6c6cad6c47c1),
220 CONST64(0x62a43131c43195f5), CONST64(0xe8f37474cd7487b9), CONST64(0xf115f6f6fff6e309), CONST64(0x8c4c464605460a43),
221 CONST64(0x45a5acac8aac0926), CONST64(0x0fb589891e893c97), CONST64(0x28b414145014a044), CONST64(0xdfbae1e1a3e15b42),
222 CONST64(0x2ca616165816b04e), CONST64(0x74f73a3ae83acdd2), CONST64(0xd2066969b9696fd0), CONST64(0x124109092409482d),
223 CONST64(0xe0d77070dd70a7ad), CONST64(0x716fb6b6e2b6d954), CONST64(0xbd1ed0d067d0ceb7), CONST64(0xc7d6eded93ed3b7e),
224 CONST64(0x85e2cccc17cc2edb), CONST64(0x8468424215422a57), CONST64(0x2d2c98985a98b4c2), CONST64(0x55eda4a4aaa4490e),
225 CONST64(0x50752828a0285d88), CONST64(0xb8865c5c6d5cda31), CONST64(0xed6bf8f8c7f8933f), CONST64(0x11c28686228644a4)
226 };
227
228 static const ulong64 sbox3[] = {
229 CONST64(0x7830d818186018c0), CONST64(0xaf462623238c2305), CONST64(0xf991b8c6c63fc67e), CONST64(0x6fcdfbe8e887e813),
230 CONST64(0xa113cb878726874c), CONST64(0x626d11b8b8dab8a9), CONST64(0x0502090101040108), CONST64(0x6e9e0d4f4f214f42),
231 CONST64(0xee6c9b3636d836ad), CONST64(0x0451ffa6a6a2a659), CONST64(0xbdb90cd2d26fd2de), CONST64(0x06f70ef5f5f3f5fb),
232 CONST64(0x80f2967979f979ef), CONST64(0xcede306f6fa16f5f), CONST64(0xef3f6d91917e91fc), CONST64(0x07a4f852525552aa),
233 CONST64(0xfdc04760609d6027), CONST64(0x766535bcbccabc89), CONST64(0xcd2b379b9b569bac), CONST64(0x8c018a8e8e028e04),
234 CONST64(0x155bd2a3a3b6a371), CONST64(0x3c186c0c0c300c60), CONST64(0x8af6847b7bf17bff), CONST64(0xe16a803535d435b5),
235 CONST64(0x693af51d1d741de8), CONST64(0x47ddb3e0e0a7e053), CONST64(0xacb321d7d77bd7f6), CONST64(0xed999cc2c22fc25e),
236 CONST64(0x965c432e2eb82e6d), CONST64(0x7a96294b4b314b62), CONST64(0x21e15dfefedffea3), CONST64(0x16aed55757415782),
237 CONST64(0x412abd15155415a8), CONST64(0xb6eee87777c1779f), CONST64(0xeb6e923737dc37a5), CONST64(0x56d79ee5e5b3e57b),
238 CONST64(0xd923139f9f469f8c), CONST64(0x17fd23f0f0e7f0d3), CONST64(0x7f94204a4a354a6a), CONST64(0x95a944dada4fda9e),
239 CONST64(0x25b0a258587d58fa), CONST64(0xca8fcfc9c903c906), CONST64(0x8d527c2929a42955), CONST64(0x22145a0a0a280a50),
240 CONST64(0x4f7f50b1b1feb1e1), CONST64(0x1a5dc9a0a0baa069), CONST64(0xdad6146b6bb16b7f), CONST64(0xab17d985852e855c),
241 CONST64(0x73673cbdbdcebd81), CONST64(0x34ba8f5d5d695dd2), CONST64(0x5020901010401080), CONST64(0x03f507f4f4f7f4f3),
242 CONST64(0xc08bddcbcb0bcb16), CONST64(0xc67cd33e3ef83eed), CONST64(0x110a2d0505140528), CONST64(0xe6ce78676781671f),
243 CONST64(0x53d597e4e4b7e473), CONST64(0xbb4e0227279c2725), CONST64(0x5882734141194132), CONST64(0x9d0ba78b8b168b2c),
244 CONST64(0x0153f6a7a7a6a751), CONST64(0x94fab27d7de97dcf), CONST64(0xfb374995956e95dc), CONST64(0x9fad56d8d847d88e),
245 CONST64(0x30eb70fbfbcbfb8b), CONST64(0x71c1cdeeee9fee23), CONST64(0x91f8bb7c7ced7cc7), CONST64(0xe3cc716666856617),
246 CONST64(0x8ea77bdddd53dda6), CONST64(0x4b2eaf17175c17b8), CONST64(0x468e454747014702), CONST64(0xdc211a9e9e429e84),
247 CONST64(0xc589d4caca0fca1e), CONST64(0x995a582d2db42d75), CONST64(0x79632ebfbfc6bf91), CONST64(0x1b0e3f07071c0738),
248 CONST64(0x2347acadad8ead01), CONST64(0x2fb4b05a5a755aea), CONST64(0xb51bef838336836c), CONST64(0xff66b63333cc3385),
249 CONST64(0xf2c65c636391633f), CONST64(0x0a04120202080210), CONST64(0x384993aaaa92aa39), CONST64(0xa8e2de7171d971af),
250 CONST64(0xcf8dc6c8c807c80e), CONST64(0x7d32d119196419c8), CONST64(0x70923b4949394972), CONST64(0x9aaf5fd9d943d986),
251 CONST64(0x1df931f2f2eff2c3), CONST64(0x48dba8e3e3abe34b), CONST64(0x2ab6b95b5b715be2), CONST64(0x920dbc88881a8834),
252 CONST64(0xc8293e9a9a529aa4), CONST64(0xbe4c0b262698262d), CONST64(0xfa64bf3232c8328d), CONST64(0x4a7d59b0b0fab0e9),
253 CONST64(0x6acff2e9e983e91b), CONST64(0x331e770f0f3c0f78), CONST64(0xa6b733d5d573d5e6), CONST64(0xba1df480803a8074),
254 CONST64(0x7c6127bebec2be99), CONST64(0xde87ebcdcd13cd26), CONST64(0xe468893434d034bd), CONST64(0x75903248483d487a),
255 CONST64(0x24e354ffffdbffab), CONST64(0x8ff48d7a7af57af7), CONST64(0xea3d6490907a90f4), CONST64(0x3ebe9d5f5f615fc2),
256 CONST64(0xa0403d202080201d), CONST64(0xd5d00f6868bd6867), CONST64(0x7234ca1a1a681ad0), CONST64(0x2c41b7aeae82ae19),
257 CONST64(0x5e757db4b4eab4c9), CONST64(0x19a8ce54544d549a), CONST64(0xe53b7f93937693ec), CONST64(0xaa442f222288220d),
258 CONST64(0xe9c86364648d6407), CONST64(0x12ff2af1f1e3f1db), CONST64(0xa2e6cc7373d173bf), CONST64(0x5a24821212481290),
259 CONST64(0x5d807a40401d403a), CONST64(0x2810480808200840), CONST64(0xe89b95c3c32bc356), CONST64(0x7bc5dfecec97ec33),
260 CONST64(0x90ab4ddbdb4bdb96), CONST64(0x1f5fc0a1a1bea161), CONST64(0x8307918d8d0e8d1c), CONST64(0xc97ac83d3df43df5),
261 CONST64(0xf1335b97976697cc), CONST64(0x0000000000000000), CONST64(0xd483f9cfcf1bcf36), CONST64(0x87566e2b2bac2b45),
262 CONST64(0xb3ece17676c57697), CONST64(0xb019e68282328264), CONST64(0xa9b128d6d67fd6fe), CONST64(0x7736c31b1b6c1bd8),
263 CONST64(0x5b7774b5b5eeb5c1), CONST64(0x2943beafaf86af11), CONST64(0xdfd41d6a6ab56a77), CONST64(0x0da0ea50505d50ba),
264 CONST64(0x4c8a574545094512), CONST64(0x18fb38f3f3ebf3cb), CONST64(0xf060ad3030c0309d), CONST64(0x74c3c4efef9bef2b),
265 CONST64(0xc37eda3f3ffc3fe5), CONST64(0x1caac75555495592), CONST64(0x1059dba2a2b2a279), CONST64(0x65c9e9eaea8fea03),
266 CONST64(0xecca6a656589650f), CONST64(0x686903babad2bab9), CONST64(0x935e4a2f2fbc2f65), CONST64(0xe79d8ec0c027c04e),
267 CONST64(0x81a160dede5fdebe), CONST64(0x6c38fc1c1c701ce0), CONST64(0x2ee746fdfdd3fdbb), CONST64(0x649a1f4d4d294d52),
268 CONST64(0xe0397692927292e4), CONST64(0xbceafa7575c9758f), CONST64(0x1e0c360606180630), CONST64(0x9809ae8a8a128a24),
269 CONST64(0x40794bb2b2f2b2f9), CONST64(0x59d185e6e6bfe663), CONST64(0x361c7e0e0e380e70), CONST64(0x633ee71f1f7c1ff8),
270 CONST64(0xf7c4556262956237), CONST64(0xa3b53ad4d477d4ee), CONST64(0x324d81a8a89aa829), CONST64(0xf4315296966296c4),
271 CONST64(0x3aef62f9f9c3f99b), CONST64(0xf697a3c5c533c566), CONST64(0xb14a102525942535), CONST64(0x20b2ab59597959f2),
272 CONST64(0xae15d084842a8454), CONST64(0xa7e4c57272d572b7), CONST64(0xdd72ec3939e439d5), CONST64(0x6198164c4c2d4c5a),
273 CONST64(0x3bbc945e5e655eca), CONST64(0x85f09f7878fd78e7), CONST64(0xd870e53838e038dd), CONST64(0x8605988c8c0a8c14),
274 CONST64(0xb2bf17d1d163d1c6), CONST64(0x0b57e4a5a5aea541), CONST64(0x4dd9a1e2e2afe243), CONST64(0xf8c24e616199612f),
275 CONST64(0x457b42b3b3f6b3f1), CONST64(0xa542342121842115), CONST64(0xd625089c9c4a9c94), CONST64(0x663cee1e1e781ef0),
276 CONST64(0x5286614343114322), CONST64(0xfc93b1c7c73bc776), CONST64(0x2be54ffcfcd7fcb3), CONST64(0x1408240404100420),
277 CONST64(0x08a2e351515951b2), CONST64(0xc72f2599995e99bc), CONST64(0xc4da226d6da96d4f), CONST64(0x391a650d0d340d68),
278 CONST64(0x35e979fafacffa83), CONST64(0x84a369dfdf5bdfb6), CONST64(0x9bfca97e7ee57ed7), CONST64(0xb44819242490243d),
279 CONST64(0xd776fe3b3bec3bc5), CONST64(0x3d4b9aabab96ab31), CONST64(0xd181f0cece1fce3e), CONST64(0x5522991111441188),
280 CONST64(0x8903838f8f068f0c), CONST64(0x6b9c044e4e254e4a), CONST64(0x517366b7b7e6b7d1), CONST64(0x60cbe0ebeb8beb0b),
281 CONST64(0xcc78c13c3cf03cfd), CONST64(0xbf1ffd81813e817c), CONST64(0xfe354094946a94d4), CONST64(0x0cf31cf7f7fbf7eb),
282 CONST64(0x676f18b9b9deb9a1), CONST64(0x5f268b13134c1398), CONST64(0x9c58512c2cb02c7d), CONST64(0xb8bb05d3d36bd3d6),
283 CONST64(0x5cd38ce7e7bbe76b), CONST64(0xcbdc396e6ea56e57), CONST64(0xf395aac4c437c46e), CONST64(0x0f061b03030c0318),
284 CONST64(0x13acdc565645568a), CONST64(0x49885e44440d441a), CONST64(0x9efea07f7fe17fdf), CONST64(0x374f88a9a99ea921),
285 CONST64(0x8254672a2aa82a4d), CONST64(0x6d6b0abbbbd6bbb1), CONST64(0xe29f87c1c123c146), CONST64(0x02a6f153535153a2),
286 CONST64(0x8ba572dcdc57dcae), CONST64(0x2716530b0b2c0b58), CONST64(0xd327019d9d4e9d9c), CONST64(0xc1d82b6c6cad6c47),
287 CONST64(0xf562a43131c43195), CONST64(0xb9e8f37474cd7487), CONST64(0x09f115f6f6fff6e3), CONST64(0x438c4c464605460a),
288 CONST64(0x2645a5acac8aac09), CONST64(0x970fb589891e893c), CONST64(0x4428b414145014a0), CONST64(0x42dfbae1e1a3e15b),
289 CONST64(0x4e2ca616165816b0), CONST64(0xd274f73a3ae83acd), CONST64(0xd0d2066969b9696f), CONST64(0x2d12410909240948),
290 CONST64(0xade0d77070dd70a7), CONST64(0x54716fb6b6e2b6d9), CONST64(0xb7bd1ed0d067d0ce), CONST64(0x7ec7d6eded93ed3b),
291 CONST64(0xdb85e2cccc17cc2e), CONST64(0x578468424215422a), CONST64(0xc22d2c98985a98b4), CONST64(0x0e55eda4a4aaa449),
292 CONST64(0x8850752828a0285d), CONST64(0x31b8865c5c6d5cda), CONST64(0x3fed6bf8f8c7f893), CONST64(0xa411c28686228644)
293 };
294
295 static const ulong64 sbox4[] = {
296 CONST64(0xc07830d818186018), CONST64(0x05af462623238c23), CONST64(0x7ef991b8c6c63fc6), CONST64(0x136fcdfbe8e887e8),
297 CONST64(0x4ca113cb87872687), CONST64(0xa9626d11b8b8dab8), CONST64(0x0805020901010401), CONST64(0x426e9e0d4f4f214f),
298 CONST64(0xadee6c9b3636d836), CONST64(0x590451ffa6a6a2a6), CONST64(0xdebdb90cd2d26fd2), CONST64(0xfb06f70ef5f5f3f5),
299 CONST64(0xef80f2967979f979), CONST64(0x5fcede306f6fa16f), CONST64(0xfcef3f6d91917e91), CONST64(0xaa07a4f852525552),
300 CONST64(0x27fdc04760609d60), CONST64(0x89766535bcbccabc), CONST64(0xaccd2b379b9b569b), CONST64(0x048c018a8e8e028e),
301 CONST64(0x71155bd2a3a3b6a3), CONST64(0x603c186c0c0c300c), CONST64(0xff8af6847b7bf17b), CONST64(0xb5e16a803535d435),
302 CONST64(0xe8693af51d1d741d), CONST64(0x5347ddb3e0e0a7e0), CONST64(0xf6acb321d7d77bd7), CONST64(0x5eed999cc2c22fc2),
303 CONST64(0x6d965c432e2eb82e), CONST64(0x627a96294b4b314b), CONST64(0xa321e15dfefedffe), CONST64(0x8216aed557574157),
304 CONST64(0xa8412abd15155415), CONST64(0x9fb6eee87777c177), CONST64(0xa5eb6e923737dc37), CONST64(0x7b56d79ee5e5b3e5),
305 CONST64(0x8cd923139f9f469f), CONST64(0xd317fd23f0f0e7f0), CONST64(0x6a7f94204a4a354a), CONST64(0x9e95a944dada4fda),
306 CONST64(0xfa25b0a258587d58), CONST64(0x06ca8fcfc9c903c9), CONST64(0x558d527c2929a429), CONST64(0x5022145a0a0a280a),
307 CONST64(0xe14f7f50b1b1feb1), CONST64(0x691a5dc9a0a0baa0), CONST64(0x7fdad6146b6bb16b), CONST64(0x5cab17d985852e85),
308 CONST64(0x8173673cbdbdcebd), CONST64(0xd234ba8f5d5d695d), CONST64(0x8050209010104010), CONST64(0xf303f507f4f4f7f4),
309 CONST64(0x16c08bddcbcb0bcb), CONST64(0xedc67cd33e3ef83e), CONST64(0x28110a2d05051405), CONST64(0x1fe6ce7867678167),
310 CONST64(0x7353d597e4e4b7e4), CONST64(0x25bb4e0227279c27), CONST64(0x3258827341411941), CONST64(0x2c9d0ba78b8b168b),
311 CONST64(0x510153f6a7a7a6a7), CONST64(0xcf94fab27d7de97d), CONST64(0xdcfb374995956e95), CONST64(0x8e9fad56d8d847d8),
312 CONST64(0x8b30eb70fbfbcbfb), CONST64(0x2371c1cdeeee9fee), CONST64(0xc791f8bb7c7ced7c), CONST64(0x17e3cc7166668566),
313 CONST64(0xa68ea77bdddd53dd), CONST64(0xb84b2eaf17175c17), CONST64(0x02468e4547470147), CONST64(0x84dc211a9e9e429e),
314 CONST64(0x1ec589d4caca0fca), CONST64(0x75995a582d2db42d), CONST64(0x9179632ebfbfc6bf), CONST64(0x381b0e3f07071c07),
315 CONST64(0x012347acadad8ead), CONST64(0xea2fb4b05a5a755a), CONST64(0x6cb51bef83833683), CONST64(0x85ff66b63333cc33),
316 CONST64(0x3ff2c65c63639163), CONST64(0x100a041202020802), CONST64(0x39384993aaaa92aa), CONST64(0xafa8e2de7171d971),
317 CONST64(0x0ecf8dc6c8c807c8), CONST64(0xc87d32d119196419), CONST64(0x7270923b49493949), CONST64(0x869aaf5fd9d943d9),
318 CONST64(0xc31df931f2f2eff2), CONST64(0x4b48dba8e3e3abe3), CONST64(0xe22ab6b95b5b715b), CONST64(0x34920dbc88881a88),
319 CONST64(0xa4c8293e9a9a529a), CONST64(0x2dbe4c0b26269826), CONST64(0x8dfa64bf3232c832), CONST64(0xe94a7d59b0b0fab0),
320 CONST64(0x1b6acff2e9e983e9), CONST64(0x78331e770f0f3c0f), CONST64(0xe6a6b733d5d573d5), CONST64(0x74ba1df480803a80),
321 CONST64(0x997c6127bebec2be), CONST64(0x26de87ebcdcd13cd), CONST64(0xbde468893434d034), CONST64(0x7a75903248483d48),
322 CONST64(0xab24e354ffffdbff), CONST64(0xf78ff48d7a7af57a), CONST64(0xf4ea3d6490907a90), CONST64(0xc23ebe9d5f5f615f),
323 CONST64(0x1da0403d20208020), CONST64(0x67d5d00f6868bd68), CONST64(0xd07234ca1a1a681a), CONST64(0x192c41b7aeae82ae),
324 CONST64(0xc95e757db4b4eab4), CONST64(0x9a19a8ce54544d54), CONST64(0xece53b7f93937693), CONST64(0x0daa442f22228822),
325 CONST64(0x07e9c86364648d64), CONST64(0xdb12ff2af1f1e3f1), CONST64(0xbfa2e6cc7373d173), CONST64(0x905a248212124812),
326 CONST64(0x3a5d807a40401d40), CONST64(0x4028104808082008), CONST64(0x56e89b95c3c32bc3), CONST64(0x337bc5dfecec97ec),
327 CONST64(0x9690ab4ddbdb4bdb), CONST64(0x611f5fc0a1a1bea1), CONST64(0x1c8307918d8d0e8d), CONST64(0xf5c97ac83d3df43d),
328 CONST64(0xccf1335b97976697), CONST64(0x0000000000000000), CONST64(0x36d483f9cfcf1bcf), CONST64(0x4587566e2b2bac2b),
329 CONST64(0x97b3ece17676c576), CONST64(0x64b019e682823282), CONST64(0xfea9b128d6d67fd6), CONST64(0xd87736c31b1b6c1b),
330 CONST64(0xc15b7774b5b5eeb5), CONST64(0x112943beafaf86af), CONST64(0x77dfd41d6a6ab56a), CONST64(0xba0da0ea50505d50),
331 CONST64(0x124c8a5745450945), CONST64(0xcb18fb38f3f3ebf3), CONST64(0x9df060ad3030c030), CONST64(0x2b74c3c4efef9bef),
332 CONST64(0xe5c37eda3f3ffc3f), CONST64(0x921caac755554955), CONST64(0x791059dba2a2b2a2), CONST64(0x0365c9e9eaea8fea),
333 CONST64(0x0fecca6a65658965), CONST64(0xb9686903babad2ba), CONST64(0x65935e4a2f2fbc2f), CONST64(0x4ee79d8ec0c027c0),
334 CONST64(0xbe81a160dede5fde), CONST64(0xe06c38fc1c1c701c), CONST64(0xbb2ee746fdfdd3fd), CONST64(0x52649a1f4d4d294d),
335 CONST64(0xe4e0397692927292), CONST64(0x8fbceafa7575c975), CONST64(0x301e0c3606061806), CONST64(0x249809ae8a8a128a),
336 CONST64(0xf940794bb2b2f2b2), CONST64(0x6359d185e6e6bfe6), CONST64(0x70361c7e0e0e380e), CONST64(0xf8633ee71f1f7c1f),
337 CONST64(0x37f7c45562629562), CONST64(0xeea3b53ad4d477d4), CONST64(0x29324d81a8a89aa8), CONST64(0xc4f4315296966296),
338 CONST64(0x9b3aef62f9f9c3f9), CONST64(0x66f697a3c5c533c5), CONST64(0x35b14a1025259425), CONST64(0xf220b2ab59597959),
339 CONST64(0x54ae15d084842a84), CONST64(0xb7a7e4c57272d572), CONST64(0xd5dd72ec3939e439), CONST64(0x5a6198164c4c2d4c),
340 CONST64(0xca3bbc945e5e655e), CONST64(0xe785f09f7878fd78), CONST64(0xddd870e53838e038), CONST64(0x148605988c8c0a8c),
341 CONST64(0xc6b2bf17d1d163d1), CONST64(0x410b57e4a5a5aea5), CONST64(0x434dd9a1e2e2afe2), CONST64(0x2ff8c24e61619961),
342 CONST64(0xf1457b42b3b3f6b3), CONST64(0x15a5423421218421), CONST64(0x94d625089c9c4a9c), CONST64(0xf0663cee1e1e781e),
343 CONST64(0x2252866143431143), CONST64(0x76fc93b1c7c73bc7), CONST64(0xb32be54ffcfcd7fc), CONST64(0x2014082404041004),
344 CONST64(0xb208a2e351515951), CONST64(0xbcc72f2599995e99), CONST64(0x4fc4da226d6da96d), CONST64(0x68391a650d0d340d),
345 CONST64(0x8335e979fafacffa), CONST64(0xb684a369dfdf5bdf), CONST64(0xd79bfca97e7ee57e), CONST64(0x3db4481924249024),
346 CONST64(0xc5d776fe3b3bec3b), CONST64(0x313d4b9aabab96ab), CONST64(0x3ed181f0cece1fce), CONST64(0x8855229911114411),
347 CONST64(0x0c8903838f8f068f), CONST64(0x4a6b9c044e4e254e), CONST64(0xd1517366b7b7e6b7), CONST64(0x0b60cbe0ebeb8beb),
348 CONST64(0xfdcc78c13c3cf03c), CONST64(0x7cbf1ffd81813e81), CONST64(0xd4fe354094946a94), CONST64(0xeb0cf31cf7f7fbf7),
349 CONST64(0xa1676f18b9b9deb9), CONST64(0x985f268b13134c13), CONST64(0x7d9c58512c2cb02c), CONST64(0xd6b8bb05d3d36bd3),
350 CONST64(0x6b5cd38ce7e7bbe7), CONST64(0x57cbdc396e6ea56e), CONST64(0x6ef395aac4c437c4), CONST64(0x180f061b03030c03),
351 CONST64(0x8a13acdc56564556), CONST64(0x1a49885e44440d44), CONST64(0xdf9efea07f7fe17f), CONST64(0x21374f88a9a99ea9),
352 CONST64(0x4d8254672a2aa82a), CONST64(0xb16d6b0abbbbd6bb), CONST64(0x46e29f87c1c123c1), CONST64(0xa202a6f153535153),
353 CONST64(0xae8ba572dcdc57dc), CONST64(0x582716530b0b2c0b), CONST64(0x9cd327019d9d4e9d), CONST64(0x47c1d82b6c6cad6c),
354 CONST64(0x95f562a43131c431), CONST64(0x87b9e8f37474cd74), CONST64(0xe309f115f6f6fff6), CONST64(0x0a438c4c46460546),
355 CONST64(0x092645a5acac8aac), CONST64(0x3c970fb589891e89), CONST64(0xa04428b414145014), CONST64(0x5b42dfbae1e1a3e1),
356 CONST64(0xb04e2ca616165816), CONST64(0xcdd274f73a3ae83a), CONST64(0x6fd0d2066969b969), CONST64(0x482d124109092409),
357 CONST64(0xa7ade0d77070dd70), CONST64(0xd954716fb6b6e2b6), CONST64(0xceb7bd1ed0d067d0), CONST64(0x3b7ec7d6eded93ed),
358 CONST64(0x2edb85e2cccc17cc), CONST64(0x2a57846842421542), CONST64(0xb4c22d2c98985a98), CONST64(0x490e55eda4a4aaa4),
359 CONST64(0x5d8850752828a028), CONST64(0xda31b8865c5c6d5c), CONST64(0x933fed6bf8f8c7f8), CONST64(0x44a411c286862286)
360 };
361
362 static const ulong64 sbox5[] = {
363 CONST64(0x18c07830d8181860), CONST64(0x2305af462623238c), CONST64(0xc67ef991b8c6c63f), CONST64(0xe8136fcdfbe8e887),
364 CONST64(0x874ca113cb878726), CONST64(0xb8a9626d11b8b8da), CONST64(0x0108050209010104), CONST64(0x4f426e9e0d4f4f21),
365 CONST64(0x36adee6c9b3636d8), CONST64(0xa6590451ffa6a6a2), CONST64(0xd2debdb90cd2d26f), CONST64(0xf5fb06f70ef5f5f3),
366 CONST64(0x79ef80f2967979f9), CONST64(0x6f5fcede306f6fa1), CONST64(0x91fcef3f6d91917e), CONST64(0x52aa07a4f8525255),
367 CONST64(0x6027fdc04760609d), CONST64(0xbc89766535bcbcca), CONST64(0x9baccd2b379b9b56), CONST64(0x8e048c018a8e8e02),
368 CONST64(0xa371155bd2a3a3b6), CONST64(0x0c603c186c0c0c30), CONST64(0x7bff8af6847b7bf1), CONST64(0x35b5e16a803535d4),
369 CONST64(0x1de8693af51d1d74), CONST64(0xe05347ddb3e0e0a7), CONST64(0xd7f6acb321d7d77b), CONST64(0xc25eed999cc2c22f),
370 CONST64(0x2e6d965c432e2eb8), CONST64(0x4b627a96294b4b31), CONST64(0xfea321e15dfefedf), CONST64(0x578216aed5575741),
371 CONST64(0x15a8412abd151554), CONST64(0x779fb6eee87777c1), CONST64(0x37a5eb6e923737dc), CONST64(0xe57b56d79ee5e5b3),
372 CONST64(0x9f8cd923139f9f46), CONST64(0xf0d317fd23f0f0e7), CONST64(0x4a6a7f94204a4a35), CONST64(0xda9e95a944dada4f),
373 CONST64(0x58fa25b0a258587d), CONST64(0xc906ca8fcfc9c903), CONST64(0x29558d527c2929a4), CONST64(0x0a5022145a0a0a28),
374 CONST64(0xb1e14f7f50b1b1fe), CONST64(0xa0691a5dc9a0a0ba), CONST64(0x6b7fdad6146b6bb1), CONST64(0x855cab17d985852e),
375 CONST64(0xbd8173673cbdbdce), CONST64(0x5dd234ba8f5d5d69), CONST64(0x1080502090101040), CONST64(0xf4f303f507f4f4f7),
376 CONST64(0xcb16c08bddcbcb0b), CONST64(0x3eedc67cd33e3ef8), CONST64(0x0528110a2d050514), CONST64(0x671fe6ce78676781),
377 CONST64(0xe47353d597e4e4b7), CONST64(0x2725bb4e0227279c), CONST64(0x4132588273414119), CONST64(0x8b2c9d0ba78b8b16),
378 CONST64(0xa7510153f6a7a7a6), CONST64(0x7dcf94fab27d7de9), CONST64(0x95dcfb374995956e), CONST64(0xd88e9fad56d8d847),
379 CONST64(0xfb8b30eb70fbfbcb), CONST64(0xee2371c1cdeeee9f), CONST64(0x7cc791f8bb7c7ced), CONST64(0x6617e3cc71666685),
380 CONST64(0xdda68ea77bdddd53), CONST64(0x17b84b2eaf17175c), CONST64(0x4702468e45474701), CONST64(0x9e84dc211a9e9e42),
381 CONST64(0xca1ec589d4caca0f), CONST64(0x2d75995a582d2db4), CONST64(0xbf9179632ebfbfc6), CONST64(0x07381b0e3f07071c),
382 CONST64(0xad012347acadad8e), CONST64(0x5aea2fb4b05a5a75), CONST64(0x836cb51bef838336), CONST64(0x3385ff66b63333cc),
383 CONST64(0x633ff2c65c636391), CONST64(0x02100a0412020208), CONST64(0xaa39384993aaaa92), CONST64(0x71afa8e2de7171d9),
384 CONST64(0xc80ecf8dc6c8c807), CONST64(0x19c87d32d1191964), CONST64(0x497270923b494939), CONST64(0xd9869aaf5fd9d943),
385 CONST64(0xf2c31df931f2f2ef), CONST64(0xe34b48dba8e3e3ab), CONST64(0x5be22ab6b95b5b71), CONST64(0x8834920dbc88881a),
386 CONST64(0x9aa4c8293e9a9a52), CONST64(0x262dbe4c0b262698), CONST64(0x328dfa64bf3232c8), CONST64(0xb0e94a7d59b0b0fa),
387 CONST64(0xe91b6acff2e9e983), CONST64(0x0f78331e770f0f3c), CONST64(0xd5e6a6b733d5d573), CONST64(0x8074ba1df480803a),
388 CONST64(0xbe997c6127bebec2), CONST64(0xcd26de87ebcdcd13), CONST64(0x34bde468893434d0), CONST64(0x487a75903248483d),
389 CONST64(0xffab24e354ffffdb), CONST64(0x7af78ff48d7a7af5), CONST64(0x90f4ea3d6490907a), CONST64(0x5fc23ebe9d5f5f61),
390 CONST64(0x201da0403d202080), CONST64(0x6867d5d00f6868bd), CONST64(0x1ad07234ca1a1a68), CONST64(0xae192c41b7aeae82),
391 CONST64(0xb4c95e757db4b4ea), CONST64(0x549a19a8ce54544d), CONST64(0x93ece53b7f939376), CONST64(0x220daa442f222288),
392 CONST64(0x6407e9c86364648d), CONST64(0xf1db12ff2af1f1e3), CONST64(0x73bfa2e6cc7373d1), CONST64(0x12905a2482121248),
393 CONST64(0x403a5d807a40401d), CONST64(0x0840281048080820), CONST64(0xc356e89b95c3c32b), CONST64(0xec337bc5dfecec97),
394 CONST64(0xdb9690ab4ddbdb4b), CONST64(0xa1611f5fc0a1a1be), CONST64(0x8d1c8307918d8d0e), CONST64(0x3df5c97ac83d3df4),
395 CONST64(0x97ccf1335b979766), CONST64(0x0000000000000000), CONST64(0xcf36d483f9cfcf1b), CONST64(0x2b4587566e2b2bac),
396 CONST64(0x7697b3ece17676c5), CONST64(0x8264b019e6828232), CONST64(0xd6fea9b128d6d67f), CONST64(0x1bd87736c31b1b6c),
397 CONST64(0xb5c15b7774b5b5ee), CONST64(0xaf112943beafaf86), CONST64(0x6a77dfd41d6a6ab5), CONST64(0x50ba0da0ea50505d),
398 CONST64(0x45124c8a57454509), CONST64(0xf3cb18fb38f3f3eb), CONST64(0x309df060ad3030c0), CONST64(0xef2b74c3c4efef9b),
399 CONST64(0x3fe5c37eda3f3ffc), CONST64(0x55921caac7555549), CONST64(0xa2791059dba2a2b2), CONST64(0xea0365c9e9eaea8f),
400 CONST64(0x650fecca6a656589), CONST64(0xbab9686903babad2), CONST64(0x2f65935e4a2f2fbc), CONST64(0xc04ee79d8ec0c027),
401 CONST64(0xdebe81a160dede5f), CONST64(0x1ce06c38fc1c1c70), CONST64(0xfdbb2ee746fdfdd3), CONST64(0x4d52649a1f4d4d29),
402 CONST64(0x92e4e03976929272), CONST64(0x758fbceafa7575c9), CONST64(0x06301e0c36060618), CONST64(0x8a249809ae8a8a12),
403 CONST64(0xb2f940794bb2b2f2), CONST64(0xe66359d185e6e6bf), CONST64(0x0e70361c7e0e0e38), CONST64(0x1ff8633ee71f1f7c),
404 CONST64(0x6237f7c455626295), CONST64(0xd4eea3b53ad4d477), CONST64(0xa829324d81a8a89a), CONST64(0x96c4f43152969662),
405 CONST64(0xf99b3aef62f9f9c3), CONST64(0xc566f697a3c5c533), CONST64(0x2535b14a10252594), CONST64(0x59f220b2ab595979),
406 CONST64(0x8454ae15d084842a), CONST64(0x72b7a7e4c57272d5), CONST64(0x39d5dd72ec3939e4), CONST64(0x4c5a6198164c4c2d),
407 CONST64(0x5eca3bbc945e5e65), CONST64(0x78e785f09f7878fd), CONST64(0x38ddd870e53838e0), CONST64(0x8c148605988c8c0a),
408 CONST64(0xd1c6b2bf17d1d163), CONST64(0xa5410b57e4a5a5ae), CONST64(0xe2434dd9a1e2e2af), CONST64(0x612ff8c24e616199),
409 CONST64(0xb3f1457b42b3b3f6), CONST64(0x2115a54234212184), CONST64(0x9c94d625089c9c4a), CONST64(0x1ef0663cee1e1e78),
410 CONST64(0x4322528661434311), CONST64(0xc776fc93b1c7c73b), CONST64(0xfcb32be54ffcfcd7), CONST64(0x0420140824040410),
411 CONST64(0x51b208a2e3515159), CONST64(0x99bcc72f2599995e), CONST64(0x6d4fc4da226d6da9), CONST64(0x0d68391a650d0d34),
412 CONST64(0xfa8335e979fafacf), CONST64(0xdfb684a369dfdf5b), CONST64(0x7ed79bfca97e7ee5), CONST64(0x243db44819242490),
413 CONST64(0x3bc5d776fe3b3bec), CONST64(0xab313d4b9aabab96), CONST64(0xce3ed181f0cece1f), CONST64(0x1188552299111144),
414 CONST64(0x8f0c8903838f8f06), CONST64(0x4e4a6b9c044e4e25), CONST64(0xb7d1517366b7b7e6), CONST64(0xeb0b60cbe0ebeb8b),
415 CONST64(0x3cfdcc78c13c3cf0), CONST64(0x817cbf1ffd81813e), CONST64(0x94d4fe354094946a), CONST64(0xf7eb0cf31cf7f7fb),
416 CONST64(0xb9a1676f18b9b9de), CONST64(0x13985f268b13134c), CONST64(0x2c7d9c58512c2cb0), CONST64(0xd3d6b8bb05d3d36b),
417 CONST64(0xe76b5cd38ce7e7bb), CONST64(0x6e57cbdc396e6ea5), CONST64(0xc46ef395aac4c437), CONST64(0x03180f061b03030c),
418 CONST64(0x568a13acdc565645), CONST64(0x441a49885e44440d), CONST64(0x7fdf9efea07f7fe1), CONST64(0xa921374f88a9a99e),
419 CONST64(0x2a4d8254672a2aa8), CONST64(0xbbb16d6b0abbbbd6), CONST64(0xc146e29f87c1c123), CONST64(0x53a202a6f1535351),
420 CONST64(0xdcae8ba572dcdc57), CONST64(0x0b582716530b0b2c), CONST64(0x9d9cd327019d9d4e), CONST64(0x6c47c1d82b6c6cad),
421 CONST64(0x3195f562a43131c4), CONST64(0x7487b9e8f37474cd), CONST64(0xf6e309f115f6f6ff), CONST64(0x460a438c4c464605),
422 CONST64(0xac092645a5acac8a), CONST64(0x893c970fb589891e), CONST64(0x14a04428b4141450), CONST64(0xe15b42dfbae1e1a3),
423 CONST64(0x16b04e2ca6161658), CONST64(0x3acdd274f73a3ae8), CONST64(0x696fd0d2066969b9), CONST64(0x09482d1241090924),
424 CONST64(0x70a7ade0d77070dd), CONST64(0xb6d954716fb6b6e2), CONST64(0xd0ceb7bd1ed0d067), CONST64(0xed3b7ec7d6eded93),
425 CONST64(0xcc2edb85e2cccc17), CONST64(0x422a578468424215), CONST64(0x98b4c22d2c98985a), CONST64(0xa4490e55eda4a4aa),
426 CONST64(0x285d8850752828a0), CONST64(0x5cda31b8865c5c6d), CONST64(0xf8933fed6bf8f8c7), CONST64(0x8644a411c2868622)
427 };
428
429 static const ulong64 sbox6[] = {
430 CONST64(0x6018c07830d81818), CONST64(0x8c2305af46262323), CONST64(0x3fc67ef991b8c6c6), CONST64(0x87e8136fcdfbe8e8),
431 CONST64(0x26874ca113cb8787), CONST64(0xdab8a9626d11b8b8), CONST64(0x0401080502090101), CONST64(0x214f426e9e0d4f4f),
432 CONST64(0xd836adee6c9b3636), CONST64(0xa2a6590451ffa6a6), CONST64(0x6fd2debdb90cd2d2), CONST64(0xf3f5fb06f70ef5f5),
433 CONST64(0xf979ef80f2967979), CONST64(0xa16f5fcede306f6f), CONST64(0x7e91fcef3f6d9191), CONST64(0x5552aa07a4f85252),
434 CONST64(0x9d6027fdc0476060), CONST64(0xcabc89766535bcbc), CONST64(0x569baccd2b379b9b), CONST64(0x028e048c018a8e8e),
435 CONST64(0xb6a371155bd2a3a3), CONST64(0x300c603c186c0c0c), CONST64(0xf17bff8af6847b7b), CONST64(0xd435b5e16a803535),
436 CONST64(0x741de8693af51d1d), CONST64(0xa7e05347ddb3e0e0), CONST64(0x7bd7f6acb321d7d7), CONST64(0x2fc25eed999cc2c2),
437 CONST64(0xb82e6d965c432e2e), CONST64(0x314b627a96294b4b), CONST64(0xdffea321e15dfefe), CONST64(0x41578216aed55757),
438 CONST64(0x5415a8412abd1515), CONST64(0xc1779fb6eee87777), CONST64(0xdc37a5eb6e923737), CONST64(0xb3e57b56d79ee5e5),
439 CONST64(0x469f8cd923139f9f), CONST64(0xe7f0d317fd23f0f0), CONST64(0x354a6a7f94204a4a), CONST64(0x4fda9e95a944dada),
440 CONST64(0x7d58fa25b0a25858), CONST64(0x03c906ca8fcfc9c9), CONST64(0xa429558d527c2929), CONST64(0x280a5022145a0a0a),
441 CONST64(0xfeb1e14f7f50b1b1), CONST64(0xbaa0691a5dc9a0a0), CONST64(0xb16b7fdad6146b6b), CONST64(0x2e855cab17d98585),
442 CONST64(0xcebd8173673cbdbd), CONST64(0x695dd234ba8f5d5d), CONST64(0x4010805020901010), CONST64(0xf7f4f303f507f4f4),
443 CONST64(0x0bcb16c08bddcbcb), CONST64(0xf83eedc67cd33e3e), CONST64(0x140528110a2d0505), CONST64(0x81671fe6ce786767),
444 CONST64(0xb7e47353d597e4e4), CONST64(0x9c2725bb4e022727), CONST64(0x1941325882734141), CONST64(0x168b2c9d0ba78b8b),
445 CONST64(0xa6a7510153f6a7a7), CONST64(0xe97dcf94fab27d7d), CONST64(0x6e95dcfb37499595), CONST64(0x47d88e9fad56d8d8),
446 CONST64(0xcbfb8b30eb70fbfb), CONST64(0x9fee2371c1cdeeee), CONST64(0xed7cc791f8bb7c7c), CONST64(0x856617e3cc716666),
447 CONST64(0x53dda68ea77bdddd), CONST64(0x5c17b84b2eaf1717), CONST64(0x014702468e454747), CONST64(0x429e84dc211a9e9e),
448 CONST64(0x0fca1ec589d4caca), CONST64(0xb42d75995a582d2d), CONST64(0xc6bf9179632ebfbf), CONST64(0x1c07381b0e3f0707),
449 CONST64(0x8ead012347acadad), CONST64(0x755aea2fb4b05a5a), CONST64(0x36836cb51bef8383), CONST64(0xcc3385ff66b63333),
450 CONST64(0x91633ff2c65c6363), CONST64(0x0802100a04120202), CONST64(0x92aa39384993aaaa), CONST64(0xd971afa8e2de7171),
451 CONST64(0x07c80ecf8dc6c8c8), CONST64(0x6419c87d32d11919), CONST64(0x39497270923b4949), CONST64(0x43d9869aaf5fd9d9),
452 CONST64(0xeff2c31df931f2f2), CONST64(0xabe34b48dba8e3e3), CONST64(0x715be22ab6b95b5b), CONST64(0x1a8834920dbc8888),
453 CONST64(0x529aa4c8293e9a9a), CONST64(0x98262dbe4c0b2626), CONST64(0xc8328dfa64bf3232), CONST64(0xfab0e94a7d59b0b0),
454 CONST64(0x83e91b6acff2e9e9), CONST64(0x3c0f78331e770f0f), CONST64(0x73d5e6a6b733d5d5), CONST64(0x3a8074ba1df48080),
455 CONST64(0xc2be997c6127bebe), CONST64(0x13cd26de87ebcdcd), CONST64(0xd034bde468893434), CONST64(0x3d487a7590324848),
456 CONST64(0xdbffab24e354ffff), CONST64(0xf57af78ff48d7a7a), CONST64(0x7a90f4ea3d649090), CONST64(0x615fc23ebe9d5f5f),
457 CONST64(0x80201da0403d2020), CONST64(0xbd6867d5d00f6868), CONST64(0x681ad07234ca1a1a), CONST64(0x82ae192c41b7aeae),
458 CONST64(0xeab4c95e757db4b4), CONST64(0x4d549a19a8ce5454), CONST64(0x7693ece53b7f9393), CONST64(0x88220daa442f2222),
459 CONST64(0x8d6407e9c8636464), CONST64(0xe3f1db12ff2af1f1), CONST64(0xd173bfa2e6cc7373), CONST64(0x4812905a24821212),
460 CONST64(0x1d403a5d807a4040), CONST64(0x2008402810480808), CONST64(0x2bc356e89b95c3c3), CONST64(0x97ec337bc5dfecec),
461 CONST64(0x4bdb9690ab4ddbdb), CONST64(0xbea1611f5fc0a1a1), CONST64(0x0e8d1c8307918d8d), CONST64(0xf43df5c97ac83d3d),
462 CONST64(0x6697ccf1335b9797), CONST64(0x0000000000000000), CONST64(0x1bcf36d483f9cfcf), CONST64(0xac2b4587566e2b2b),
463 CONST64(0xc57697b3ece17676), CONST64(0x328264b019e68282), CONST64(0x7fd6fea9b128d6d6), CONST64(0x6c1bd87736c31b1b),
464 CONST64(0xeeb5c15b7774b5b5), CONST64(0x86af112943beafaf), CONST64(0xb56a77dfd41d6a6a), CONST64(0x5d50ba0da0ea5050),
465 CONST64(0x0945124c8a574545), CONST64(0xebf3cb18fb38f3f3), CONST64(0xc0309df060ad3030), CONST64(0x9bef2b74c3c4efef),
466 CONST64(0xfc3fe5c37eda3f3f), CONST64(0x4955921caac75555), CONST64(0xb2a2791059dba2a2), CONST64(0x8fea0365c9e9eaea),
467 CONST64(0x89650fecca6a6565), CONST64(0xd2bab9686903baba), CONST64(0xbc2f65935e4a2f2f), CONST64(0x27c04ee79d8ec0c0),
468 CONST64(0x5fdebe81a160dede), CONST64(0x701ce06c38fc1c1c), CONST64(0xd3fdbb2ee746fdfd), CONST64(0x294d52649a1f4d4d),
469 CONST64(0x7292e4e039769292), CONST64(0xc9758fbceafa7575), CONST64(0x1806301e0c360606), CONST64(0x128a249809ae8a8a),
470 CONST64(0xf2b2f940794bb2b2), CONST64(0xbfe66359d185e6e6), CONST64(0x380e70361c7e0e0e), CONST64(0x7c1ff8633ee71f1f),
471 CONST64(0x956237f7c4556262), CONST64(0x77d4eea3b53ad4d4), CONST64(0x9aa829324d81a8a8), CONST64(0x6296c4f431529696),
472 CONST64(0xc3f99b3aef62f9f9), CONST64(0x33c566f697a3c5c5), CONST64(0x942535b14a102525), CONST64(0x7959f220b2ab5959),
473 CONST64(0x2a8454ae15d08484), CONST64(0xd572b7a7e4c57272), CONST64(0xe439d5dd72ec3939), CONST64(0x2d4c5a6198164c4c),
474 CONST64(0x655eca3bbc945e5e), CONST64(0xfd78e785f09f7878), CONST64(0xe038ddd870e53838), CONST64(0x0a8c148605988c8c),
475 CONST64(0x63d1c6b2bf17d1d1), CONST64(0xaea5410b57e4a5a5), CONST64(0xafe2434dd9a1e2e2), CONST64(0x99612ff8c24e6161),
476 CONST64(0xf6b3f1457b42b3b3), CONST64(0x842115a542342121), CONST64(0x4a9c94d625089c9c), CONST64(0x781ef0663cee1e1e),
477 CONST64(0x1143225286614343), CONST64(0x3bc776fc93b1c7c7), CONST64(0xd7fcb32be54ffcfc), CONST64(0x1004201408240404),
478 CONST64(0x5951b208a2e35151), CONST64(0x5e99bcc72f259999), CONST64(0xa96d4fc4da226d6d), CONST64(0x340d68391a650d0d),
479 CONST64(0xcffa8335e979fafa), CONST64(0x5bdfb684a369dfdf), CONST64(0xe57ed79bfca97e7e), CONST64(0x90243db448192424),
480 CONST64(0xec3bc5d776fe3b3b), CONST64(0x96ab313d4b9aabab), CONST64(0x1fce3ed181f0cece), CONST64(0x4411885522991111),
481 CONST64(0x068f0c8903838f8f), CONST64(0x254e4a6b9c044e4e), CONST64(0xe6b7d1517366b7b7), CONST64(0x8beb0b60cbe0ebeb),
482 CONST64(0xf03cfdcc78c13c3c), CONST64(0x3e817cbf1ffd8181), CONST64(0x6a94d4fe35409494), CONST64(0xfbf7eb0cf31cf7f7),
483 CONST64(0xdeb9a1676f18b9b9), CONST64(0x4c13985f268b1313), CONST64(0xb02c7d9c58512c2c), CONST64(0x6bd3d6b8bb05d3d3),
484 CONST64(0xbbe76b5cd38ce7e7), CONST64(0xa56e57cbdc396e6e), CONST64(0x37c46ef395aac4c4), CONST64(0x0c03180f061b0303),
485 CONST64(0x45568a13acdc5656), CONST64(0x0d441a49885e4444), CONST64(0xe17fdf9efea07f7f), CONST64(0x9ea921374f88a9a9),
486 CONST64(0xa82a4d8254672a2a), CONST64(0xd6bbb16d6b0abbbb), CONST64(0x23c146e29f87c1c1), CONST64(0x5153a202a6f15353),
487 CONST64(0x57dcae8ba572dcdc), CONST64(0x2c0b582716530b0b), CONST64(0x4e9d9cd327019d9d), CONST64(0xad6c47c1d82b6c6c),
488 CONST64(0xc43195f562a43131), CONST64(0xcd7487b9e8f37474), CONST64(0xfff6e309f115f6f6), CONST64(0x05460a438c4c4646),
489 CONST64(0x8aac092645a5acac), CONST64(0x1e893c970fb58989), CONST64(0x5014a04428b41414), CONST64(0xa3e15b42dfbae1e1),
490 CONST64(0x5816b04e2ca61616), CONST64(0xe83acdd274f73a3a), CONST64(0xb9696fd0d2066969), CONST64(0x2409482d12410909),
491 CONST64(0xdd70a7ade0d77070), CONST64(0xe2b6d954716fb6b6), CONST64(0x67d0ceb7bd1ed0d0), CONST64(0x93ed3b7ec7d6eded),
492 CONST64(0x17cc2edb85e2cccc), CONST64(0x15422a5784684242), CONST64(0x5a98b4c22d2c9898), CONST64(0xaaa4490e55eda4a4),
493 CONST64(0xa0285d8850752828), CONST64(0x6d5cda31b8865c5c), CONST64(0xc7f8933fed6bf8f8), CONST64(0x228644a411c28686)
494 };
495
496 static const ulong64 sbox7[] = {
497 CONST64(0x186018c07830d818), CONST64(0x238c2305af462623), CONST64(0xc63fc67ef991b8c6), CONST64(0xe887e8136fcdfbe8),
498 CONST64(0x8726874ca113cb87), CONST64(0xb8dab8a9626d11b8), CONST64(0x0104010805020901), CONST64(0x4f214f426e9e0d4f),
499 CONST64(0x36d836adee6c9b36), CONST64(0xa6a2a6590451ffa6), CONST64(0xd26fd2debdb90cd2), CONST64(0xf5f3f5fb06f70ef5),
500 CONST64(0x79f979ef80f29679), CONST64(0x6fa16f5fcede306f), CONST64(0x917e91fcef3f6d91), CONST64(0x525552aa07a4f852),
501 CONST64(0x609d6027fdc04760), CONST64(0xbccabc89766535bc), CONST64(0x9b569baccd2b379b), CONST64(0x8e028e048c018a8e),
502 CONST64(0xa3b6a371155bd2a3), CONST64(0x0c300c603c186c0c), CONST64(0x7bf17bff8af6847b), CONST64(0x35d435b5e16a8035),
503 CONST64(0x1d741de8693af51d), CONST64(0xe0a7e05347ddb3e0), CONST64(0xd77bd7f6acb321d7), CONST64(0xc22fc25eed999cc2),
504 CONST64(0x2eb82e6d965c432e), CONST64(0x4b314b627a96294b), CONST64(0xfedffea321e15dfe), CONST64(0x5741578216aed557),
505 CONST64(0x155415a8412abd15), CONST64(0x77c1779fb6eee877), CONST64(0x37dc37a5eb6e9237), CONST64(0xe5b3e57b56d79ee5),
506 CONST64(0x9f469f8cd923139f), CONST64(0xf0e7f0d317fd23f0), CONST64(0x4a354a6a7f94204a), CONST64(0xda4fda9e95a944da),
507 CONST64(0x587d58fa25b0a258), CONST64(0xc903c906ca8fcfc9), CONST64(0x29a429558d527c29), CONST64(0x0a280a5022145a0a),
508 CONST64(0xb1feb1e14f7f50b1), CONST64(0xa0baa0691a5dc9a0), CONST64(0x6bb16b7fdad6146b), CONST64(0x852e855cab17d985),
509 CONST64(0xbdcebd8173673cbd), CONST64(0x5d695dd234ba8f5d), CONST64(0x1040108050209010), CONST64(0xf4f7f4f303f507f4),
510 CONST64(0xcb0bcb16c08bddcb), CONST64(0x3ef83eedc67cd33e), CONST64(0x05140528110a2d05), CONST64(0x6781671fe6ce7867),
511 CONST64(0xe4b7e47353d597e4), CONST64(0x279c2725bb4e0227), CONST64(0x4119413258827341), CONST64(0x8b168b2c9d0ba78b),
512 CONST64(0xa7a6a7510153f6a7), CONST64(0x7de97dcf94fab27d), CONST64(0x956e95dcfb374995), CONST64(0xd847d88e9fad56d8),
513 CONST64(0xfbcbfb8b30eb70fb), CONST64(0xee9fee2371c1cdee), CONST64(0x7ced7cc791f8bb7c), CONST64(0x66856617e3cc7166),
514 CONST64(0xdd53dda68ea77bdd), CONST64(0x175c17b84b2eaf17), CONST64(0x47014702468e4547), CONST64(0x9e429e84dc211a9e),
515 CONST64(0xca0fca1ec589d4ca), CONST64(0x2db42d75995a582d), CONST64(0xbfc6bf9179632ebf), CONST64(0x071c07381b0e3f07),
516 CONST64(0xad8ead012347acad), CONST64(0x5a755aea2fb4b05a), CONST64(0x8336836cb51bef83), CONST64(0x33cc3385ff66b633),
517 CONST64(0x6391633ff2c65c63), CONST64(0x020802100a041202), CONST64(0xaa92aa39384993aa), CONST64(0x71d971afa8e2de71),
518 CONST64(0xc807c80ecf8dc6c8), CONST64(0x196419c87d32d119), CONST64(0x4939497270923b49), CONST64(0xd943d9869aaf5fd9),
519 CONST64(0xf2eff2c31df931f2), CONST64(0xe3abe34b48dba8e3), CONST64(0x5b715be22ab6b95b), CONST64(0x881a8834920dbc88),
520 CONST64(0x9a529aa4c8293e9a), CONST64(0x2698262dbe4c0b26), CONST64(0x32c8328dfa64bf32), CONST64(0xb0fab0e94a7d59b0),
521 CONST64(0xe983e91b6acff2e9), CONST64(0x0f3c0f78331e770f), CONST64(0xd573d5e6a6b733d5), CONST64(0x803a8074ba1df480),
522 CONST64(0xbec2be997c6127be), CONST64(0xcd13cd26de87ebcd), CONST64(0x34d034bde4688934), CONST64(0x483d487a75903248),
523 CONST64(0xffdbffab24e354ff), CONST64(0x7af57af78ff48d7a), CONST64(0x907a90f4ea3d6490), CONST64(0x5f615fc23ebe9d5f),
524 CONST64(0x2080201da0403d20), CONST64(0x68bd6867d5d00f68), CONST64(0x1a681ad07234ca1a), CONST64(0xae82ae192c41b7ae),
525 CONST64(0xb4eab4c95e757db4), CONST64(0x544d549a19a8ce54), CONST64(0x937693ece53b7f93), CONST64(0x2288220daa442f22),
526 CONST64(0x648d6407e9c86364), CONST64(0xf1e3f1db12ff2af1), CONST64(0x73d173bfa2e6cc73), CONST64(0x124812905a248212),
527 CONST64(0x401d403a5d807a40), CONST64(0x0820084028104808), CONST64(0xc32bc356e89b95c3), CONST64(0xec97ec337bc5dfec),
528 CONST64(0xdb4bdb9690ab4ddb), CONST64(0xa1bea1611f5fc0a1), CONST64(0x8d0e8d1c8307918d), CONST64(0x3df43df5c97ac83d),
529 CONST64(0x976697ccf1335b97), CONST64(0x0000000000000000), CONST64(0xcf1bcf36d483f9cf), CONST64(0x2bac2b4587566e2b),
530 CONST64(0x76c57697b3ece176), CONST64(0x82328264b019e682), CONST64(0xd67fd6fea9b128d6), CONST64(0x1b6c1bd87736c31b),
531 CONST64(0xb5eeb5c15b7774b5), CONST64(0xaf86af112943beaf), CONST64(0x6ab56a77dfd41d6a), CONST64(0x505d50ba0da0ea50),
532 CONST64(0x450945124c8a5745), CONST64(0xf3ebf3cb18fb38f3), CONST64(0x30c0309df060ad30), CONST64(0xef9bef2b74c3c4ef),
533 CONST64(0x3ffc3fe5c37eda3f), CONST64(0x554955921caac755), CONST64(0xa2b2a2791059dba2), CONST64(0xea8fea0365c9e9ea),
534 CONST64(0x6589650fecca6a65), CONST64(0xbad2bab9686903ba), CONST64(0x2fbc2f65935e4a2f), CONST64(0xc027c04ee79d8ec0),
535 CONST64(0xde5fdebe81a160de), CONST64(0x1c701ce06c38fc1c), CONST64(0xfdd3fdbb2ee746fd), CONST64(0x4d294d52649a1f4d),
536 CONST64(0x927292e4e0397692), CONST64(0x75c9758fbceafa75), CONST64(0x061806301e0c3606), CONST64(0x8a128a249809ae8a),
537 CONST64(0xb2f2b2f940794bb2), CONST64(0xe6bfe66359d185e6), CONST64(0x0e380e70361c7e0e), CONST64(0x1f7c1ff8633ee71f),
538 CONST64(0x62956237f7c45562), CONST64(0xd477d4eea3b53ad4), CONST64(0xa89aa829324d81a8), CONST64(0x966296c4f4315296),
539 CONST64(0xf9c3f99b3aef62f9), CONST64(0xc533c566f697a3c5), CONST64(0x25942535b14a1025), CONST64(0x597959f220b2ab59),
540 CONST64(0x842a8454ae15d084), CONST64(0x72d572b7a7e4c572), CONST64(0x39e439d5dd72ec39), CONST64(0x4c2d4c5a6198164c),
541 CONST64(0x5e655eca3bbc945e), CONST64(0x78fd78e785f09f78), CONST64(0x38e038ddd870e538), CONST64(0x8c0a8c148605988c),
542 CONST64(0xd163d1c6b2bf17d1), CONST64(0xa5aea5410b57e4a5), CONST64(0xe2afe2434dd9a1e2), CONST64(0x6199612ff8c24e61),
543 CONST64(0xb3f6b3f1457b42b3), CONST64(0x21842115a5423421), CONST64(0x9c4a9c94d625089c), CONST64(0x1e781ef0663cee1e),
544 CONST64(0x4311432252866143), CONST64(0xc73bc776fc93b1c7), CONST64(0xfcd7fcb32be54ffc), CONST64(0x0410042014082404),
545 CONST64(0x515951b208a2e351), CONST64(0x995e99bcc72f2599), CONST64(0x6da96d4fc4da226d), CONST64(0x0d340d68391a650d),
546 CONST64(0xfacffa8335e979fa), CONST64(0xdf5bdfb684a369df), CONST64(0x7ee57ed79bfca97e), CONST64(0x2490243db4481924),
547 CONST64(0x3bec3bc5d776fe3b), CONST64(0xab96ab313d4b9aab), CONST64(0xce1fce3ed181f0ce), CONST64(0x1144118855229911),
548 CONST64(0x8f068f0c8903838f), CONST64(0x4e254e4a6b9c044e), CONST64(0xb7e6b7d1517366b7), CONST64(0xeb8beb0b60cbe0eb),
549 CONST64(0x3cf03cfdcc78c13c), CONST64(0x813e817cbf1ffd81), CONST64(0x946a94d4fe354094), CONST64(0xf7fbf7eb0cf31cf7),
550 CONST64(0xb9deb9a1676f18b9), CONST64(0x134c13985f268b13), CONST64(0x2cb02c7d9c58512c), CONST64(0xd36bd3d6b8bb05d3),
551 CONST64(0xe7bbe76b5cd38ce7), CONST64(0x6ea56e57cbdc396e), CONST64(0xc437c46ef395aac4), CONST64(0x030c03180f061b03),
552 CONST64(0x5645568a13acdc56), CONST64(0x440d441a49885e44), CONST64(0x7fe17fdf9efea07f), CONST64(0xa99ea921374f88a9),
553 CONST64(0x2aa82a4d8254672a), CONST64(0xbbd6bbb16d6b0abb), CONST64(0xc123c146e29f87c1), CONST64(0x535153a202a6f153),
554 CONST64(0xdc57dcae8ba572dc), CONST64(0x0b2c0b582716530b), CONST64(0x9d4e9d9cd327019d), CONST64(0x6cad6c47c1d82b6c),
555 CONST64(0x31c43195f562a431), CONST64(0x74cd7487b9e8f374), CONST64(0xf6fff6e309f115f6), CONST64(0x4605460a438c4c46),
556 CONST64(0xac8aac092645a5ac), CONST64(0x891e893c970fb589), CONST64(0x145014a04428b414), CONST64(0xe1a3e15b42dfbae1),
557 CONST64(0x165816b04e2ca616), CONST64(0x3ae83acdd274f73a), CONST64(0x69b9696fd0d20669), CONST64(0x092409482d124109),
558 CONST64(0x70dd70a7ade0d770), CONST64(0xb6e2b6d954716fb6), CONST64(0xd067d0ceb7bd1ed0), CONST64(0xed93ed3b7ec7d6ed),
559 CONST64(0xcc17cc2edb85e2cc), CONST64(0x4215422a57846842), CONST64(0x985a98b4c22d2c98), CONST64(0xa4aaa4490e55eda4),
560 CONST64(0x28a0285d88507528), CONST64(0x5c6d5cda31b8865c), CONST64(0xf8c7f8933fed6bf8), CONST64(0x86228644a411c286)
561 };
562
563 #endif
564
565 static const ulong64 cont[] = {
566 CONST64(0x1823c6e887b8014f),
567 CONST64(0x36a6d2f5796f9152),
568 CONST64(0x60bc9b8ea30c7b35),
569 CONST64(0x1de0d7c22e4bfe57),
570 CONST64(0x157737e59ff04ada),
571 CONST64(0x58c9290ab1a06b85),
572 CONST64(0xbd5d10f4cb3e0567),
573 CONST64(0xe427418ba77d95d8),
574 CONST64(0xfbee7c66dd17479e),
575 CONST64(0xca2dbf07ad5a8333),
576 CONST64(0x6302aa71c81949d9),
577 };
578
579
580 /* $Source$ */
581 /* $Revision$ */
582 /* $Date$ */
+0
-89
libtom-src/headers/tomcrypt.h less more
0 #ifndef TOMCRYPT_H_
1 #define TOMCRYPT_H_
2 #include <assert.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <stddef.h>
7 #include <time.h>
8 #include <ctype.h>
9 #include <limits.h>
10
11 /* use configuration data */
12 #include <tomcrypt_custom.h>
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 /* version */
19 #define CRYPT 0x0117
20 #define SCRYPT "1.17"
21
22 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
23 #define MAXBLOCKSIZE 128
24
25 /* descriptor table size */
26 #define TAB_SIZE 32
27
28 /* error codes [will be expanded in future releases] */
29 enum {
30 CRYPT_OK=0, /* Result OK */
31 CRYPT_ERROR, /* Generic Error */
32 CRYPT_NOP, /* Not a failure but no operation was performed */
33
34 CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
35 CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */
36 CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */
37
38 CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */
39 CRYPT_INVALID_PACKET, /* Invalid input packet given */
40
41 CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
42 CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */
43
44 CRYPT_INVALID_CIPHER, /* Invalid cipher specified */
45 CRYPT_INVALID_HASH, /* Invalid hash specified */
46 CRYPT_INVALID_PRNG, /* Invalid PRNG specified */
47
48 CRYPT_MEM, /* Out of memory */
49
50 CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
51 CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */
52
53 CRYPT_INVALID_ARG, /* Generic invalid argument */
54 CRYPT_FILE_NOTFOUND, /* File Not Found */
55
56 CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */
57 CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */
58 CRYPT_PK_DUP, /* Duplicate key already in key ring */
59 CRYPT_PK_NOT_FOUND, /* Key not found in keyring */
60 CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */
61
62 CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
63 CRYPT_PK_INVALID_PADDING /* Invalid padding on input */
64 };
65
66 #include <tomcrypt_cfg.h>
67 #include <tomcrypt_macros.h>
68 #include <tomcrypt_cipher.h>
69 #include <tomcrypt_hash.h>
70 #include <tomcrypt_mac.h>
71 #include <tomcrypt_prng.h>
72 #include <tomcrypt_pk.h>
73 #include <tomcrypt_math.h>
74 #include <tomcrypt_misc.h>
75 #include <tomcrypt_argchk.h>
76 #include <tomcrypt_pkcs.h>
77 #include <tomcrypt_hkdf.h>
78
79 #ifdef __cplusplus
80 }
81 #endif
82
83 #endif /* TOMCRYPT_H_ */
84
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
+0
-38
libtom-src/headers/tomcrypt_argchk.h less more
0 /* Defines the LTC_ARGCHK macro used within the library */
1 /* ARGTYPE is defined in mycrypt_cfg.h */
2 #if ARGTYPE == 0
3
4 #include <signal.h>
5
6 /* this is the default LibTomCrypt macro */
7 void crypt_argchk(char *v, char *s, int d);
8 #define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); }
9 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
10
11 #elif ARGTYPE == 1
12
13 /* fatal type of error */
14 #define LTC_ARGCHK(x) assert((x))
15 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
16
17 #elif ARGTYPE == 2
18
19 #define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); }
20 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
21
22 #elif ARGTYPE == 3
23
24 #define LTC_ARGCHK(x)
25 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
26
27 #elif ARGTYPE == 4
28
29 #define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG;
30 #define LTC_ARGCHKVD(x) if (!(x)) return;
31
32 #endif
33
34
35 /* $Source$ */
36 /* $Revision$ */
37 /* $Date$ */
+0
-160
libtom-src/headers/tomcrypt_cfg.h less more
0 /* This is the build config file.
1 *
2 * With this you can setup what to inlcude/exclude automatically during any build. Just comment
3 * out the line that #define's the word for the thing you want to remove. phew!
4 */
5
6 #ifndef TOMCRYPT_CFG_H
7 #define TOMCRYPT_CFG_H
8
9 #if defined(_WIN32) || defined(_MSC_VER)
10 #define LTC_CALL __cdecl
11 #else
12 #ifndef LTC_CALL
13 #define LTC_CALL
14 #endif
15 #endif
16
17 #ifndef LTC_EXPORT
18 #define LTC_EXPORT
19 #endif
20
21 /* certain platforms use macros for these, making the prototypes broken */
22 #ifndef LTC_NO_PROTOTYPES
23
24 /* you can change how memory allocation works ... */
25 LTC_EXPORT void * LTC_CALL XMALLOC(size_t n);
26 LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n);
27 LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s);
28 LTC_EXPORT void LTC_CALL XFREE(void *p);
29
30 LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
31
32
33 /* change the clock function too */
34 LTC_EXPORT clock_t LTC_CALL XCLOCK(void);
35
36 /* various other functions */
37 LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n);
38 LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n);
39 LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n);
40
41 LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
42
43 #endif
44
45 /* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */
46 #ifndef ARGTYPE
47 #define ARGTYPE 0
48 #endif
49
50 /* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code
51 *
52 * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes.
53 * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST**
54 * use the portable [slower] macros.
55 */
56
57 /* detect x86-32 machines somewhat */
58 #if !defined(__STRICT_ANSI__) && !defined(_WIN64) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))))
59 #define ENDIAN_LITTLE
60 #define ENDIAN_32BITWORD
61 #define LTC_FAST
62 #define LTC_FAST_TYPE unsigned long
63 #endif
64
65 /* detects MIPS R5900 processors (PS2) */
66 #if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips))
67 #define ENDIAN_LITTLE
68 #define ENDIAN_64BITWORD
69 #endif
70
71 /* detect amd64 */
72 #ifdef _WIN64
73 #define ENDIAN_LITTLE
74 #define ENDIAN_64BITWORD
75 #define LTC_FAST
76 /* on 64bit ms windows 'unsigned long' is only 32bit we need 'long long'*/
77 #define LTC_FAST_TYPE unsigned long long
78 #else
79 #if !defined(__STRICT_ANSI__) && defined(__x86_64__)
80 #define ENDIAN_LITTLE
81 #define ENDIAN_64BITWORD
82 #define LTC_FAST
83 #define LTC_FAST_TYPE unsigned long
84 #endif
85 #endif
86
87 /* detect PPC32 */
88 #if !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
89 #define ENDIAN_BIG
90 #define ENDIAN_32BITWORD
91 #define LTC_FAST
92 #define LTC_FAST_TYPE unsigned long
93 #endif
94
95 /* detect sparc and sparc64 */
96 #if defined(__sparc__)
97 #define ENDIAN_BIG
98 #if defined(__arch64__)
99 #define ENDIAN_64BITWORD
100 #else
101 #define ENDIAN_32BITWORD
102 #endif
103 #endif
104
105
106 #ifdef LTC_NO_FAST
107 #ifdef LTC_FAST
108 #undef LTC_FAST
109 #endif
110 #endif
111
112 /* No asm is a quick way to disable anything "not portable" */
113 #ifdef LTC_NO_ASM
114 #undef ENDIAN_LITTLE
115 #undef ENDIAN_BIG
116 #undef ENDIAN_32BITWORD
117 #undef ENDIAN_64BITWORD
118 #undef LTC_FAST
119 #undef LTC_FAST_TYPE
120 #define LTC_NO_ROLC
121 #define LTC_NO_BSWAP
122 #endif
123
124 /* #define ENDIAN_LITTLE */
125 /* #define ENDIAN_BIG */
126
127 /* #define ENDIAN_32BITWORD */
128 /* #define ENDIAN_64BITWORD */
129
130 #if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
131 #error You must specify a word size as well as endianess in tomcrypt_cfg.h
132 #endif
133
134 #if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
135 #define ENDIAN_NEUTRAL
136 #endif
137
138 /* gcc 4.3 and up has a bswap builtin; detect it by gcc version.
139 * clang also supports the bswap builtin, and although clang pretends
140 * to be gcc (macro-wise, anyway), clang pretends to be a version
141 * prior to gcc 4.3, so we can't detect bswap that way. Instead,
142 * clang has a __has_builtin mechanism that can be used to check
143 * for builtins:
144 * http://clang.llvm.org/docs/LanguageExtensions.html#feature_check */
145 #ifndef __has_builtin
146 #define __has_builtin(x) 0
147 #endif
148 #if !defined(LTC_NO_BSWAP) && defined(__GNUC__) && \
149 ((__GNUC__ * 100 + __GNUC_MINOR__ >= 403) || \
150 (__has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)))
151 #define LTC_HAVE_BSWAP_BUILTIN
152 #endif
153
154 #endif
155
156
157 /* $Source$ */
158 /* $Revision$ */
159 /* $Date$ */
+0
-911
libtom-src/headers/tomcrypt_cipher.h less more
0 /* ---- SYMMETRIC KEY STUFF -----
1 *
2 * We put each of the ciphers scheduled keys in their own structs then we put all of
3 * the key formats in one union. This makes the function prototypes easier to use.
4 */
5 #ifdef LTC_BLOWFISH
6 struct blowfish_key {
7 ulong32 S[4][256];
8 ulong32 K[18];
9 };
10 #endif
11
12 #ifdef LTC_RC5
13 struct rc5_key {
14 int rounds;
15 ulong32 K[50];
16 };
17 #endif
18
19 #ifdef LTC_RC6
20 struct rc6_key {
21 ulong32 K[44];
22 };
23 #endif
24
25 #ifdef LTC_SAFERP
26 struct saferp_key {
27 unsigned char K[33][16];
28 long rounds;
29 };
30 #endif
31
32 #ifdef LTC_RIJNDAEL
33 struct rijndael_key {
34 ulong32 eK[60], dK[60];
35 int Nr;
36 };
37 #endif
38
39 #ifdef LTC_KSEED
40 struct kseed_key {
41 ulong32 K[32], dK[32];
42 };
43 #endif
44
45 #ifdef LTC_KASUMI
46 struct kasumi_key {
47 ulong32 KLi1[8], KLi2[8],
48 KOi1[8], KOi2[8], KOi3[8],
49 KIi1[8], KIi2[8], KIi3[8];
50 };
51 #endif
52
53 #ifdef LTC_XTEA
54 struct xtea_key {
55 unsigned long A[32], B[32];
56 };
57 #endif
58
59 #ifdef LTC_TWOFISH
60 #ifndef LTC_TWOFISH_SMALL
61 struct twofish_key {
62 ulong32 S[4][256], K[40];
63 };
64 #else
65 struct twofish_key {
66 ulong32 K[40];
67 unsigned char S[32], start;
68 };
69 #endif
70 #endif
71
72 #ifdef LTC_SAFER
73 #define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6
74 #define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10
75 #define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8
76 #define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10
77 #define LTC_SAFER_MAX_NOF_ROUNDS 13
78 #define LTC_SAFER_BLOCK_LEN 8
79 #define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS))
80 typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN];
81 typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN];
82 struct safer_key { safer_key_t key; };
83 #endif
84
85 #ifdef LTC_RC2
86 struct rc2_key { unsigned xkey[64]; };
87 #endif
88
89 #ifdef LTC_DES
90 struct des_key {
91 ulong32 ek[32], dk[32];
92 };
93
94 struct des3_key {
95 ulong32 ek[3][32], dk[3][32];
96 };
97 #endif
98
99 #ifdef LTC_CAST5
100 struct cast5_key {
101 ulong32 K[32], keylen;
102 };
103 #endif
104
105 #ifdef LTC_NOEKEON
106 struct noekeon_key {
107 ulong32 K[4], dK[4];
108 };
109 #endif
110
111 #ifdef LTC_SKIPJACK
112 struct skipjack_key {
113 unsigned char key[10];
114 };
115 #endif
116
117 #ifdef LTC_KHAZAD
118 struct khazad_key {
119 ulong64 roundKeyEnc[8 + 1];
120 ulong64 roundKeyDec[8 + 1];
121 };
122 #endif
123
124 #ifdef LTC_ANUBIS
125 struct anubis_key {
126 int keyBits;
127 int R;
128 ulong32 roundKeyEnc[18 + 1][4];
129 ulong32 roundKeyDec[18 + 1][4];
130 };
131 #endif
132
133 #ifdef LTC_MULTI2
134 struct multi2_key {
135 int N;
136 ulong32 uk[8];
137 };
138 #endif
139
140 #ifdef LTC_CAMELLIA
141 struct camellia_key {
142 int R;
143 ulong64 kw[4], k[24], kl[6];
144 };
145 #endif
146
147 typedef union Symmetric_key {
148 #ifdef LTC_DES
149 struct des_key des;
150 struct des3_key des3;
151 #endif
152 #ifdef LTC_RC2
153 struct rc2_key rc2;
154 #endif
155 #ifdef LTC_SAFER
156 struct safer_key safer;
157 #endif
158 #ifdef LTC_TWOFISH
159 struct twofish_key twofish;
160 #endif
161 #ifdef LTC_BLOWFISH
162 struct blowfish_key blowfish;
163 #endif
164 #ifdef LTC_RC5
165 struct rc5_key rc5;
166 #endif
167 #ifdef LTC_RC6
168 struct rc6_key rc6;
169 #endif
170 #ifdef LTC_SAFERP
171 struct saferp_key saferp;
172 #endif
173 #ifdef LTC_RIJNDAEL
174 struct rijndael_key rijndael;
175 #endif
176 #ifdef LTC_XTEA
177 struct xtea_key xtea;
178 #endif
179 #ifdef LTC_CAST5
180 struct cast5_key cast5;
181 #endif
182 #ifdef LTC_NOEKEON
183 struct noekeon_key noekeon;
184 #endif
185 #ifdef LTC_SKIPJACK
186 struct skipjack_key skipjack;
187 #endif
188 #ifdef LTC_KHAZAD
189 struct khazad_key khazad;
190 #endif
191 #ifdef LTC_ANUBIS
192 struct anubis_key anubis;
193 #endif
194 #ifdef LTC_KSEED
195 struct kseed_key kseed;
196 #endif
197 #ifdef LTC_KASUMI
198 struct kasumi_key kasumi;
199 #endif
200 #ifdef LTC_MULTI2
201 struct multi2_key multi2;
202 #endif
203 #ifdef LTC_CAMELLIA
204 struct camellia_key camellia;
205 #endif
206 void *data;
207 } symmetric_key;
208
209 #ifdef LTC_ECB_MODE
210 /** A block cipher ECB structure */
211 typedef struct {
212 /** The index of the cipher chosen */
213 int cipher,
214 /** The block size of the given cipher */
215 blocklen;
216 /** The scheduled key */
217 symmetric_key key;
218 } symmetric_ECB;
219 #endif
220
221 #ifdef LTC_CFB_MODE
222 /** A block cipher CFB structure */
223 typedef struct {
224 /** The index of the cipher chosen */
225 int cipher,
226 /** The block size of the given cipher */
227 blocklen,
228 /** The padding offset */
229 padlen;
230 /** The current IV */
231 unsigned char IV[MAXBLOCKSIZE],
232 /** The pad used to encrypt/decrypt */
233 pad[MAXBLOCKSIZE];
234 /** The scheduled key */
235 symmetric_key key;
236 } symmetric_CFB;
237 #endif
238
239 #ifdef LTC_OFB_MODE
240 /** A block cipher OFB structure */
241 typedef struct {
242 /** The index of the cipher chosen */
243 int cipher,
244 /** The block size of the given cipher */
245 blocklen,
246 /** The padding offset */
247 padlen;
248 /** The current IV */
249 unsigned char IV[MAXBLOCKSIZE];
250 /** The scheduled key */
251 symmetric_key key;
252 } symmetric_OFB;
253 #endif
254
255 #ifdef LTC_CBC_MODE
256 /** A block cipher CBC structure */
257 typedef struct {
258 /** The index of the cipher chosen */
259 int cipher,
260 /** The block size of the given cipher */
261 blocklen;
262 /** The current IV */
263 unsigned char IV[MAXBLOCKSIZE];
264 /** The scheduled key */
265 symmetric_key key;
266 } symmetric_CBC;
267 #endif
268
269
270 #ifdef LTC_CTR_MODE
271 /** A block cipher CTR structure */
272 typedef struct {
273 /** The index of the cipher chosen */
274 int cipher,
275 /** The block size of the given cipher */
276 blocklen,
277 /** The padding offset */
278 padlen,
279 /** The mode (endianess) of the CTR, 0==little, 1==big */
280 mode,
281 /** counter width */
282 ctrlen;
283
284 /** The counter */
285 unsigned char ctr[MAXBLOCKSIZE],
286 /** The pad used to encrypt/decrypt */
287 pad[MAXBLOCKSIZE];
288 /** The scheduled key */
289 symmetric_key key;
290 } symmetric_CTR;
291 #endif
292
293
294 #ifdef LTC_LRW_MODE
295 /** A LRW structure */
296 typedef struct {
297 /** The index of the cipher chosen (must be a 128-bit block cipher) */
298 int cipher;
299
300 /** The current IV */
301 unsigned char IV[16],
302
303 /** the tweak key */
304 tweak[16],
305
306 /** The current pad, it's the product of the first 15 bytes against the tweak key */
307 pad[16];
308
309 /** The scheduled symmetric key */
310 symmetric_key key;
311
312 #ifdef LRW_TABLES
313 /** The pre-computed multiplication table */
314 unsigned char PC[16][256][16];
315 #endif
316 } symmetric_LRW;
317 #endif
318
319 #ifdef LTC_F8_MODE
320 /** A block cipher F8 structure */
321 typedef struct {
322 /** The index of the cipher chosen */
323 int cipher,
324 /** The block size of the given cipher */
325 blocklen,
326 /** The padding offset */
327 padlen;
328 /** The current IV */
329 unsigned char IV[MAXBLOCKSIZE],
330 MIV[MAXBLOCKSIZE];
331 /** Current block count */
332 ulong32 blockcnt;
333 /** The scheduled key */
334 symmetric_key key;
335 } symmetric_F8;
336 #endif
337
338
339 /** cipher descriptor table, last entry has "name == NULL" to mark the end of table */
340 extern struct ltc_cipher_descriptor {
341 /** name of cipher */
342 char *name;
343 /** internal ID */
344 unsigned char ID;
345 /** min keysize (octets) */
346 int min_key_length,
347 /** max keysize (octets) */
348 max_key_length,
349 /** block size (octets) */
350 block_length,
351 /** default number of rounds */
352 default_rounds;
353 /** Setup the cipher
354 @param key The input symmetric key
355 @param keylen The length of the input key (octets)
356 @param num_rounds The requested number of rounds (0==default)
357 @param skey [out] The destination of the scheduled key
358 @return CRYPT_OK if successful
359 */
360 int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
361 /** Encrypt a block
362 @param pt The plaintext
363 @param ct [out] The ciphertext
364 @param skey The scheduled key
365 @return CRYPT_OK if successful
366 */
367 int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
368 /** Decrypt a block
369 @param ct The ciphertext
370 @param pt [out] The plaintext
371 @param skey The scheduled key
372 @return CRYPT_OK if successful
373 */
374 int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
375 /** Test the block cipher
376 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
377 */
378 int (*test)(void);
379
380 /** Terminate the context
381 @param skey The scheduled key
382 */
383 void (*done)(symmetric_key *skey);
384
385 /** Determine a key size
386 @param keysize [in/out] The size of the key desired and the suggested size
387 @return CRYPT_OK if successful
388 */
389 int (*keysize)(int *keysize);
390
391 /** Accelerators **/
392 /** Accelerated ECB encryption
393 @param pt Plaintext
394 @param ct Ciphertext
395 @param blocks The number of complete blocks to process
396 @param skey The scheduled key context
397 @return CRYPT_OK if successful
398 */
399 int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
400
401 /** Accelerated ECB decryption
402 @param pt Plaintext
403 @param ct Ciphertext
404 @param blocks The number of complete blocks to process
405 @param skey The scheduled key context
406 @return CRYPT_OK if successful
407 */
408 int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
409
410 /** Accelerated CBC encryption
411 @param pt Plaintext
412 @param ct Ciphertext
413 @param blocks The number of complete blocks to process
414 @param IV The initial value (input/output)
415 @param skey The scheduled key context
416 @return CRYPT_OK if successful
417 */
418 int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
419
420 /** Accelerated CBC decryption
421 @param pt Plaintext
422 @param ct Ciphertext
423 @param blocks The number of complete blocks to process
424 @param IV The initial value (input/output)
425 @param skey The scheduled key context
426 @return CRYPT_OK if successful
427 */
428 int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
429
430 /** Accelerated CTR encryption
431 @param pt Plaintext
432 @param ct Ciphertext
433 @param blocks The number of complete blocks to process
434 @param IV The initial value (input/output)
435 @param mode little or big endian counter (mode=0 or mode=1)
436 @param skey The scheduled key context
437 @return CRYPT_OK if successful
438 */
439 int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
440
441 /** Accelerated LRW
442 @param pt Plaintext
443 @param ct Ciphertext
444 @param blocks The number of complete blocks to process
445 @param IV The initial value (input/output)
446 @param tweak The LRW tweak
447 @param skey The scheduled key context
448 @return CRYPT_OK if successful
449 */
450 int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
451
452 /** Accelerated LRW
453 @param ct Ciphertext
454 @param pt Plaintext
455 @param blocks The number of complete blocks to process
456 @param IV The initial value (input/output)
457 @param tweak The LRW tweak
458 @param skey The scheduled key context
459 @return CRYPT_OK if successful
460 */
461 int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
462
463 /** Accelerated CCM packet (one-shot)
464 @param key The secret key to use
465 @param keylen The length of the secret key (octets)
466 @param uskey A previously scheduled key [optional can be NULL]
467 @param nonce The session nonce [use once]
468 @param noncelen The length of the nonce
469 @param header The header for the session
470 @param headerlen The length of the header (octets)
471 @param pt [out] The plaintext
472 @param ptlen The length of the plaintext (octets)
473 @param ct [out] The ciphertext
474 @param tag [out] The destination tag
475 @param taglen [in/out] The max size and resulting size of the authentication tag
476 @param direction Encrypt or Decrypt direction (0 or 1)
477 @return CRYPT_OK if successful
478 */
479 int (*accel_ccm_memory)(
480 const unsigned char *key, unsigned long keylen,
481 symmetric_key *uskey,
482 const unsigned char *nonce, unsigned long noncelen,
483 const unsigned char *header, unsigned long headerlen,
484 unsigned char *pt, unsigned long ptlen,
485 unsigned char *ct,
486 unsigned char *tag, unsigned long *taglen,
487 int direction);
488
489 /** Accelerated GCM packet (one shot)
490 @param key The secret key
491 @param keylen The length of the secret key
492 @param IV The initial vector
493 @param IVlen The length of the initial vector
494 @param adata The additional authentication data (header)
495 @param adatalen The length of the adata
496 @param pt The plaintext
497 @param ptlen The length of the plaintext (ciphertext length is the same)
498 @param ct The ciphertext
499 @param tag [out] The MAC tag
500 @param taglen [in/out] The MAC tag length
501 @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
502 @return CRYPT_OK on success
503 */
504 int (*accel_gcm_memory)(
505 const unsigned char *key, unsigned long keylen,
506 const unsigned char *IV, unsigned long IVlen,
507 const unsigned char *adata, unsigned long adatalen,
508 unsigned char *pt, unsigned long ptlen,
509 unsigned char *ct,
510 unsigned char *tag, unsigned long *taglen,
511 int direction);
512
513 /** Accelerated one shot LTC_OMAC
514 @param key The secret key
515 @param keylen The key length (octets)
516 @param in The message
517 @param inlen Length of message (octets)
518 @param out [out] Destination for tag
519 @param outlen [in/out] Initial and final size of out
520 @return CRYPT_OK on success
521 */
522 int (*omac_memory)(
523 const unsigned char *key, unsigned long keylen,
524 const unsigned char *in, unsigned long inlen,
525 unsigned char *out, unsigned long *outlen);
526
527 /** Accelerated one shot XCBC
528 @param key The secret key
529 @param keylen The key length (octets)
530 @param in The message
531 @param inlen Length of message (octets)
532 @param out [out] Destination for tag
533 @param outlen [in/out] Initial and final size of out
534 @return CRYPT_OK on success
535 */
536 int (*xcbc_memory)(
537 const unsigned char *key, unsigned long keylen,
538 const unsigned char *in, unsigned long inlen,
539 unsigned char *out, unsigned long *outlen);
540
541 /** Accelerated one shot F9
542 @param key The secret key
543 @param keylen The key length (octets)
544 @param in The message
545 @param inlen Length of message (octets)
546 @param out [out] Destination for tag
547 @param outlen [in/out] Initial and final size of out
548 @return CRYPT_OK on success
549 @remark Requires manual padding
550 */
551 int (*f9_memory)(
552 const unsigned char *key, unsigned long keylen,
553 const unsigned char *in, unsigned long inlen,
554 unsigned char *out, unsigned long *outlen);
555 } cipher_descriptor[];
556
557 #ifdef LTC_BLOWFISH
558 int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
559 int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
560 int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
561 int blowfish_test(void);
562 void blowfish_done(symmetric_key *skey);
563 int blowfish_keysize(int *keysize);
564 extern const struct ltc_cipher_descriptor blowfish_desc;
565 #endif
566
567 #ifdef LTC_RC5
568 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
569 int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
570 int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
571 int rc5_test(void);
572 void rc5_done(symmetric_key *skey);
573 int rc5_keysize(int *keysize);
574 extern const struct ltc_cipher_descriptor rc5_desc;
575 #endif
576
577 #ifdef LTC_RC6
578 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
579 int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
580 int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
581 int rc6_test(void);
582 void rc6_done(symmetric_key *skey);
583 int rc6_keysize(int *keysize);
584 extern const struct ltc_cipher_descriptor rc6_desc;
585 #endif
586
587 #ifdef LTC_RC2
588 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
589 int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
590 int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
591 int rc2_test(void);
592 void rc2_done(symmetric_key *skey);
593 int rc2_keysize(int *keysize);
594 extern const struct ltc_cipher_descriptor rc2_desc;
595 #endif
596
597 #ifdef LTC_SAFERP
598 int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
599 int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
600 int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
601 int saferp_test(void);
602 void saferp_done(symmetric_key *skey);
603 int saferp_keysize(int *keysize);
604 extern const struct ltc_cipher_descriptor saferp_desc;
605 #endif
606
607 #ifdef LTC_SAFER
608 int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
609 int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
610 int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
611 int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
612 int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
613 int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
614 int safer_k64_test(void);
615 int safer_sk64_test(void);
616 int safer_sk128_test(void);
617 void safer_done(symmetric_key *skey);
618 int safer_64_keysize(int *keysize);
619 int safer_128_keysize(int *keysize);
620 extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc;
621 #endif
622
623 #ifdef LTC_RIJNDAEL
624
625 /* make aes an alias */
626 #define aes_setup rijndael_setup
627 #define aes_ecb_encrypt rijndael_ecb_encrypt
628 #define aes_ecb_decrypt rijndael_ecb_decrypt
629 #define aes_test rijndael_test
630 #define aes_done rijndael_done
631 #define aes_keysize rijndael_keysize
632
633 #define aes_enc_setup rijndael_enc_setup
634 #define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt
635 #define aes_enc_keysize rijndael_enc_keysize
636
637 int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
638 int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
639 int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
640 int rijndael_test(void);
641 void rijndael_done(symmetric_key *skey);
642 int rijndael_keysize(int *keysize);
643 int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
644 int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
645 void rijndael_enc_done(symmetric_key *skey);
646 int rijndael_enc_keysize(int *keysize);
647 extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
648 extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
649 #endif
650
651 #ifdef LTC_XTEA
652 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
653 int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
654 int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
655 int xtea_test(void);
656 void xtea_done(symmetric_key *skey);
657 int xtea_keysize(int *keysize);
658 extern const struct ltc_cipher_descriptor xtea_desc;
659 #endif
660
661 #ifdef LTC_TWOFISH
662 int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
663 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
664 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
665 int twofish_test(void);
666 void twofish_done(symmetric_key *skey);
667 int twofish_keysize(int *keysize);
668 extern const struct ltc_cipher_descriptor twofish_desc;
669 #endif
670
671 #ifdef LTC_DES
672 int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
673 int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
674 int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
675 int des_test(void);
676 void des_done(symmetric_key *skey);
677 int des_keysize(int *keysize);
678 int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
679 int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
680 int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
681 int des3_test(void);
682 void des3_done(symmetric_key *skey);
683 int des3_keysize(int *keysize);
684 extern const struct ltc_cipher_descriptor des_desc, des3_desc;
685 #endif
686
687 #ifdef LTC_CAST5
688 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
689 int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
690 int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
691 int cast5_test(void);
692 void cast5_done(symmetric_key *skey);
693 int cast5_keysize(int *keysize);
694 extern const struct ltc_cipher_descriptor cast5_desc;
695 #endif
696
697 #ifdef LTC_NOEKEON
698 int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
699 int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
700 int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
701 int noekeon_test(void);
702 void noekeon_done(symmetric_key *skey);
703 int noekeon_keysize(int *keysize);
704 extern const struct ltc_cipher_descriptor noekeon_desc;
705 #endif
706
707 #ifdef LTC_SKIPJACK
708 int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
709 int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
710 int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
711 int skipjack_test(void);
712 void skipjack_done(symmetric_key *skey);
713 int skipjack_keysize(int *keysize);
714 extern const struct ltc_cipher_descriptor skipjack_desc;
715 #endif
716
717 #ifdef LTC_KHAZAD
718 int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
719 int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
720 int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
721 int khazad_test(void);
722 void khazad_done(symmetric_key *skey);
723 int khazad_keysize(int *keysize);
724 extern const struct ltc_cipher_descriptor khazad_desc;
725 #endif
726
727 #ifdef LTC_ANUBIS
728 int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
729 int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
730 int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
731 int anubis_test(void);
732 void anubis_done(symmetric_key *skey);
733 int anubis_keysize(int *keysize);
734 extern const struct ltc_cipher_descriptor anubis_desc;
735 #endif
736
737 #ifdef LTC_KSEED
738 int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
739 int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
740 int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
741 int kseed_test(void);
742 void kseed_done(symmetric_key *skey);
743 int kseed_keysize(int *keysize);
744 extern const struct ltc_cipher_descriptor kseed_desc;
745 #endif
746
747 #ifdef LTC_KASUMI
748 int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
749 int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
750 int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
751 int kasumi_test(void);
752 void kasumi_done(symmetric_key *skey);
753 int kasumi_keysize(int *keysize);
754 extern const struct ltc_cipher_descriptor kasumi_desc;
755 #endif
756
757
758 #ifdef LTC_MULTI2
759 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
760 int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
761 int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
762 int multi2_test(void);
763 void multi2_done(symmetric_key *skey);
764 int multi2_keysize(int *keysize);
765 extern const struct ltc_cipher_descriptor multi2_desc;
766 #endif
767
768 #ifdef LTC_CAMELLIA
769 int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
770 int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
771 int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
772 int camellia_test(void);
773 void camellia_done(symmetric_key *skey);
774 int camellia_keysize(int *keysize);
775 extern const struct ltc_cipher_descriptor camellia_desc;
776 #endif
777
778 #ifdef LTC_ECB_MODE
779 int ecb_start(int cipher, const unsigned char *key,
780 int keylen, int num_rounds, symmetric_ECB *ecb);
781 int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb);
782 int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb);
783 int ecb_done(symmetric_ECB *ecb);
784 #endif
785
786 #ifdef LTC_CFB_MODE
787 int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
788 int keylen, int num_rounds, symmetric_CFB *cfb);
789 int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb);
790 int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
791 int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb);
792 int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb);
793 int cfb_done(symmetric_CFB *cfb);
794 #endif
795
796 #ifdef LTC_OFB_MODE
797 int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
798 int keylen, int num_rounds, symmetric_OFB *ofb);
799 int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb);
800 int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb);
801 int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb);
802 int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb);
803 int ofb_done(symmetric_OFB *ofb);
804 #endif
805
806 #ifdef LTC_CBC_MODE
807 int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
808 int keylen, int num_rounds, symmetric_CBC *cbc);
809 int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc);
810 int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc);
811 int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc);
812 int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc);
813 int cbc_done(symmetric_CBC *cbc);
814 #endif
815
816 #ifdef LTC_CTR_MODE
817
818 #define CTR_COUNTER_LITTLE_ENDIAN 0x0000
819 #define CTR_COUNTER_BIG_ENDIAN 0x1000
820 #define LTC_CTR_RFC3686 0x2000
821
822 int ctr_start( int cipher,
823 const unsigned char *IV,
824 const unsigned char *key, int keylen,
825 int num_rounds, int ctr_mode,
826 symmetric_CTR *ctr);
827 int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
828 int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
829 int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
830 int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
831 int ctr_done(symmetric_CTR *ctr);
832 int ctr_test(void);
833 #endif
834
835 #ifdef LTC_LRW_MODE
836
837 #define LRW_ENCRYPT 0
838 #define LRW_DECRYPT 1
839
840 int lrw_start( int cipher,
841 const unsigned char *IV,
842 const unsigned char *key, int keylen,
843 const unsigned char *tweak,
844 int num_rounds,
845 symmetric_LRW *lrw);
846 int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw);
847 int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw);
848 int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw);
849 int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw);
850 int lrw_done(symmetric_LRW *lrw);
851 int lrw_test(void);
852
853 /* don't call */
854 int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw);
855 #endif
856
857 #ifdef LTC_F8_MODE
858 int f8_start( int cipher, const unsigned char *IV,
859 const unsigned char *key, int keylen,
860 const unsigned char *salt_key, int skeylen,
861 int num_rounds, symmetric_F8 *f8);
862 int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8);
863 int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8);
864 int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8);
865 int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8);
866 int f8_done(symmetric_F8 *f8);
867 int f8_test_mode(void);
868 #endif
869
870 #ifdef LTC_XTS_MODE
871 typedef struct {
872 symmetric_key key1, key2;
873 int cipher;
874 } symmetric_xts;
875
876 int xts_start( int cipher,
877 const unsigned char *key1,
878 const unsigned char *key2,
879 unsigned long keylen,
880 int num_rounds,
881 symmetric_xts *xts);
882
883 int xts_encrypt(
884 const unsigned char *pt, unsigned long ptlen,
885 unsigned char *ct,
886 const unsigned char *tweak,
887 symmetric_xts *xts);
888 int xts_decrypt(
889 const unsigned char *ct, unsigned long ptlen,
890 unsigned char *pt,
891 const unsigned char *tweak,
892 symmetric_xts *xts);
893
894 void xts_done(symmetric_xts *xts);
895 int xts_test(void);
896 void xts_mult_x(unsigned char *I);
897 #endif
898
899 int find_cipher(const char *name);
900 int find_cipher_any(const char *name, int blocklen, int keylen);
901 int find_cipher_id(unsigned char ID);
902 int register_cipher(const struct ltc_cipher_descriptor *cipher);
903 int unregister_cipher(const struct ltc_cipher_descriptor *cipher);
904 int cipher_is_valid(int idx);
905
906 LTC_MUTEX_PROTO(ltc_cipher_mutex)
907
908 /* $Source$ */
909 /* $Revision$ */
910 /* $Date$ */
+0
-448
libtom-src/headers/tomcrypt_custom.h less more
0 #ifndef TOMCRYPT_CUSTOM_H_
1 #define TOMCRYPT_CUSTOM_H_
2
3 /* macros for various libc functions you can change for embedded targets */
4 #ifndef XMALLOC
5 #ifdef malloc
6 /* #define LTC_NO_PROTOTYPES */
7 #endif
8 #define XMALLOC malloc
9 #endif
10 #ifndef XREALLOC
11 #ifdef realloc
12 /* #define LTC_NO_PROTOTYPES */
13 #endif
14 #define XREALLOC realloc
15 #endif
16 #ifndef XCALLOC
17 #ifdef calloc
18 /* #define LTC_NO_PROTOTYPES */
19 #endif
20 #define XCALLOC calloc
21 #endif
22 #ifndef XFREE
23 #ifdef free
24 /* #define LTC_NO_PROTOTYPES */
25 #endif
26 #define XFREE free
27 #endif
28
29 #ifndef XMEMSET
30 #ifdef memset
31 /* #define LTC_NO_PROTOTYPES */
32 #endif
33 #define XMEMSET memset
34 #endif
35 #ifndef XMEMCPY
36 #ifdef memcpy
37 /* #define LTC_NO_PROTOTYPES */
38 #endif
39 #define XMEMCPY memcpy
40 #endif
41 #ifndef XMEMCMP
42 #ifdef memcmp
43 /* #define LTC_NO_PROTOTYPES */
44 #endif
45 #define XMEMCMP memcmp
46 #endif
47 #ifndef XSTRCMP
48 #ifdef strcmp
49 /* #define LTC_NO_PROTOTYPES */
50 #endif
51 #define XSTRCMP strcmp
52 #endif
53
54 #ifndef XCLOCK
55 #define XCLOCK clock
56 #endif
57 #ifndef XCLOCKS_PER_SEC
58 #define XCLOCKS_PER_SEC CLOCKS_PER_SEC
59 #endif
60
61 #ifndef XQSORT
62 #ifdef qsort
63 /* #define LTC_NO_PROTOTYPES */
64 #endif
65 #define XQSORT qsort
66 #endif
67
68 /* Easy button? */
69 #ifdef LTC_EASY
70 #define LTC_NO_CIPHERS
71 #define LTC_RIJNDAEL
72 #define LTC_BLOWFISH
73 #define LTC_DES
74 #define LTC_CAST5
75
76 #define LTC_NO_MODES
77 #define LTC_ECB_MODE
78 #define LTC_CBC_MODE
79 #define LTC_CTR_MODE
80
81 #define LTC_NO_HASHES
82 #define LTC_SHA1
83 #define LTC_SHA512
84 #define LTC_SHA384
85 #define LTC_SHA256
86 #define LTC_SHA224
87
88 #define LTC_NO_MACS
89 #define LTC_HMAC
90 #define LTC_OMAC
91 #define LTC_CCM_MODE
92
93 #define LTC_NO_PRNGS
94 #define LTC_SPRNG
95 #define LTC_YARROW
96 #define LTC_DEVRANDOM
97 #define TRY_URANDOM_FIRST
98
99 #define LTC_NO_PK
100 #define LTC_MRSA
101 #define LTC_MECC
102 #endif
103
104 /* Use small code where possible */
105 /* #define LTC_SMALL_CODE */
106
107 /* Enable self-test test vector checking */
108 #ifndef LTC_NO_TEST
109 #define LTC_TEST
110 #endif
111
112 /* clean the stack of functions which put private information on stack */
113 /* #define LTC_CLEAN_STACK */
114
115 /* disable all file related functions */
116 /* #define LTC_NO_FILE */
117
118 /* disable all forms of ASM */
119 /* #define LTC_NO_ASM */
120
121 /* disable FAST mode */
122 /* #define LTC_NO_FAST */
123
124 /* disable BSWAP on x86 */
125 /* #define LTC_NO_BSWAP */
126
127 /* ---> Symmetric Block Ciphers <--- */
128 #ifndef LTC_NO_CIPHERS
129
130 #define LTC_BLOWFISH
131 #define LTC_RC2
132 #define LTC_RC5
133 #define LTC_RC6
134 #define LTC_SAFERP
135 #define LTC_RIJNDAEL
136 #define LTC_XTEA
137 /* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format
138 * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */
139 #define LTC_TWOFISH
140 #ifndef LTC_NO_TABLES
141 #define LTC_TWOFISH_TABLES
142 /* #define LTC_TWOFISH_ALL_TABLES */
143 #else
144 #define LTC_TWOFISH_SMALL
145 #endif
146 /* #define LTC_TWOFISH_SMALL */
147 /* LTC_DES includes EDE triple-LTC_DES */
148 #define LTC_DES
149 #define LTC_CAST5
150 #define LTC_NOEKEON
151 #define LTC_SKIPJACK
152 #define LTC_SAFER
153 #define LTC_KHAZAD
154 #define LTC_ANUBIS
155 #define LTC_ANUBIS_TWEAK
156 #define LTC_KSEED
157 #define LTC_KASUMI
158 #define LTC_MULTI2
159 #define LTC_CAMELLIA
160
161 #endif /* LTC_NO_CIPHERS */
162
163
164 /* ---> Block Cipher Modes of Operation <--- */
165 #ifndef LTC_NO_MODES
166
167 #define LTC_CFB_MODE
168 #define LTC_OFB_MODE
169 #define LTC_ECB_MODE
170 #define LTC_CBC_MODE
171 #define LTC_CTR_MODE
172
173 /* F8 chaining mode */
174 #define LTC_F8_MODE
175
176 /* LRW mode */
177 #define LTC_LRW_MODE
178 #ifndef LTC_NO_TABLES
179 /* like GCM mode this will enable 16 8x128 tables [64KB] that make
180 * seeking very fast.
181 */
182 #define LRW_TABLES
183 #endif
184
185 /* XTS mode */
186 #define LTC_XTS_MODE
187
188 #endif /* LTC_NO_MODES */
189
190 /* ---> One-Way Hash Functions <--- */
191 #ifndef LTC_NO_HASHES
192
193 #define LTC_CHC_HASH
194 #define LTC_WHIRLPOOL
195 #define LTC_SHA512
196 #define LTC_SHA384
197 #define LTC_SHA256
198 #define LTC_SHA224
199 #define LTC_TIGER
200 #define LTC_SHA1
201 #define LTC_MD5
202 #define LTC_MD4
203 #define LTC_MD2
204 #define LTC_RIPEMD128
205 #define LTC_RIPEMD160
206 #define LTC_RIPEMD256
207 #define LTC_RIPEMD320
208
209 #endif /* LTC_NO_HASHES */
210
211 /* ---> MAC functions <--- */
212 #ifndef LTC_NO_MACS
213
214 #define LTC_HMAC
215 #define LTC_OMAC
216 #define LTC_PMAC
217 #define LTC_XCBC
218 #define LTC_F9_MODE
219 #define LTC_PELICAN
220
221 #if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL)
222 #error Pelican-MAC requires LTC_RIJNDAEL
223 #endif
224
225 /* ---> Encrypt + Authenticate Modes <--- */
226
227 #define LTC_EAX_MODE
228 #if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC))
229 #error LTC_EAX_MODE requires CTR and LTC_OMAC mode
230 #endif
231
232 #define LTC_OCB_MODE
233 #define LTC_OCB3_MODE
234 #define LTC_CCM_MODE
235 #define LTC_GCM_MODE
236
237 /* Use 64KiB tables */
238 #ifndef LTC_NO_TABLES
239 #define LTC_GCM_TABLES
240 #endif
241
242 /* USE SSE2? requires GCC works on x86_32 and x86_64*/
243 #ifdef LTC_GCM_TABLES
244 /* #define LTC_GCM_TABLES_SSE2 */
245 #endif
246
247 #endif /* LTC_NO_MACS */
248
249 /* Various tidbits of modern neatoness */
250 #define LTC_BASE64
251
252 /* --> Pseudo Random Number Generators <--- */
253 #ifndef LTC_NO_PRNGS
254
255 /* Yarrow */
256 #define LTC_YARROW
257 /* which descriptor of AES to use? */
258 /* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */
259 #ifdef ENCRYPT_ONLY
260 #define LTC_YARROW_AES 3
261 #else
262 #define LTC_YARROW_AES 3
263 #endif
264
265 #if defined(LTC_YARROW) && !defined(LTC_CTR_MODE)
266 #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined!
267 #endif
268
269 /* a PRNG that simply reads from an available system source */
270 #define LTC_SPRNG
271
272 /* The LTC_RC4 stream cipher */
273 #define LTC_RC4
274
275 /* Fortuna PRNG */
276 #define LTC_FORTUNA
277 /* reseed every N calls to the read function */
278 #define LTC_FORTUNA_WD 10
279 /* number of pools (4..32) can save a bit of ram by lowering the count */
280 #define LTC_FORTUNA_POOLS 32
281
282 /* Greg's LTC_SOBER128 PRNG ;-0 */
283 #define LTC_SOBER128
284
285 /* the *nix style /dev/random device */
286 #define LTC_DEVRANDOM
287 /* try /dev/urandom before trying /dev/random */
288 #define TRY_URANDOM_FIRST
289
290 #endif /* LTC_NO_PRNGS */
291
292 /* ---> math provider? <--- */
293 #ifndef LTC_NO_MATH
294
295 /* LibTomMath */
296 /* #define LTM_DESC */
297
298 /* TomsFastMath */
299 /* #define TFM_DESC */
300
301 #endif /* LTC_NO_MATH */
302
303 /* ---> Public Key Crypto <--- */
304 #ifndef LTC_NO_PK
305
306 /* Include RSA support */
307 #define LTC_MRSA
308
309 /* Enable RSA blinding when doing private key operations? */
310 /* #define LTC_RSA_BLINDING */
311
312 /* Include Diffie-Hellman support */
313 #ifndef GMP_DESC
314 /* is_prime fails for GMP */
315 #define MDH
316 /* Supported Key Sizes */
317 #define DH768
318 #define DH1024
319 #define DH1280
320 #define DH1536
321 #define DH1792
322 #define DH2048
323
324 #ifndef TFM_DESC
325 /* tfm has a problem in fp_isprime for larger key sizes */
326 #define DH2560
327 #define DH3072
328 #define DH4096
329 #endif
330 #endif
331
332 /* Include Katja (a Rabin variant like RSA) */
333 /* #define MKAT */
334
335 /* Digital Signature Algorithm */
336 #define LTC_MDSA
337
338 /* ECC */
339 #define LTC_MECC
340
341 /* use Shamir's trick for point mul (speeds up signature verification) */
342 #define LTC_ECC_SHAMIR
343
344 #if defined(TFM_LTC_DESC) && defined(LTC_MECC)
345 #define LTC_MECC_ACCEL
346 #endif
347
348 /* do we want fixed point ECC */
349 /* #define LTC_MECC_FP */
350
351 /* Timing Resistant? */
352 /* #define LTC_ECC_TIMING_RESISTANT */
353
354 #endif /* LTC_NO_PK */
355
356 /* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */
357 #ifndef LTC_NO_PKCS
358
359 #define LTC_PKCS_1
360 #define LTC_PKCS_5
361
362 /* Include ASN.1 DER (required by DSA/RSA) */
363 #define LTC_DER
364
365 #endif /* LTC_NO_PKCS */
366
367 /* LTC_HKDF Key Derivation/Expansion stuff */
368 #ifndef LTC_NO_HKDF
369
370 #define LTC_HKDF
371
372 #endif /* LTC_NO_HKDF */
373
374 /* cleanup */
375
376 #ifdef LTC_MECC
377 /* Supported ECC Key Sizes */
378 #ifndef LTC_NO_CURVES
379 #define ECC112
380 #define ECC128
381 #define ECC160
382 #define ECC192
383 #define ECC224
384 #define ECC256
385 #define ECC384
386 #define ECC521
387 #endif
388 #endif
389
390 #if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA)
391 /* Include the MPI functionality? (required by the PK algorithms) */
392 #define MPI
393 #endif
394
395 #ifdef LTC_MRSA
396 #define LTC_PKCS_1
397 #endif
398
399 #if defined(TFM_DESC) && defined(LTC_RSA_BLINDING)
400 #warning RSA blinding currently not supported in combination with TFM
401 #undef LTC_RSA_BLINDING
402 #endif
403
404 #if defined(LTC_DER) && !defined(MPI)
405 #error ASN.1 DER requires MPI functionality
406 #endif
407
408 #if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER)
409 #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled
410 #endif
411
412 /* THREAD management */
413 #ifdef LTC_PTHREAD
414
415 #include <pthread.h>
416
417 #define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
418 #define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
419 #define LTC_MUTEX_TYPE(x) pthread_mutex_t x;
420 #define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL);
421 #define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x);
422 #define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x);
423
424 #else
425
426 /* default no functions */
427 #define LTC_MUTEX_GLOBAL(x)
428 #define LTC_MUTEX_PROTO(x)
429 #define LTC_MUTEX_TYPE(x)
430 #define LTC_MUTEX_INIT(x)
431 #define LTC_MUTEX_LOCK(x)
432 #define LTC_MUTEX_UNLOCK(x)
433
434 #endif
435
436 /* Debuggers */
437
438 /* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */
439 /* #define LTC_VALGRIND */
440
441 #endif
442
443
444
445 /* $Source$ */
446 /* $Revision$ */
447 /* $Date$ */
+0
-382
libtom-src/headers/tomcrypt_hash.h less more
0 /* ---- HASH FUNCTIONS ---- */
1 #ifdef LTC_SHA512
2 struct sha512_state {
3 ulong64 length, state[8];
4 unsigned long curlen;
5 unsigned char buf[128];
6 };
7 #endif
8
9 #ifdef LTC_SHA256
10 struct sha256_state {
11 ulong64 length;
12 ulong32 state[8], curlen;
13 unsigned char buf[64];
14 };
15 #endif
16
17 #ifdef LTC_SHA1
18 struct sha1_state {
19 ulong64 length;
20 ulong32 state[5], curlen;
21 unsigned char buf[64];
22 };
23 #endif
24
25 #ifdef LTC_MD5
26 struct md5_state {
27 ulong64 length;
28 ulong32 state[4], curlen;
29 unsigned char buf[64];
30 };
31 #endif
32
33 #ifdef LTC_MD4
34 struct md4_state {
35 ulong64 length;
36 ulong32 state[4], curlen;
37 unsigned char buf[64];
38 };
39 #endif
40
41 #ifdef LTC_TIGER
42 struct tiger_state {
43 ulong64 state[3], length;
44 unsigned long curlen;
45 unsigned char buf[64];
46 };
47 #endif
48
49 #ifdef LTC_MD2
50 struct md2_state {
51 unsigned char chksum[16], X[48], buf[16];
52 unsigned long curlen;
53 };
54 #endif
55
56 #ifdef LTC_RIPEMD128
57 struct rmd128_state {
58 ulong64 length;
59 unsigned char buf[64];
60 ulong32 curlen, state[4];
61 };
62 #endif
63
64 #ifdef LTC_RIPEMD160
65 struct rmd160_state {
66 ulong64 length;
67 unsigned char buf[64];
68 ulong32 curlen, state[5];
69 };
70 #endif
71
72 #ifdef LTC_RIPEMD256
73 struct rmd256_state {
74 ulong64 length;
75 unsigned char buf[64];
76 ulong32 curlen, state[8];
77 };
78 #endif
79
80 #ifdef LTC_RIPEMD320
81 struct rmd320_state {
82 ulong64 length;
83 unsigned char buf[64];
84 ulong32 curlen, state[10];
85 };
86 #endif
87
88 #ifdef LTC_WHIRLPOOL
89 struct whirlpool_state {
90 ulong64 length, state[8];
91 unsigned char buf[64];
92 ulong32 curlen;
93 };
94 #endif
95
96 #ifdef LTC_CHC_HASH
97 struct chc_state {
98 ulong64 length;
99 unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE];
100 ulong32 curlen;
101 };
102 #endif
103
104 typedef union Hash_state {
105 char dummy[1];
106 #ifdef LTC_CHC_HASH
107 struct chc_state chc;
108 #endif
109 #ifdef LTC_WHIRLPOOL
110 struct whirlpool_state whirlpool;
111 #endif
112 #ifdef LTC_SHA512
113 struct sha512_state sha512;
114 #endif
115 #ifdef LTC_SHA256
116 struct sha256_state sha256;
117 #endif
118 #ifdef LTC_SHA1
119 struct sha1_state sha1;
120 #endif
121 #ifdef LTC_MD5
122 struct md5_state md5;
123 #endif
124 #ifdef LTC_MD4
125 struct md4_state md4;
126 #endif
127 #ifdef LTC_MD2
128 struct md2_state md2;
129 #endif
130 #ifdef LTC_TIGER
131 struct tiger_state tiger;
132 #endif
133 #ifdef LTC_RIPEMD128
134 struct rmd128_state rmd128;
135 #endif
136 #ifdef LTC_RIPEMD160
137 struct rmd160_state rmd160;
138 #endif
139 #ifdef LTC_RIPEMD256
140 struct rmd256_state rmd256;
141 #endif
142 #ifdef LTC_RIPEMD320
143 struct rmd320_state rmd320;
144 #endif
145 void *data;
146 } hash_state;
147
148 /** hash descriptor */
149 extern struct ltc_hash_descriptor {
150 /** name of hash */
151 char *name;
152 /** internal ID */
153 unsigned char ID;
154 /** Size of digest in octets */
155 unsigned long hashsize;
156 /** Input block size in octets */
157 unsigned long blocksize;
158 /** ASN.1 OID */
159 unsigned long OID[16];
160 /** Length of DER encoding */
161 unsigned long OIDlen;
162
163 /** Init a hash state
164 @param hash The hash to initialize
165 @return CRYPT_OK if successful
166 */
167 int (*init)(hash_state *hash);
168 /** Process a block of data
169 @param hash The hash state
170 @param in The data to hash
171 @param inlen The length of the data (octets)
172 @return CRYPT_OK if successful
173 */
174 int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen);
175 /** Produce the digest and store it
176 @param hash The hash state
177 @param out [out] The destination of the digest
178 @return CRYPT_OK if successful
179 */
180 int (*done)(hash_state *hash, unsigned char *out);
181 /** Self-test
182 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
183 */
184 int (*test)(void);
185
186 /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */
187 int (*hmac_block)(const unsigned char *key, unsigned long keylen,
188 const unsigned char *in, unsigned long inlen,
189 unsigned char *out, unsigned long *outlen);
190
191 } hash_descriptor[];
192
193 #ifdef LTC_CHC_HASH
194 int chc_register(int cipher);
195 int chc_init(hash_state * md);
196 int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen);
197 int chc_done(hash_state * md, unsigned char *hash);
198 int chc_test(void);
199 extern const struct ltc_hash_descriptor chc_desc;
200 #endif
201
202 #ifdef LTC_WHIRLPOOL
203 int whirlpool_init(hash_state * md);
204 int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen);
205 int whirlpool_done(hash_state * md, unsigned char *hash);
206 int whirlpool_test(void);
207 extern const struct ltc_hash_descriptor whirlpool_desc;
208 #endif
209
210 #ifdef LTC_SHA512
211 int sha512_init(hash_state * md);
212 int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen);
213 int sha512_done(hash_state * md, unsigned char *hash);
214 int sha512_test(void);
215 extern const struct ltc_hash_descriptor sha512_desc;
216 #endif
217
218 #ifdef LTC_SHA384
219 #ifndef LTC_SHA512
220 #error LTC_SHA512 is required for LTC_SHA384
221 #endif
222 int sha384_init(hash_state * md);
223 #define sha384_process sha512_process
224 int sha384_done(hash_state * md, unsigned char *hash);
225 int sha384_test(void);
226 extern const struct ltc_hash_descriptor sha384_desc;
227 #endif
228
229 #ifdef LTC_SHA256
230 int sha256_init(hash_state * md);
231 int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
232 int sha256_done(hash_state * md, unsigned char *hash);
233 int sha256_test(void);
234 extern const struct ltc_hash_descriptor sha256_desc;
235
236 #ifdef LTC_SHA224
237 #ifndef LTC_SHA256
238 #error LTC_SHA256 is required for LTC_SHA224
239 #endif
240 int sha224_init(hash_state * md);
241 #define sha224_process sha256_process
242 int sha224_done(hash_state * md, unsigned char *hash);
243 int sha224_test(void);
244 extern const struct ltc_hash_descriptor sha224_desc;
245 #endif
246 #endif
247
248 #ifdef LTC_SHA1
249 int sha1_init(hash_state * md);
250 int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen);
251 int sha1_done(hash_state * md, unsigned char *hash);
252 int sha1_test(void);
253 extern const struct ltc_hash_descriptor sha1_desc;
254 #endif
255
256 #ifdef LTC_MD5
257 int md5_init(hash_state * md);
258 int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen);
259 int md5_done(hash_state * md, unsigned char *hash);
260 int md5_test(void);
261 extern const struct ltc_hash_descriptor md5_desc;
262 #endif
263
264 #ifdef LTC_MD4
265 int md4_init(hash_state * md);
266 int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen);
267 int md4_done(hash_state * md, unsigned char *hash);
268 int md4_test(void);
269 extern const struct ltc_hash_descriptor md4_desc;
270 #endif
271
272 #ifdef LTC_MD2
273 int md2_init(hash_state * md);
274 int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen);
275 int md2_done(hash_state * md, unsigned char *hash);
276 int md2_test(void);
277 extern const struct ltc_hash_descriptor md2_desc;
278 #endif
279
280 #ifdef LTC_TIGER
281 int tiger_init(hash_state * md);
282 int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen);
283 int tiger_done(hash_state * md, unsigned char *hash);
284 int tiger_test(void);
285 extern const struct ltc_hash_descriptor tiger_desc;
286 #endif
287
288 #ifdef LTC_RIPEMD128
289 int rmd128_init(hash_state * md);
290 int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen);
291 int rmd128_done(hash_state * md, unsigned char *hash);
292 int rmd128_test(void);
293 extern const struct ltc_hash_descriptor rmd128_desc;
294 #endif
295
296 #ifdef LTC_RIPEMD160
297 int rmd160_init(hash_state * md);
298 int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen);
299 int rmd160_done(hash_state * md, unsigned char *hash);
300 int rmd160_test(void);
301 extern const struct ltc_hash_descriptor rmd160_desc;
302 #endif
303
304 #ifdef LTC_RIPEMD256
305 int rmd256_init(hash_state * md);
306 int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
307 int rmd256_done(hash_state * md, unsigned char *hash);
308 int rmd256_test(void);
309 extern const struct ltc_hash_descriptor rmd256_desc;
310 #endif
311
312 #ifdef LTC_RIPEMD320
313 int rmd320_init(hash_state * md);
314 int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen);
315 int rmd320_done(hash_state * md, unsigned char *hash);
316 int rmd320_test(void);
317 extern const struct ltc_hash_descriptor rmd320_desc;
318 #endif
319
320
321 int find_hash(const char *name);
322 int find_hash_id(unsigned char ID);
323 int find_hash_oid(const unsigned long *ID, unsigned long IDlen);
324 int find_hash_any(const char *name, int digestlen);
325 int register_hash(const struct ltc_hash_descriptor *hash);
326 int unregister_hash(const struct ltc_hash_descriptor *hash);
327 int hash_is_valid(int idx);
328
329 LTC_MUTEX_PROTO(ltc_hash_mutex)
330
331 int hash_memory(int hash,
332 const unsigned char *in, unsigned long inlen,
333 unsigned char *out, unsigned long *outlen);
334 int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
335 const unsigned char *in, unsigned long inlen, ...);
336
337 #ifndef LTC_NO_FILE
338 int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen);
339 int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen);
340 #endif
341
342 /* a simple macro for making hash "process" functions */
343 #define HASH_PROCESS(func_name, compress_name, state_var, block_size) \
344 int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \
345 { \
346 unsigned long n; \
347 int err; \
348 LTC_ARGCHK(md != NULL); \
349 LTC_ARGCHK(in != NULL); \
350 if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \
351 return CRYPT_INVALID_ARG; \
352 } \
353 while (inlen > 0) { \
354 if (md-> state_var .curlen == 0 && inlen >= block_size) { \
355 if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \
356 return err; \
357 } \
358 md-> state_var .length += block_size * 8; \
359 in += block_size; \
360 inlen -= block_size; \
361 } else { \
362 n = MIN(inlen, (block_size - md-> state_var .curlen)); \
363 memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \
364 md-> state_var .curlen += n; \
365 in += n; \
366 inlen -= n; \
367 if (md-> state_var .curlen == block_size) { \
368 if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \
369 return err; \
370 } \
371 md-> state_var .length += 8*block_size; \
372 md-> state_var .curlen = 0; \
373 } \
374 } \
375 } \
376 return CRYPT_OK; \
377 }
378
379 /* $Source$ */
380 /* $Revision$ */
381 /* $Date$ */
+0
-28
libtom-src/headers/tomcrypt_hkdf.h less more
0 /* LTC_HKDF Header Info */
1
2 /* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */
3 #ifdef LTC_HKDF
4
5 int hkdf_test(void);
6
7 int hkdf_extract(int hash_idx,
8 const unsigned char *salt, unsigned long saltlen,
9 const unsigned char *in, unsigned long inlen,
10 unsigned char *out, unsigned long *outlen);
11
12 int hkdf_expand(int hash_idx,
13 const unsigned char *info, unsigned long infolen,
14 const unsigned char *in, unsigned long inlen,
15 unsigned char *out, unsigned long outlen);
16
17 int hkdf(int hash_idx,
18 const unsigned char *salt, unsigned long saltlen,
19 const unsigned char *info, unsigned long infolen,
20 const unsigned char *in, unsigned long inlen,
21 unsigned char *out, unsigned long outlen);
22
23 #endif /* LTC_HKDF */
24
25 /* $Source$ */
26 /* $Revision$ */
27 /* $Date$ */
+0
-458
libtom-src/headers/tomcrypt_mac.h less more
0 #ifdef LTC_HMAC
1 typedef struct Hmac_state {
2 hash_state md;
3 int hash;
4 hash_state hashstate;
5 unsigned char *key;
6 } hmac_state;
7
8 int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
9 int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen);
10 int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen);
11 int hmac_test(void);
12 int hmac_memory(int hash,
13 const unsigned char *key, unsigned long keylen,
14 const unsigned char *in, unsigned long inlen,
15 unsigned char *out, unsigned long *outlen);
16 int hmac_memory_multi(int hash,
17 const unsigned char *key, unsigned long keylen,
18 unsigned char *out, unsigned long *outlen,
19 const unsigned char *in, unsigned long inlen, ...);
20 int hmac_file(int hash, const char *fname, const unsigned char *key,
21 unsigned long keylen,
22 unsigned char *dst, unsigned long *dstlen);
23 #endif
24
25 #ifdef LTC_OMAC
26
27 typedef struct {
28 int cipher_idx,
29 buflen,
30 blklen;
31 unsigned char block[MAXBLOCKSIZE],
32 prev[MAXBLOCKSIZE],
33 Lu[2][MAXBLOCKSIZE];
34 symmetric_key key;
35 } omac_state;
36
37 int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen);
38 int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen);
39 int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen);
40 int omac_memory(int cipher,
41 const unsigned char *key, unsigned long keylen,
42 const unsigned char *in, unsigned long inlen,
43 unsigned char *out, unsigned long *outlen);
44 int omac_memory_multi(int cipher,
45 const unsigned char *key, unsigned long keylen,
46 unsigned char *out, unsigned long *outlen,
47 const unsigned char *in, unsigned long inlen, ...);
48 int omac_file(int cipher,
49 const unsigned char *key, unsigned long keylen,
50 const char *filename,
51 unsigned char *out, unsigned long *outlen);
52 int omac_test(void);
53 #endif /* LTC_OMAC */
54
55 #ifdef LTC_PMAC
56
57 typedef struct {
58 unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
59 Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
60 Lr[MAXBLOCKSIZE], /* L * x^-1 */
61 block[MAXBLOCKSIZE], /* currently accumulated block */
62 checksum[MAXBLOCKSIZE]; /* current checksum */
63
64 symmetric_key key; /* scheduled key for cipher */
65 unsigned long block_index; /* index # for current block */
66 int cipher_idx, /* cipher idx */
67 block_len, /* length of block */
68 buflen; /* number of bytes in the buffer */
69 } pmac_state;
70
71 int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen);
72 int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen);
73 int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen);
74
75 int pmac_memory(int cipher,
76 const unsigned char *key, unsigned long keylen,
77 const unsigned char *msg, unsigned long msglen,
78 unsigned char *out, unsigned long *outlen);
79
80 int pmac_memory_multi(int cipher,
81 const unsigned char *key, unsigned long keylen,
82 unsigned char *out, unsigned long *outlen,
83 const unsigned char *in, unsigned long inlen, ...);
84
85 int pmac_file(int cipher,
86 const unsigned char *key, unsigned long keylen,
87 const char *filename,
88 unsigned char *out, unsigned long *outlen);
89
90 int pmac_test(void);
91
92 /* internal functions */
93 int pmac_ntz(unsigned long x);
94 void pmac_shift_xor(pmac_state *pmac);
95
96 #endif /* PMAC */
97
98 #ifdef LTC_EAX_MODE
99
100 #if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE))
101 #error LTC_EAX_MODE requires LTC_OMAC and CTR
102 #endif
103
104 typedef struct {
105 unsigned char N[MAXBLOCKSIZE];
106 symmetric_CTR ctr;
107 omac_state headeromac, ctomac;
108 } eax_state;
109
110 int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
111 const unsigned char *nonce, unsigned long noncelen,
112 const unsigned char *header, unsigned long headerlen);
113
114 int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);
115 int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);
116 int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);
117 int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);
118
119 int eax_encrypt_authenticate_memory(int cipher,
120 const unsigned char *key, unsigned long keylen,
121 const unsigned char *nonce, unsigned long noncelen,
122 const unsigned char *header, unsigned long headerlen,
123 const unsigned char *pt, unsigned long ptlen,
124 unsigned char *ct,
125 unsigned char *tag, unsigned long *taglen);
126
127 int eax_decrypt_verify_memory(int cipher,
128 const unsigned char *key, unsigned long keylen,
129 const unsigned char *nonce, unsigned long noncelen,
130 const unsigned char *header, unsigned long headerlen,
131 const unsigned char *ct, unsigned long ctlen,
132 unsigned char *pt,
133 unsigned char *tag, unsigned long taglen,
134 int *stat);
135
136 int eax_test(void);
137 #endif /* EAX MODE */
138
139 #ifdef LTC_OCB_MODE
140 typedef struct {
141 unsigned char L[MAXBLOCKSIZE], /* L value */
142 Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
143 Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
144 Lr[MAXBLOCKSIZE], /* L * x^-1 */
145 R[MAXBLOCKSIZE], /* R value */
146 checksum[MAXBLOCKSIZE]; /* current checksum */
147
148 symmetric_key key; /* scheduled key for cipher */
149 unsigned long block_index; /* index # for current block */
150 int cipher, /* cipher idx */
151 block_len; /* length of block */
152 } ocb_state;
153
154 int ocb_init(ocb_state *ocb, int cipher,
155 const unsigned char *key, unsigned long keylen, const unsigned char *nonce);
156
157 int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
158 int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
159
160 int ocb_done_encrypt(ocb_state *ocb,
161 const unsigned char *pt, unsigned long ptlen,
162 unsigned char *ct,
163 unsigned char *tag, unsigned long *taglen);
164
165 int ocb_done_decrypt(ocb_state *ocb,
166 const unsigned char *ct, unsigned long ctlen,
167 unsigned char *pt,
168 const unsigned char *tag, unsigned long taglen, int *stat);
169
170 int ocb_encrypt_authenticate_memory(int cipher,
171 const unsigned char *key, unsigned long keylen,
172 const unsigned char *nonce,
173 const unsigned char *pt, unsigned long ptlen,
174 unsigned char *ct,
175 unsigned char *tag, unsigned long *taglen);
176
177 int ocb_decrypt_verify_memory(int cipher,
178 const unsigned char *key, unsigned long keylen,
179 const unsigned char *nonce,
180 const unsigned char *ct, unsigned long ctlen,
181 unsigned char *pt,
182 const unsigned char *tag, unsigned long taglen,
183 int *stat);
184
185 int ocb_test(void);
186
187 /* internal functions */
188 void ocb_shift_xor(ocb_state *ocb, unsigned char *Z);
189 int ocb_ntz(unsigned long x);
190 int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
191 unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode);
192
193 #endif /* LTC_OCB_MODE */
194
195 #ifdef LTC_OCB3_MODE
196 typedef struct {
197 unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */
198 Offset_current[MAXBLOCKSIZE], /* Offset_{current_block_index} value */
199 L_dollar[MAXBLOCKSIZE], /* L_$ value */
200 L_star[MAXBLOCKSIZE], /* L_* value */
201 L_[32][MAXBLOCKSIZE], /* L_{i} values */
202 tag_part[MAXBLOCKSIZE], /* intermediate result of tag calculation */
203 checksum[MAXBLOCKSIZE]; /* current checksum */
204
205 /* AAD related members */
206 unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */
207 aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */
208 adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */
209 int adata_buffer_bytes; /* bytes in AAD buffer */
210 unsigned long ablock_index; /* index # for current adata (AAD) block */
211
212 symmetric_key key; /* scheduled key for cipher */
213 unsigned long block_index; /* index # for current data block */
214 int cipher, /* cipher idx */
215 block_len; /* length of block */
216 } ocb3_state;
217
218 int ocb3_init(ocb3_state *ocb, int cipher,
219 const unsigned char *key, unsigned long keylen,
220 const unsigned char *nonce, unsigned long noncelen);
221
222 int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
223 int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
224 int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
225 int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
226 int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen);
227 int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen);
228
229 int ocb3_encrypt_authenticate_memory(int cipher,
230 const unsigned char *key, unsigned long keylen,
231 const unsigned char *nonce, unsigned long noncelen,
232 const unsigned char *adata, unsigned long adatalen,
233 const unsigned char *pt, unsigned long ptlen,
234 unsigned char *ct,
235 unsigned char *tag, unsigned long *taglen);
236
237 int ocb3_decrypt_verify_memory(int cipher,
238 const unsigned char *key, unsigned long keylen,
239 const unsigned char *nonce, unsigned long noncelen,
240 const unsigned char *adata, unsigned long adatalen,
241 const unsigned char *ct, unsigned long ctlen,
242 unsigned char *pt,
243 const unsigned char *tag, unsigned long taglen,
244 int *stat);
245
246 int ocb3_test(void);
247
248 /* internal helper functions */
249 int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block);
250 void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen);
251 int ocb3_int_ntz(unsigned long x);
252 void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len);
253
254 #endif /* LTC_OCB3_MODE */
255
256 #ifdef LTC_CCM_MODE
257
258 #define CCM_ENCRYPT 0
259 #define CCM_DECRYPT 1
260
261 int ccm_memory(int cipher,
262 const unsigned char *key, unsigned long keylen,
263 symmetric_key *uskey,
264 const unsigned char *nonce, unsigned long noncelen,
265 const unsigned char *header, unsigned long headerlen,
266 unsigned char *pt, unsigned long ptlen,
267 unsigned char *ct,
268 unsigned char *tag, unsigned long *taglen,
269 int direction);
270
271 int ccm_memory_ex(int cipher,
272 const unsigned char *key, unsigned long keylen,
273 symmetric_key *uskey,
274 const unsigned char *nonce, unsigned long noncelen,
275 const unsigned char *header, unsigned long headerlen,
276 unsigned char *pt, unsigned long ptlen,
277 unsigned char *ct,
278 unsigned char *tag, unsigned long *taglen,
279 int direction,
280 const unsigned char *B_0,
281 const unsigned char *CTR,
282 int ctrwidth);
283
284 int ccm_test(void);
285
286 #endif /* LTC_CCM_MODE */
287
288 #if defined(LRW_MODE) || defined(LTC_GCM_MODE)
289 void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c);
290 #endif
291
292
293 /* table shared between GCM and LRW */
294 #if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
295 extern const unsigned char gcm_shift_table[];
296 #endif
297
298 #ifdef LTC_GCM_MODE
299
300 #define GCM_ENCRYPT 0
301 #define GCM_DECRYPT 1
302
303 #define LTC_GCM_MODE_IV 0
304 #define LTC_GCM_MODE_AAD 1
305 #define LTC_GCM_MODE_TEXT 2
306
307 typedef struct {
308 symmetric_key K;
309 unsigned char H[16], /* multiplier */
310 X[16], /* accumulator */
311 Y[16], /* counter */
312 Y_0[16], /* initial counter */
313 buf[16]; /* buffer for stuff */
314
315 int cipher, /* which cipher */
316 ivmode, /* Which mode is the IV in? */
317 mode, /* mode the GCM code is in */
318 buflen; /* length of data in buf */
319
320 ulong64 totlen, /* 64-bit counter used for IV and AAD */
321 pttotlen; /* 64-bit counter for the PT */
322
323 #ifdef LTC_GCM_TABLES
324 unsigned char PC[16][256][16] /* 16 tables of 8x128 */
325 #ifdef LTC_GCM_TABLES_SSE2
326 __attribute__ ((aligned (16)))
327 #endif
328 ;
329 #endif
330 } gcm_state;
331
332 void gcm_mult_h(gcm_state *gcm, unsigned char *I);
333
334 int gcm_init(gcm_state *gcm, int cipher,
335 const unsigned char *key, int keylen);
336
337 int gcm_reset(gcm_state *gcm);
338
339 int gcm_add_iv(gcm_state *gcm,
340 const unsigned char *IV, unsigned long IVlen);
341
342 int gcm_add_aad(gcm_state *gcm,
343 const unsigned char *adata, unsigned long adatalen);
344
345 int gcm_process(gcm_state *gcm,
346 unsigned char *pt, unsigned long ptlen,
347 unsigned char *ct,
348 int direction);
349
350 int gcm_done(gcm_state *gcm,
351 unsigned char *tag, unsigned long *taglen);
352
353 int gcm_memory( int cipher,
354 const unsigned char *key, unsigned long keylen,
355 const unsigned char *IV, unsigned long IVlen,
356 const unsigned char *adata, unsigned long adatalen,
357 unsigned char *pt, unsigned long ptlen,
358 unsigned char *ct,
359 unsigned char *tag, unsigned long *taglen,
360 int direction);
361 int gcm_test(void);
362
363 #endif /* LTC_GCM_MODE */
364
365 #ifdef LTC_PELICAN
366
367 typedef struct pelican_state
368 {
369 symmetric_key K;
370 unsigned char state[16];
371 int buflen;
372 } pelican_state;
373
374 int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen);
375 int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen);
376 int pelican_done(pelican_state *pelmac, unsigned char *out);
377 int pelican_test(void);
378
379 int pelican_memory(const unsigned char *key, unsigned long keylen,
380 const unsigned char *in, unsigned long inlen,
381 unsigned char *out);
382
383 #endif
384
385 #ifdef LTC_XCBC
386
387 /* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */
388 #define LTC_XCBC_PURE 0x8000UL
389
390 typedef struct {
391 unsigned char K[3][MAXBLOCKSIZE],
392 IV[MAXBLOCKSIZE];
393
394 symmetric_key key;
395
396 int cipher,
397 buflen,
398 blocksize;
399 } xcbc_state;
400
401 int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen);
402 int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen);
403 int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen);
404 int xcbc_memory(int cipher,
405 const unsigned char *key, unsigned long keylen,
406 const unsigned char *in, unsigned long inlen,
407 unsigned char *out, unsigned long *outlen);
408 int xcbc_memory_multi(int cipher,
409 const unsigned char *key, unsigned long keylen,
410 unsigned char *out, unsigned long *outlen,
411 const unsigned char *in, unsigned long inlen, ...);
412 int xcbc_file(int cipher,
413 const unsigned char *key, unsigned long keylen,
414 const char *filename,
415 unsigned char *out, unsigned long *outlen);
416 int xcbc_test(void);
417
418 #endif
419
420 #ifdef LTC_F9_MODE
421
422 typedef struct {
423 unsigned char akey[MAXBLOCKSIZE],
424 ACC[MAXBLOCKSIZE],
425 IV[MAXBLOCKSIZE];
426
427 symmetric_key key;
428
429 int cipher,
430 buflen,
431 keylen,
432 blocksize;
433 } f9_state;
434
435 int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen);
436 int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen);
437 int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
438 int f9_memory(int cipher,
439 const unsigned char *key, unsigned long keylen,
440 const unsigned char *in, unsigned long inlen,
441 unsigned char *out, unsigned long *outlen);
442 int f9_memory_multi(int cipher,
443 const unsigned char *key, unsigned long keylen,
444 unsigned char *out, unsigned long *outlen,
445 const unsigned char *in, unsigned long inlen, ...);
446 int f9_file(int cipher,
447 const unsigned char *key, unsigned long keylen,
448 const char *filename,
449 unsigned char *out, unsigned long *outlen);
450 int f9_test(void);
451
452 #endif
453
454
455 /* $Source$ */
456 /* $Revision$ */
457 /* $Date$ */
+0
-443
libtom-src/headers/tomcrypt_macros.h less more
0 /* fix for MSVC ...evil! */
1 #ifdef _MSC_VER
2 #define CONST64(n) n ## ui64
3 typedef unsigned __int64 ulong64;
4 #else
5 #define CONST64(n) n ## ULL
6 typedef unsigned long long ulong64;
7 #endif
8
9 /* this is the "32-bit at least" data type
10 * Re-define it to suit your platform but it must be at least 32-bits
11 */
12 #if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__))
13 typedef unsigned ulong32;
14 #else
15 typedef unsigned long ulong32;
16 #endif
17
18 /* ---- HELPER MACROS ---- */
19 #ifdef ENDIAN_NEUTRAL
20
21 #define STORE32L(x, y) \
22 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
23 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
24
25 #define LOAD32L(x, y) \
26 { x = ((unsigned long)((y)[3] & 255)<<24) | \
27 ((unsigned long)((y)[2] & 255)<<16) | \
28 ((unsigned long)((y)[1] & 255)<<8) | \
29 ((unsigned long)((y)[0] & 255)); }
30
31 #define STORE64L(x, y) \
32 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
33 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
34 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
35 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
36
37 #define LOAD64L(x, y) \
38 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
39 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
40 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
41 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
42
43 #define STORE32H(x, y) \
44 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
45 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
46
47 #define LOAD32H(x, y) \
48 { x = ((unsigned long)((y)[0] & 255)<<24) | \
49 ((unsigned long)((y)[1] & 255)<<16) | \
50 ((unsigned long)((y)[2] & 255)<<8) | \
51 ((unsigned long)((y)[3] & 255)); }
52
53 #define STORE64H(x, y) \
54 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
55 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
56 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
57 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
58
59 #define LOAD64H(x, y) \
60 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
61 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
62 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
63 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
64
65 #endif /* ENDIAN_NEUTRAL */
66
67 #ifdef ENDIAN_LITTLE
68
69 #ifdef LTC_HAVE_BSWAP_BUILTIN
70
71 #define STORE32H(x, y) \
72 { ulong32 __t = __builtin_bswap32 ((x)); \
73 XMEMCPY ((y), &__t, 4); }
74
75 #define LOAD32H(x, y) \
76 { XMEMCPY (&(x), (y), 4); \
77 (x) = __builtin_bswap32 ((x)); }
78
79 #elif !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))
80
81 #define STORE32H(x, y) \
82 asm __volatile__ ( \
83 "bswapl %0 \n\t" \
84 "movl %0,(%1)\n\t" \
85 "bswapl %0 \n\t" \
86 ::"r"(x), "r"(y));
87
88 #define LOAD32H(x, y) \
89 asm __volatile__ ( \
90 "movl (%1),%0\n\t" \
91 "bswapl %0\n\t" \
92 :"=r"(x): "r"(y));
93
94 #else
95
96 #define STORE32H(x, y) \
97 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
98 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
99
100 #define LOAD32H(x, y) \
101 { x = ((unsigned long)((y)[0] & 255)<<24) | \
102 ((unsigned long)((y)[1] & 255)<<16) | \
103 ((unsigned long)((y)[2] & 255)<<8) | \
104 ((unsigned long)((y)[3] & 255)); }
105
106 #endif
107
108 #ifdef LTC_HAVE_BSWAP_BUILTIN
109
110 #define STORE64H(x, y) \
111 { ulong64 __t = __builtin_bswap64 ((x)); \
112 XMEMCPY ((y), &__t, 8); }
113
114 #define LOAD64H(x, y) \
115 { XMEMCPY (&(x), (y), 8); \
116 (x) = __builtin_bswap64 ((x)); }
117
118 /* x86_64 processor */
119 #elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
120
121 #define STORE64H(x, y) \
122 asm __volatile__ ( \
123 "bswapq %0 \n\t" \
124 "movq %0,(%1)\n\t" \
125 "bswapq %0 \n\t" \
126 ::"r"(x), "r"(y): "memory");
127
128 #define LOAD64H(x, y) \
129 asm __volatile__ ( \
130 "movq (%1),%0\n\t" \
131 "bswapq %0\n\t" \
132 :"=r"(x): "r"(y): "memory");
133
134 #else
135
136 #define STORE64H(x, y) \
137 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
138 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
139 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
140 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
141
142 #define LOAD64H(x, y) \
143 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
144 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
145 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
146 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
147
148 #endif
149
150 #ifdef ENDIAN_32BITWORD
151
152 #define STORE32L(x, y) \
153 { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
154
155 #define LOAD32L(x, y) \
156 XMEMCPY(&(x), y, 4);
157
158 #define STORE64L(x, y) \
159 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
160 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
161 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
162 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
163
164 #define LOAD64L(x, y) \
165 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
166 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
167 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
168 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
169
170 #else /* 64-bit words then */
171
172 #define STORE32L(x, y) \
173 { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
174
175 #define LOAD32L(x, y) \
176 { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
177
178 #define STORE64L(x, y) \
179 { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
180
181 #define LOAD64L(x, y) \
182 { XMEMCPY(&(x), y, 8); }
183
184 #endif /* ENDIAN_64BITWORD */
185
186 #endif /* ENDIAN_LITTLE */
187
188 #ifdef ENDIAN_BIG
189 #define STORE32L(x, y) \
190 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
191 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
192
193 #define LOAD32L(x, y) \
194 { x = ((unsigned long)((y)[3] & 255)<<24) | \
195 ((unsigned long)((y)[2] & 255)<<16) | \
196 ((unsigned long)((y)[1] & 255)<<8) | \
197 ((unsigned long)((y)[0] & 255)); }
198
199 #define STORE64L(x, y) \
200 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
201 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
202 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
203 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
204
205 #define LOAD64L(x, y) \
206 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
207 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
208 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
209 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
210
211 #ifdef ENDIAN_32BITWORD
212
213 #define STORE32H(x, y) \
214 { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
215
216 #define LOAD32H(x, y) \
217 XMEMCPY(&(x), y, 4);
218
219 #define STORE64H(x, y) \
220 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
221 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
222 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
223 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
224
225 #define LOAD64H(x, y) \
226 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
227 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
228 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
229 (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
230
231 #else /* 64-bit words then */
232
233 #define STORE32H(x, y) \
234 { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
235
236 #define LOAD32H(x, y) \
237 { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
238
239 #define STORE64H(x, y) \
240 { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
241
242 #define LOAD64H(x, y) \
243 { XMEMCPY(&(x), y, 8); }
244
245 #endif /* ENDIAN_64BITWORD */
246 #endif /* ENDIAN_BIG */
247
248 #define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
249 ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
250
251
252 /* 32-bit Rotates */
253 #if defined(_MSC_VER)
254
255 /* instrinsic rotate */
256 #include <stdlib.h>
257 #pragma intrinsic(_lrotr,_lrotl)
258 #define ROR(x,n) _lrotr(x,n)
259 #define ROL(x,n) _lrotl(x,n)
260 #define RORc(x,n) _lrotr(x,n)
261 #define ROLc(x,n) _lrotl(x,n)
262
263 #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
264
265 static inline unsigned ROL(unsigned word, int i)
266 {
267 asm ("roll %%cl,%0"
268 :"=r" (word)
269 :"0" (word),"c" (i));
270 return word;
271 }
272
273 static inline unsigned ROR(unsigned word, int i)
274 {
275 asm ("rorl %%cl,%0"
276 :"=r" (word)
277 :"0" (word),"c" (i));
278 return word;
279 }
280
281 #ifndef LTC_NO_ROLC
282
283 static inline unsigned ROLc(unsigned word, const int i)
284 {
285 asm ("roll %2,%0"
286 :"=r" (word)
287 :"0" (word),"I" (i));
288 return word;
289 }
290
291 static inline unsigned RORc(unsigned word, const int i)
292 {
293 asm ("rorl %2,%0"
294 :"=r" (word)
295 :"0" (word),"I" (i));
296 return word;
297 }
298
299 #else
300
301 #define ROLc ROL
302 #define RORc ROR
303
304 #endif
305
306 #elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
307
308 static inline unsigned ROL(unsigned word, int i)
309 {
310 asm ("rotlw %0,%0,%2"
311 :"=r" (word)
312 :"0" (word),"r" (i));
313 return word;
314 }
315
316 static inline unsigned ROR(unsigned word, int i)
317 {
318 asm ("rotlw %0,%0,%2"
319 :"=r" (word)
320 :"0" (word),"r" (32-i));
321 return word;
322 }
323
324 #ifndef LTC_NO_ROLC
325
326 static inline unsigned ROLc(unsigned word, const int i)
327 {
328 asm ("rotlwi %0,%0,%2"
329 :"=r" (word)
330 :"0" (word),"I" (i));
331 return word;
332 }
333
334 static inline unsigned RORc(unsigned word, const int i)
335 {
336 asm ("rotrwi %0,%0,%2"
337 :"=r" (word)
338 :"0" (word),"I" (i));
339 return word;
340 }
341
342 #else
343
344 #define ROLc ROL
345 #define RORc ROR
346
347 #endif
348
349
350 #else
351
352 /* rotates the hard way */
353 #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
354 #define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
355 #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
356 #define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
357
358 #endif
359
360
361 /* 64-bit Rotates */
362 #if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM)
363
364 static inline unsigned long ROL64(unsigned long word, int i)
365 {
366 asm("rolq %%cl,%0"
367 :"=r" (word)
368 :"0" (word),"c" (i));
369 return word;
370 }
371
372 static inline unsigned long ROR64(unsigned long word, int i)
373 {
374 asm("rorq %%cl,%0"
375 :"=r" (word)
376 :"0" (word),"c" (i));
377 return word;
378 }
379
380 #ifndef LTC_NO_ROLC
381
382 static inline unsigned long ROL64c(unsigned long word, const int i)
383 {
384 asm("rolq %2,%0"
385 :"=r" (word)
386 :"0" (word),"J" (i));
387 return word;
388 }
389
390 static inline unsigned long ROR64c(unsigned long word, const int i)
391 {
392 asm("rorq %2,%0"
393 :"=r" (word)
394 :"0" (word),"J" (i));
395 return word;
396 }
397
398 #else /* LTC_NO_ROLC */
399
400 #define ROL64c ROL64
401 #define ROR64c ROR64
402
403 #endif
404
405 #else /* Not x86_64 */
406
407 #define ROL64(x, y) \
408 ( (((x)<<((ulong64)(y)&63)) | \
409 (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
410
411 #define ROR64(x, y) \
412 ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
413 ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
414
415 #define ROL64c(x, y) \
416 ( (((x)<<((ulong64)(y)&63)) | \
417 (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
418
419 #define ROR64c(x, y) \
420 ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
421 ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
422
423 #endif
424
425 #ifndef MAX
426 #define MAX(x, y) ( ((x)>(y))?(x):(y) )
427 #endif
428
429 #ifndef MIN
430 #define MIN(x, y) ( ((x)<(y))?(x):(y) )
431 #endif
432
433 /* extract a byte portably */
434 #ifdef _MSC_VER
435 #define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
436 #else
437 #define byte(x, n) (((x) >> (8 * (n))) & 255)
438 #endif
439
440 /* $Source$ */
441 /* $Revision$ */
442 /* $Date$ */
+0
-533
libtom-src/headers/tomcrypt_math.h less more
0 /** math functions **/
1
2 #define LTC_MP_LT -1
3 #define LTC_MP_EQ 0
4 #define LTC_MP_GT 1
5
6 #define LTC_MP_NO 0
7 #define LTC_MP_YES 1
8
9 #ifndef LTC_MECC
10 typedef void ecc_point;
11 #endif
12
13 #ifndef LTC_MRSA
14 typedef void rsa_key;
15 #endif
16
17 /** math descriptor */
18 typedef struct {
19 /** Name of the math provider */
20 char *name;
21
22 /** Bits per digit, amount of bits must fit in an unsigned long */
23 int bits_per_digit;
24
25 /* ---- init/deinit functions ---- */
26
27 /** initialize a bignum
28 @param a The number to initialize
29 @return CRYPT_OK on success
30 */
31 int (*init)(void **a);
32
33 /** init copy
34 @param dst The number to initialize and write to
35 @param src The number to copy from
36 @return CRYPT_OK on success
37 */
38 int (*init_copy)(void **dst, void *src);
39
40 /** deinit
41 @param a The number to free
42 @return CRYPT_OK on success
43 */
44 void (*deinit)(void *a);
45
46 /* ---- data movement ---- */
47
48 /** negate
49 @param src The number to negate
50 @param dst The destination
51 @return CRYPT_OK on success
52 */
53 int (*neg)(void *src, void *dst);
54
55 /** copy
56 @param src The number to copy from
57 @param dst The number to write to
58 @return CRYPT_OK on success
59 */
60 int (*copy)(void *src, void *dst);
61
62 /* ---- trivial low level functions ---- */
63
64 /** set small constant
65 @param a Number to write to
66 @param n Source upto bits_per_digit (actually meant for very small constants)
67 @return CRYPT_OK on succcess
68 */
69 int (*set_int)(void *a, unsigned long n);
70
71 /** get small constant
72 @param a Number to read, only fetches upto bits_per_digit from the number
73 @return The lower bits_per_digit of the integer (unsigned)
74 */
75 unsigned long (*get_int)(void *a);
76
77 /** get digit n
78 @param a The number to read from
79 @param n The number of the digit to fetch
80 @return The bits_per_digit sized n'th digit of a
81 */
82 unsigned long (*get_digit)(void *a, int n);
83
84 /** Get the number of digits that represent the number
85 @param a The number to count
86 @return The number of digits used to represent the number
87 */
88 int (*get_digit_count)(void *a);
89
90 /** compare two integers
91 @param a The left side integer
92 @param b The right side integer
93 @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison)
94 */
95 int (*compare)(void *a, void *b);
96
97 /** compare against int
98 @param a The left side integer
99 @param b The right side integer (upto bits_per_digit)
100 @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison)
101 */
102 int (*compare_d)(void *a, unsigned long n);
103
104 /** Count the number of bits used to represent the integer
105 @param a The integer to count
106 @return The number of bits required to represent the integer
107 */
108 int (*count_bits)(void * a);
109
110 /** Count the number of LSB bits which are zero
111 @param a The integer to count
112 @return The number of contiguous zero LSB bits
113 */
114 int (*count_lsb_bits)(void *a);
115
116 /** Compute a power of two
117 @param a The integer to store the power in
118 @param n The power of two you want to store (a = 2^n)
119 @return CRYPT_OK on success
120 */
121 int (*twoexpt)(void *a , int n);
122
123 /* ---- radix conversions ---- */
124
125 /** read ascii string
126 @param a The integer to store into
127 @param str The string to read
128 @param radix The radix the integer has been represented in (2-64)
129 @return CRYPT_OK on success
130 */
131 int (*read_radix)(void *a, const char *str, int radix);
132
133 /** write number to string
134 @param a The integer to store
135 @param str The destination for the string
136 @param radix The radix the integer is to be represented in (2-64)
137 @return CRYPT_OK on success
138 */
139 int (*write_radix)(void *a, char *str, int radix);
140
141 /** get size as unsigned char string
142 @param a The integer to get the size (when stored in array of octets)
143 @return The length of the integer
144 */
145 unsigned long (*unsigned_size)(void *a);
146
147 /** store an integer as an array of octets
148 @param src The integer to store
149 @param dst The buffer to store the integer in
150 @return CRYPT_OK on success
151 */
152 int (*unsigned_write)(void *src, unsigned char *dst);
153
154 /** read an array of octets and store as integer
155 @param dst The integer to load
156 @param src The array of octets
157 @param len The number of octets
158 @return CRYPT_OK on success
159 */
160 int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len);
161
162 /* ---- basic math ---- */
163
164 /** add two integers
165 @param a The first source integer
166 @param b The second source integer
167 @param c The destination of "a + b"
168 @return CRYPT_OK on success
169 */
170 int (*add)(void *a, void *b, void *c);
171
172
173 /** add two integers
174 @param a The first source integer
175 @param b The second source integer (single digit of upto bits_per_digit in length)
176 @param c The destination of "a + b"
177 @return CRYPT_OK on success
178 */
179 int (*addi)(void *a, unsigned long b, void *c);
180
181 /** subtract two integers
182 @param a The first source integer
183 @param b The second source integer
184 @param c The destination of "a - b"
185 @return CRYPT_OK on success
186 */
187 int (*sub)(void *a, void *b, void *c);
188
189 /** subtract two integers
190 @param a The first source integer
191 @param b The second source integer (single digit of upto bits_per_digit in length)
192 @param c The destination of "a - b"
193 @return CRYPT_OK on success
194 */
195 int (*subi)(void *a, unsigned long b, void *c);
196
197 /** multiply two integers
198 @param a The first source integer
199 @param b The second source integer (single digit of upto bits_per_digit in length)
200 @param c The destination of "a * b"
201 @return CRYPT_OK on success
202 */
203 int (*mul)(void *a, void *b, void *c);
204
205 /** multiply two integers
206 @param a The first source integer
207 @param b The second source integer (single digit of upto bits_per_digit in length)
208 @param c The destination of "a * b"
209 @return CRYPT_OK on success
210 */
211 int (*muli)(void *a, unsigned long b, void *c);
212
213 /** Square an integer
214 @param a The integer to square
215 @param b The destination
216 @return CRYPT_OK on success
217 */
218 int (*sqr)(void *a, void *b);
219
220 /** Divide an integer
221 @param a The dividend
222 @param b The divisor
223 @param c The quotient (can be NULL to signify don't care)
224 @param d The remainder (can be NULL to signify don't care)
225 @return CRYPT_OK on success
226 */
227 int (*mpdiv)(void *a, void *b, void *c, void *d);
228
229 /** divide by two
230 @param a The integer to divide (shift right)
231 @param b The destination
232 @return CRYPT_OK on success
233 */
234 int (*div_2)(void *a, void *b);
235
236 /** Get remainder (small value)
237 @param a The integer to reduce
238 @param b The modulus (upto bits_per_digit in length)
239 @param c The destination for the residue
240 @return CRYPT_OK on success
241 */
242 int (*modi)(void *a, unsigned long b, unsigned long *c);
243
244 /** gcd
245 @param a The first integer
246 @param b The second integer
247 @param c The destination for (a, b)
248 @return CRYPT_OK on success
249 */
250 int (*gcd)(void *a, void *b, void *c);
251
252 /** lcm
253 @param a The first integer
254 @param b The second integer
255 @param c The destination for [a, b]
256 @return CRYPT_OK on success
257 */
258 int (*lcm)(void *a, void *b, void *c);
259
260 /** Modular multiplication
261 @param a The first source
262 @param b The second source
263 @param c The modulus
264 @param d The destination (a*b mod c)
265 @return CRYPT_OK on success
266 */
267 int (*mulmod)(void *a, void *b, void *c, void *d);
268
269 /** Modular squaring
270 @param a The first source
271 @param b The modulus
272 @param c The destination (a*a mod b)
273 @return CRYPT_OK on success
274 */
275 int (*sqrmod)(void *a, void *b, void *c);
276
277 /** Modular inversion
278 @param a The value to invert
279 @param b The modulus
280 @param c The destination (1/a mod b)
281 @return CRYPT_OK on success
282 */
283 int (*invmod)(void *, void *, void *);
284
285 /* ---- reduction ---- */
286
287 /** setup montgomery
288 @param a The modulus
289 @param b The destination for the reduction digit
290 @return CRYPT_OK on success
291 */
292 int (*montgomery_setup)(void *a, void **b);
293
294 /** get normalization value
295 @param a The destination for the normalization value
296 @param b The modulus
297 @return CRYPT_OK on success
298 */
299 int (*montgomery_normalization)(void *a, void *b);
300
301 /** reduce a number
302 @param a The number [and dest] to reduce
303 @param b The modulus
304 @param c The value "b" from montgomery_setup()
305 @return CRYPT_OK on success
306 */
307 int (*montgomery_reduce)(void *a, void *b, void *c);
308
309 /** clean up (frees memory)
310 @param a The value "b" from montgomery_setup()
311 @return CRYPT_OK on success
312 */
313 void (*montgomery_deinit)(void *a);
314
315 /* ---- exponentiation ---- */
316
317 /** Modular exponentiation
318 @param a The base integer
319 @param b The power (can be negative) integer
320 @param c The modulus integer
321 @param d The destination
322 @return CRYPT_OK on success
323 */
324 int (*exptmod)(void *a, void *b, void *c, void *d);
325
326 /** Primality testing
327 @param a The integer to test
328 @param b The destination of the result (FP_YES if prime)
329 @return CRYPT_OK on success
330 */
331 int (*isprime)(void *a, int *b);
332
333 /* ---- (optional) ecc point math ---- */
334
335 /** ECC GF(p) point multiplication (from the NIST curves)
336 @param k The integer to multiply the point by
337 @param G The point to multiply
338 @param R The destination for kG
339 @param modulus The modulus for the field
340 @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only)
341 @return CRYPT_OK on success
342 */
343 int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
344
345 /** ECC GF(p) point addition
346 @param P The first point
347 @param Q The second point
348 @param R The destination of P + Q
349 @param modulus The modulus
350 @param mp The "b" value from montgomery_setup()
351 @return CRYPT_OK on success
352 */
353 int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
354
355 /** ECC GF(p) point double
356 @param P The first point
357 @param R The destination of 2P
358 @param modulus The modulus
359 @param mp The "b" value from montgomery_setup()
360 @return CRYPT_OK on success
361 */
362 int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp);
363
364 /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1)
365 @param P The point to map
366 @param modulus The modulus
367 @param mp The "b" value from montgomery_setup()
368 @return CRYPT_OK on success
369 @remark The mapping can be different but keep in mind a ecc_point only has three
370 integers (x,y,z) so if you use a different mapping you have to make it fit.
371 */
372 int (*ecc_map)(ecc_point *P, void *modulus, void *mp);
373
374 /** Computes kA*A + kB*B = C using Shamir's Trick
375 @param A First point to multiply
376 @param kA What to multiple A by
377 @param B Second point to multiply
378 @param kB What to multiple B by
379 @param C [out] Destination point (can overlap with A or B
380 @param modulus Modulus for curve
381 @return CRYPT_OK on success
382 */
383 int (*ecc_mul2add)(ecc_point *A, void *kA,
384 ecc_point *B, void *kB,
385 ecc_point *C,
386 void *modulus);
387
388 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
389
390 /** RSA Key Generation
391 @param prng An active PRNG state
392 @param wprng The index of the PRNG desired
393 @param size The size of the modulus (key size) desired (octets)
394 @param e The "e" value (public key). e==65537 is a good choice
395 @param key [out] Destination of a newly created private key pair
396 @return CRYPT_OK if successful, upon error all allocated ram is freed
397 */
398 int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
399
400
401 /** RSA exponentiation
402 @param in The octet array representing the base
403 @param inlen The length of the input
404 @param out The destination (to be stored in an octet array format)
405 @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus)
406 @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
407 @param key The RSA key to use
408 @return CRYPT_OK on success
409 */
410 int (*rsa_me)(const unsigned char *in, unsigned long inlen,
411 unsigned char *out, unsigned long *outlen, int which,
412 rsa_key *key);
413
414 /* ---- basic math continued ---- */
415
416 /** Modular addition
417 @param a The first source
418 @param b The second source
419 @param c The modulus
420 @param d The destination (a + b mod c)
421 @return CRYPT_OK on success
422 */
423 int (*addmod)(void *a, void *b, void *c, void *d);
424
425 /** Modular substraction
426 @param a The first source
427 @param b The second source
428 @param c The modulus
429 @param d The destination (a - b mod c)
430 @return CRYPT_OK on success
431 */
432 int (*submod)(void *a, void *b, void *c, void *d);
433
434 /* ---- misc stuff ---- */
435 /** Make a pseudo-random mpi
436 @param a The mpi to make random
437 @param size The desired length
438 @return CRYPT_OK on success
439 */
440 int (*rand)(void *a, int size);
441
442 } ltc_math_descriptor;
443
444 extern ltc_math_descriptor ltc_mp;
445
446 int ltc_init_multi(void **a, ...);
447 void ltc_deinit_multi(void *a, ...);
448
449 #ifdef LTM_DESC
450 extern const ltc_math_descriptor ltm_desc;
451 #endif
452
453 #ifdef TFM_DESC
454 extern const ltc_math_descriptor tfm_desc;
455 #endif
456
457 #ifdef GMP_DESC
458 extern const ltc_math_descriptor gmp_desc;
459 #endif
460
461 #if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE)
462
463 #define MP_DIGIT_BIT ltc_mp.bits_per_digit
464
465 /* some handy macros */
466 #define mp_init(a) ltc_mp.init(a)
467 #define mp_init_multi ltc_init_multi
468 #define mp_clear(a) ltc_mp.deinit(a)
469 #define mp_clear_multi ltc_deinit_multi
470 #define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
471
472 #define mp_neg(a, b) ltc_mp.neg(a, b)
473 #define mp_copy(a, b) ltc_mp.copy(a, b)
474
475 #define mp_set(a, b) ltc_mp.set_int(a, b)
476 #define mp_set_int(a, b) ltc_mp.set_int(a, b)
477 #define mp_get_int(a) ltc_mp.get_int(a)
478 #define mp_get_digit(a, n) ltc_mp.get_digit(a, n)
479 #define mp_get_digit_count(a) ltc_mp.get_digit_count(a)
480 #define mp_cmp(a, b) ltc_mp.compare(a, b)
481 #define mp_cmp_d(a, b) ltc_mp.compare_d(a, b)
482 #define mp_count_bits(a) ltc_mp.count_bits(a)
483 #define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a)
484 #define mp_2expt(a, b) ltc_mp.twoexpt(a, b)
485
486 #define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c)
487 #define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c)
488 #define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
489 #define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
490 #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
491
492 #define mp_add(a, b, c) ltc_mp.add(a, b, c)
493 #define mp_add_d(a, b, c) ltc_mp.addi(a, b, c)
494 #define mp_sub(a, b, c) ltc_mp.sub(a, b, c)
495 #define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c)
496 #define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
497 #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
498 #define mp_sqr(a, b) ltc_mp.sqr(a, b)
499 #define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
500 #define mp_div_2(a, b) ltc_mp.div_2(a, b)
501 #define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
502 #define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c)
503 #define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c)
504 #define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c)
505
506 #define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d)
507 #define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d)
508 #define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d)
509 #define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c)
510 #define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c)
511
512 #define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b)
513 #define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)
514 #define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c)
515 #define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a)
516
517 #define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
518 #define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, c)
519
520 #define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)
521 #define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO)
522 #define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0);
523
524 #define mp_tohex(a, b) mp_toradix(a, b, 16)
525
526 #define mp_rand(a, b) ltc_mp.rand(a, b)
527
528 #endif
529
530 /* $Source$ */
531 /* $Revision$ */
532 /* $Date$ */
+0
-29
libtom-src/headers/tomcrypt_misc.h less more
0 /* ---- LTC_BASE64 Routines ---- */
1 #ifdef LTC_BASE64
2 int base64_encode(const unsigned char *in, unsigned long len,
3 unsigned char *out, unsigned long *outlen);
4
5 int base64_decode(const unsigned char *in, unsigned long len,
6 unsigned char *out, unsigned long *outlen);
7
8 int base64url_encode(const unsigned char *in, unsigned long len,
9 unsigned char *out, unsigned long *outlen);
10
11 int base64url_decode(const unsigned char *in, unsigned long len,
12 unsigned char *out, unsigned long *outlen);
13 #endif
14
15 /* ---- MEM routines ---- */
16 void zeromem(volatile void *dst, size_t len);
17 void burn_stack(unsigned long len);
18
19 const char *error_to_string(int err);
20
21 extern const char *crypt_build_settings;
22
23 /* ---- HMM ---- */
24 int crypt_fsa(void *mp, ...);
25
26 /* $Source$ */
27 /* $Revision$ */
28 /* $Date$ */
+0
-632
libtom-src/headers/tomcrypt_pk.h less more
0 /* ---- NUMBER THEORY ---- */
1
2 enum {
3 PK_PUBLIC=0,
4 PK_PRIVATE=1
5 };
6
7 int rand_prime(void *N, long len, prng_state *prng, int wprng);
8
9 enum {
10 PKA_RSA,
11 PKA_DSA
12 };
13
14 typedef struct Oid {
15 unsigned long OID[16];
16 /** Length of DER encoding */
17 unsigned long OIDlen;
18 } oid_st;
19
20 int pk_get_oid(int pk, oid_st *st);
21
22 /* ---- RSA ---- */
23 #ifdef LTC_MRSA
24
25 /* Min and Max RSA key sizes (in bits) */
26 #define MIN_RSA_SIZE 1024
27 #define MAX_RSA_SIZE 4096
28
29 /** RSA LTC_PKCS style key */
30 typedef struct Rsa_key {
31 /** Type of key, PK_PRIVATE or PK_PUBLIC */
32 int type;
33 /** The public exponent */
34 void *e;
35 /** The private exponent */
36 void *d;
37 /** The modulus */
38 void *N;
39 /** The p factor of N */
40 void *p;
41 /** The q factor of N */
42 void *q;
43 /** The 1/q mod p CRT param */
44 void *qP;
45 /** The d mod (p - 1) CRT param */
46 void *dP;
47 /** The d mod (q - 1) CRT param */
48 void *dQ;
49 } rsa_key;
50
51 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
52
53 int rsa_exptmod(const unsigned char *in, unsigned long inlen,
54 unsigned char *out, unsigned long *outlen, int which,
55 rsa_key *key);
56
57 void rsa_free(rsa_key *key);
58
59 /* These use LTC_PKCS #1 v2.0 padding */
60 #define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \
61 rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_PKCS_1_OAEP, _key)
62
63 #define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \
64 rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_PKCS_1_OAEP, _stat, _key)
65
66 #define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \
67 rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key)
68
69 #define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \
70 rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key)
71
72 /* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */
73 int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
74 unsigned char *out, unsigned long *outlen,
75 const unsigned char *lparam, unsigned long lparamlen,
76 prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key);
77
78 int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
79 unsigned char *out, unsigned long *outlen,
80 const unsigned char *lparam, unsigned long lparamlen,
81 int hash_idx, int padding,
82 int *stat, rsa_key *key);
83
84 int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
85 unsigned char *out, unsigned long *outlen,
86 int padding,
87 prng_state *prng, int prng_idx,
88 int hash_idx, unsigned long saltlen,
89 rsa_key *key);
90
91 int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
92 const unsigned char *hash, unsigned long hashlen,
93 int padding,
94 int hash_idx, unsigned long saltlen,
95 int *stat, rsa_key *key);
96
97 /* LTC_PKCS #1 import/export */
98 int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
99 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
100
101 #endif
102
103 /* ---- Katja ---- */
104 #ifdef MKAT
105
106 /* Min and Max KAT key sizes (in bits) */
107 #define MIN_KAT_SIZE 1024
108 #define MAX_KAT_SIZE 4096
109
110 /** Katja LTC_PKCS style key */
111 typedef struct KAT_key {
112 /** Type of key, PK_PRIVATE or PK_PUBLIC */
113 int type;
114 /** The private exponent */
115 void *d;
116 /** The modulus */
117 void *N;
118 /** The p factor of N */
119 void *p;
120 /** The q factor of N */
121 void *q;
122 /** The 1/q mod p CRT param */
123 void *qP;
124 /** The d mod (p - 1) CRT param */
125 void *dP;
126 /** The d mod (q - 1) CRT param */
127 void *dQ;
128 /** The pq param */
129 void *pq;
130 } katja_key;
131
132 int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key);
133
134 int katja_exptmod(const unsigned char *in, unsigned long inlen,
135 unsigned char *out, unsigned long *outlen, int which,
136 katja_key *key);
137
138 void katja_free(katja_key *key);
139
140 /* These use LTC_PKCS #1 v2.0 padding */
141 int katja_encrypt_key(const unsigned char *in, unsigned long inlen,
142 unsigned char *out, unsigned long *outlen,
143 const unsigned char *lparam, unsigned long lparamlen,
144 prng_state *prng, int prng_idx, int hash_idx, katja_key *key);
145
146 int katja_decrypt_key(const unsigned char *in, unsigned long inlen,
147 unsigned char *out, unsigned long *outlen,
148 const unsigned char *lparam, unsigned long lparamlen,
149 int hash_idx, int *stat,
150 katja_key *key);
151
152 /* LTC_PKCS #1 import/export */
153 int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key);
154 int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key);
155
156 #endif
157
158 /* ---- DH Routines ---- */
159 #ifdef MDH
160
161 typedef struct Dh_key {
162 int idx, type;
163 void *x;
164 void *y;
165 } dh_key;
166
167 int dh_compat_test(void);
168 void dh_sizes(int *low, int *high);
169 int dh_get_size(dh_key *key);
170
171 int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key);
172 void dh_free(dh_key *key);
173
174 int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key);
175 int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key);
176
177 int dh_shared_secret(dh_key *private_key, dh_key *public_key,
178 unsigned char *out, unsigned long *outlen);
179
180 int dh_encrypt_key(const unsigned char *in, unsigned long keylen,
181 unsigned char *out, unsigned long *outlen,
182 prng_state *prng, int wprng, int hash,
183 dh_key *key);
184
185 int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
186 unsigned char *out, unsigned long *outlen,
187 dh_key *key);
188
189 int dh_sign_hash(const unsigned char *in, unsigned long inlen,
190 unsigned char *out, unsigned long *outlen,
191 prng_state *prng, int wprng, dh_key *key);
192
193 int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
194 const unsigned char *hash, unsigned long hashlen,
195 int *stat, dh_key *key);
196
197
198 #endif
199
200
201 /* ---- ECC Routines ---- */
202 #ifdef LTC_MECC
203
204 /* size of our temp buffers for exported keys */
205 #define ECC_BUF_SIZE 256
206
207 /* max private key size */
208 #define ECC_MAXSIZE 66
209
210 /** Structure defines a NIST GF(p) curve */
211 typedef struct {
212 /** The size of the curve in octets */
213 int size;
214
215 /** name of curve */
216 char *name;
217
218 /** The prime that defines the field the curve is in (encoded in hex) */
219 char *prime;
220
221 /** The fields B param (hex) */
222 char *B;
223
224 /** The order of the curve (hex) */
225 char *order;
226
227 /** The x co-ordinate of the base point on the curve (hex) */
228 char *Gx;
229
230 /** The y co-ordinate of the base point on the curve (hex) */
231 char *Gy;
232 } ltc_ecc_set_type;
233
234 /** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */
235 typedef struct {
236 /** The x co-ordinate */
237 void *x;
238
239 /** The y co-ordinate */
240 void *y;
241
242 /** The z co-ordinate */
243 void *z;
244 } ecc_point;
245
246 /** An ECC key */
247 typedef struct {
248 /** Type of key, PK_PRIVATE or PK_PUBLIC */
249 int type;
250
251 /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */
252 int idx;
253
254 /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */
255 const ltc_ecc_set_type *dp;
256
257 /** The public key */
258 ecc_point pubkey;
259
260 /** The private key */
261 void *k;
262 } ecc_key;
263
264 /** the ECC params provided */
265 extern const ltc_ecc_set_type ltc_ecc_sets[];
266
267 int ecc_test(void);
268 void ecc_sizes(int *low, int *high);
269 int ecc_get_size(ecc_key *key);
270
271 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
272 int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
273 void ecc_free(ecc_key *key);
274
275 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
276 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
277 int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp);
278
279 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
280 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
281 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
282
283 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
284 unsigned char *out, unsigned long *outlen);
285
286 int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
287 unsigned char *out, unsigned long *outlen,
288 prng_state *prng, int wprng, int hash,
289 ecc_key *key);
290
291 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
292 unsigned char *out, unsigned long *outlen,
293 ecc_key *key);
294
295 int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
296 unsigned char *out, unsigned long *outlen,
297 prng_state *prng, int wprng, ecc_key *key);
298
299 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
300 const unsigned char *hash, unsigned long hashlen,
301 int *stat, ecc_key *key);
302
303 /* low level functions */
304 ecc_point *ltc_ecc_new_point(void);
305 void ltc_ecc_del_point(ecc_point *p);
306 int ltc_ecc_is_valid_idx(int n);
307
308 /* point ops (mp == montgomery digit) */
309 #if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC)
310 /* R = 2P */
311 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
312
313 /* R = P + Q */
314 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
315 #endif
316
317 #if defined(LTC_MECC_FP)
318 /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
319 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
320
321 /* functions for saving/loading/freeing/adding to fixed point cache */
322 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
323 int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen);
324 void ltc_ecc_fp_free(void);
325 int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock);
326
327 /* lock/unlock all points currently in fixed point cache */
328 void ltc_ecc_fp_tablelock(int lock);
329 #endif
330
331 /* R = kG */
332 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
333
334 #ifdef LTC_ECC_SHAMIR
335 /* kA*A + kB*B = C */
336 int ltc_ecc_mul2add(ecc_point *A, void *kA,
337 ecc_point *B, void *kB,
338 ecc_point *C,
339 void *modulus);
340
341 #ifdef LTC_MECC_FP
342 /* Shamir's trick with optimized point multiplication using fixed point cache */
343 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
344 ecc_point *B, void *kB,
345 ecc_point *C, void *modulus);
346 #endif
347
348 #endif
349
350
351 /* map P to affine from projective */
352 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
353
354 #endif
355
356 #ifdef LTC_MDSA
357
358 /* Max diff between group and modulus size in bytes */
359 #define LTC_MDSA_DELTA 512
360
361 /* Max DSA group size in bytes (default allows 4k-bit groups) */
362 #define LTC_MDSA_MAX_GROUP 512
363
364 /** DSA key structure */
365 typedef struct {
366 /** The key type, PK_PRIVATE or PK_PUBLIC */
367 int type;
368
369 /** The order of the sub-group used in octets */
370 int qord;
371
372 /** The generator */
373 void *g;
374
375 /** The prime used to generate the sub-group */
376 void *q;
377
378 /** The large prime that generats the field the contains the sub-group */
379 void *p;
380
381 /** The private key */
382 void *x;
383
384 /** The public key */
385 void *y;
386 } dsa_key;
387
388 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
389 void dsa_free(dsa_key *key);
390
391 int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
392 void *r, void *s,
393 prng_state *prng, int wprng, dsa_key *key);
394
395 int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
396 unsigned char *out, unsigned long *outlen,
397 prng_state *prng, int wprng, dsa_key *key);
398
399 int dsa_verify_hash_raw( void *r, void *s,
400 const unsigned char *hash, unsigned long hashlen,
401 int *stat, dsa_key *key);
402
403 int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
404 const unsigned char *hash, unsigned long hashlen,
405 int *stat, dsa_key *key);
406
407 int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
408 unsigned char *out, unsigned long *outlen,
409 prng_state *prng, int wprng, int hash,
410 dsa_key *key);
411
412 int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
413 unsigned char *out, unsigned long *outlen,
414 dsa_key *key);
415
416 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
417 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
418 int dsa_verify_key(dsa_key *key, int *stat);
419
420 int dsa_shared_secret(void *private_key, void *base,
421 dsa_key *public_key,
422 unsigned char *out, unsigned long *outlen);
423 #endif
424
425 #ifdef LTC_DER
426 /* DER handling */
427
428 enum {
429 LTC_ASN1_EOL,
430 LTC_ASN1_BOOLEAN,
431 LTC_ASN1_INTEGER,
432 LTC_ASN1_SHORT_INTEGER,
433 LTC_ASN1_BIT_STRING,
434 LTC_ASN1_OCTET_STRING,
435 LTC_ASN1_NULL,
436 LTC_ASN1_OBJECT_IDENTIFIER,
437 LTC_ASN1_IA5_STRING,
438 LTC_ASN1_PRINTABLE_STRING,
439 LTC_ASN1_UTF8_STRING,
440 LTC_ASN1_UTCTIME,
441 LTC_ASN1_CHOICE,
442 LTC_ASN1_SEQUENCE,
443 LTC_ASN1_SET,
444 LTC_ASN1_SETOF,
445 LTC_ASN1_RAW_BIT_STRING,
446 LTC_ASN1_TELETEX_STRING,
447 LTC_ASN1_CONSTRUCTED,
448 };
449
450 /** A LTC ASN.1 list type */
451 typedef struct ltc_asn1_list_ {
452 /** The LTC ASN.1 enumerated type identifier */
453 int type;
454 /** The data to encode or place for decoding */
455 void *data;
456 /** The size of the input or resulting output */
457 unsigned long size;
458 /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
459 int used;
460 /** prev/next entry in the list */
461 struct ltc_asn1_list_ *prev, *next, *child, *parent;
462 } ltc_asn1_list;
463
464 #define LTC_SET_ASN1(list, index, Type, Data, Size) \
465 do { \
466 int LTC_MACRO_temp = (index); \
467 ltc_asn1_list *LTC_MACRO_list = (list); \
468 LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
469 LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
470 LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
471 LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
472 } while (0);
473
474 /* SEQUENCE */
475 int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
476 unsigned char *out, unsigned long *outlen, int type_of);
477
478 #define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE)
479
480 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
481 ltc_asn1_list *list, unsigned long outlen, int ordered);
482
483 #define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
484
485 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
486 unsigned long *outlen);
487
488 /* SUBJECT PUBLIC KEY INFO */
489 int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
490 unsigned int algorithm, void* public_key, unsigned long public_key_len,
491 unsigned long parameters_type, void* parameters, unsigned long parameters_len);
492
493 int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
494 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
495 unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len);
496
497 /* SET */
498 #define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
499 #define der_length_set der_length_sequence
500 int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
501 unsigned char *out, unsigned long *outlen);
502
503 int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
504 unsigned char *out, unsigned long *outlen);
505
506 /* VA list handy helpers with triplets of <type, size, data> */
507 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
508 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
509
510 /* FLEXI DECODER handle unknown list decoder */
511 int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
512 void der_free_sequence_flexi(ltc_asn1_list *list);
513 void der_sequence_free(ltc_asn1_list *in);
514
515 /* BOOLEAN */
516 int der_length_boolean(unsigned long *outlen);
517 int der_encode_boolean(int in,
518 unsigned char *out, unsigned long *outlen);
519 int der_decode_boolean(const unsigned char *in, unsigned long inlen,
520 int *out);
521 /* INTEGER */
522 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
523 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);
524 int der_length_integer(void *num, unsigned long *len);
525
526 /* INTEGER -- handy for 0..2^32-1 values */
527 int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num);
528 int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen);
529 int der_length_short_integer(unsigned long num, unsigned long *outlen);
530
531 /* BIT STRING */
532 int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
533 unsigned char *out, unsigned long *outlen);
534 int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
535 unsigned char *out, unsigned long *outlen);
536 int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
537 unsigned char *out, unsigned long *outlen);
538 int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
539 unsigned char *out, unsigned long *outlen);
540 int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
541
542 /* OCTET STRING */
543 int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
544 unsigned char *out, unsigned long *outlen);
545 int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
546 unsigned char *out, unsigned long *outlen);
547 int der_length_octet_string(unsigned long noctets, unsigned long *outlen);
548
549 /* OBJECT IDENTIFIER */
550 int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
551 unsigned char *out, unsigned long *outlen);
552 int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
553 unsigned long *words, unsigned long *outlen);
554 int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen);
555 unsigned long der_object_identifier_bits(unsigned long x);
556
557 /* IA5 STRING */
558 int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
559 unsigned char *out, unsigned long *outlen);
560 int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
561 unsigned char *out, unsigned long *outlen);
562 int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
563
564 int der_ia5_char_encode(int c);
565 int der_ia5_value_decode(int v);
566
567 /* TELETEX STRING */
568 int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
569 unsigned char *out, unsigned long *outlen);
570 int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
571
572 int der_teletex_char_encode(int c);
573 int der_teletex_value_decode(int v);
574
575 /* PRINTABLE STRING */
576 int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
577 unsigned char *out, unsigned long *outlen);
578 int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
579 unsigned char *out, unsigned long *outlen);
580 int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
581
582 int der_printable_char_encode(int c);
583 int der_printable_value_decode(int v);
584
585 /* UTF-8 */
586 #if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR)
587 #include <wchar.h>
588 #else
589 typedef ulong32 wchar_t;
590 #endif
591
592 int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,
593 unsigned char *out, unsigned long *outlen);
594
595 int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
596 wchar_t *out, unsigned long *outlen);
597 unsigned long der_utf8_charsize(const wchar_t c);
598 int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen);
599
600
601 /* CHOICE */
602 int der_decode_choice(const unsigned char *in, unsigned long *inlen,
603 ltc_asn1_list *list, unsigned long outlen);
604
605 /* UTCTime */
606 typedef struct {
607 unsigned YY, /* year */
608 MM, /* month */
609 DD, /* day */
610 hh, /* hour */
611 mm, /* minute */
612 ss, /* second */
613 off_dir, /* timezone offset direction 0 == +, 1 == - */
614 off_hh, /* timezone offset hours */
615 off_mm; /* timezone offset minutes */
616 } ltc_utctime;
617
618 int der_encode_utctime(ltc_utctime *utctime,
619 unsigned char *out, unsigned long *outlen);
620
621 int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
622 ltc_utctime *out);
623
624 int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
625
626
627 #endif
628
629 /* $Source$ */
630 /* $Revision$ */
631 /* $Date$ */
+0
-89
libtom-src/headers/tomcrypt_pkcs.h less more
0 /* LTC_PKCS Header Info */
1
2 /* ===> LTC_PKCS #1 -- RSA Cryptography <=== */
3 #ifdef LTC_PKCS_1
4
5 enum ltc_pkcs_1_v1_5_blocks
6 {
7 LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */
8 LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */
9 };
10
11 enum ltc_pkcs_1_paddings
12 {
13 LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */
14 LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */
15 LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */
16 };
17
18 int pkcs_1_mgf1( int hash_idx,
19 const unsigned char *seed, unsigned long seedlen,
20 unsigned char *mask, unsigned long masklen);
21
22 int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
23 int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen);
24
25 /* *** v1.5 padding */
26 int pkcs_1_v1_5_encode(const unsigned char *msg,
27 unsigned long msglen,
28 int block_type,
29 unsigned long modulus_bitlen,
30 prng_state *prng,
31 int prng_idx,
32 unsigned char *out,
33 unsigned long *outlen);
34
35 int pkcs_1_v1_5_decode(const unsigned char *msg,
36 unsigned long msglen,
37 int block_type,
38 unsigned long modulus_bitlen,
39 unsigned char *out,
40 unsigned long *outlen,
41 int *is_valid);
42
43 /* *** v2.1 padding */
44 int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
45 const unsigned char *lparam, unsigned long lparamlen,
46 unsigned long modulus_bitlen, prng_state *prng,
47 int prng_idx, int hash_idx,
48 unsigned char *out, unsigned long *outlen);
49
50 int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
51 const unsigned char *lparam, unsigned long lparamlen,
52 unsigned long modulus_bitlen, int hash_idx,
53 unsigned char *out, unsigned long *outlen,
54 int *res);
55
56 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
57 unsigned long saltlen, prng_state *prng,
58 int prng_idx, int hash_idx,
59 unsigned long modulus_bitlen,
60 unsigned char *out, unsigned long *outlen);
61
62 int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
63 const unsigned char *sig, unsigned long siglen,
64 unsigned long saltlen, int hash_idx,
65 unsigned long modulus_bitlen, int *res);
66
67 #endif /* LTC_PKCS_1 */
68
69 /* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */
70 #ifdef LTC_PKCS_5
71
72 /* Algorithm #1 (old) */
73 int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
74 const unsigned char *salt,
75 int iteration_count, int hash_idx,
76 unsigned char *out, unsigned long *outlen);
77
78 /* Algorithm #2 (new) */
79 int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
80 const unsigned char *salt, unsigned long salt_len,
81 int iteration_count, int hash_idx,
82 unsigned char *out, unsigned long *outlen);
83
84 #endif /* LTC_PKCS_5 */
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
+0
-199
libtom-src/headers/tomcrypt_prng.h less more
0 /* ---- PRNG Stuff ---- */
1 #ifdef LTC_YARROW
2 struct yarrow_prng {
3 int cipher, hash;
4 unsigned char pool[MAXBLOCKSIZE];
5 symmetric_CTR ctr;
6 LTC_MUTEX_TYPE(prng_lock)
7 };
8 #endif
9
10 #ifdef LTC_RC4
11 struct rc4_prng {
12 int x, y;
13 unsigned char buf[256];
14 };
15 #endif
16
17 #ifdef LTC_FORTUNA
18 struct fortuna_prng {
19 hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */
20
21 symmetric_key skey;
22
23 unsigned char K[32], /* the current key */
24 IV[16]; /* IV for CTR mode */
25
26 unsigned long pool_idx, /* current pool we will add to */
27 pool0_len, /* length of 0'th pool */
28 wd;
29
30 ulong64 reset_cnt; /* number of times we have reset */
31 LTC_MUTEX_TYPE(prng_lock)
32 };
33 #endif
34
35 #ifdef LTC_SOBER128
36 struct sober128_prng {
37 ulong32 R[17], /* Working storage for the shift register */
38 initR[17], /* saved register contents */
39 konst, /* key dependent constant */
40 sbuf; /* partial word encryption buffer */
41
42 int nbuf, /* number of part-word stream bits buffered */
43 flag, /* first add_entropy call or not? */
44 set; /* did we call add_entropy to set key? */
45
46 };
47 #endif
48
49 typedef union Prng_state {
50 char dummy[1];
51 #ifdef LTC_YARROW
52 struct yarrow_prng yarrow;
53 #endif
54 #ifdef LTC_RC4
55 struct rc4_prng rc4;
56 #endif
57 #ifdef LTC_FORTUNA
58 struct fortuna_prng fortuna;
59 #endif
60 #ifdef LTC_SOBER128
61 struct sober128_prng sober128;
62 #endif
63 } prng_state;
64
65 /** PRNG descriptor */
66 extern struct ltc_prng_descriptor {
67 /** Name of the PRNG */
68 char *name;
69 /** size in bytes of exported state */
70 int export_size;
71 /** Start a PRNG state
72 @param prng [out] The state to initialize
73 @return CRYPT_OK if successful
74 */
75 int (*start)(prng_state *prng);
76 /** Add entropy to the PRNG
77 @param in The entropy
78 @param inlen Length of the entropy (octets)\
79 @param prng The PRNG state
80 @return CRYPT_OK if successful
81 */
82 int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng);
83 /** Ready a PRNG state to read from
84 @param prng The PRNG state to ready
85 @return CRYPT_OK if successful
86 */
87 int (*ready)(prng_state *prng);
88 /** Read from the PRNG
89 @param out [out] Where to store the data
90 @param outlen Length of data desired (octets)
91 @param prng The PRNG state to read from
92 @return Number of octets read
93 */
94 unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng);
95 /** Terminate a PRNG state
96 @param prng The PRNG state to terminate
97 @return CRYPT_OK if successful
98 */
99 int (*done)(prng_state *prng);
100 /** Export a PRNG state
101 @param out [out] The destination for the state
102 @param outlen [in/out] The max size and resulting size of the PRNG state
103 @param prng The PRNG to export
104 @return CRYPT_OK if successful
105 */
106 int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng);
107 /** Import a PRNG state
108 @param in The data to import
109 @param inlen The length of the data to import (octets)
110 @param prng The PRNG to initialize/import
111 @return CRYPT_OK if successful
112 */
113 int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng);
114 /** Self-test the PRNG
115 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
116 */
117 int (*test)(void);
118 } prng_descriptor[];
119
120 #ifdef LTC_YARROW
121 int yarrow_start(prng_state *prng);
122 int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
123 int yarrow_ready(prng_state *prng);
124 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng);
125 int yarrow_done(prng_state *prng);
126 int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
127 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
128 int yarrow_test(void);
129 extern const struct ltc_prng_descriptor yarrow_desc;
130 #endif
131
132 #ifdef LTC_FORTUNA
133 int fortuna_start(prng_state *prng);
134 int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
135 int fortuna_ready(prng_state *prng);
136 unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng);
137 int fortuna_done(prng_state *prng);
138 int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
139 int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
140 int fortuna_test(void);
141 extern const struct ltc_prng_descriptor fortuna_desc;
142 #endif
143
144 #ifdef LTC_RC4
145 int rc4_start(prng_state *prng);
146 int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
147 int rc4_ready(prng_state *prng);
148 unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng);
149 int rc4_done(prng_state *prng);
150 int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
151 int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
152 int rc4_test(void);
153 extern const struct ltc_prng_descriptor rc4_desc;
154 #endif
155
156 #ifdef LTC_SPRNG
157 int sprng_start(prng_state *prng);
158 int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
159 int sprng_ready(prng_state *prng);
160 unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng);
161 int sprng_done(prng_state *prng);
162 int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
163 int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
164 int sprng_test(void);
165 extern const struct ltc_prng_descriptor sprng_desc;
166 #endif
167
168 #ifdef LTC_SOBER128
169 int sober128_start(prng_state *prng);
170 int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
171 int sober128_ready(prng_state *prng);
172 unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng);
173 int sober128_done(prng_state *prng);
174 int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
175 int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
176 int sober128_test(void);
177 extern const struct ltc_prng_descriptor sober128_desc;
178 #endif
179
180 int find_prng(const char *name);
181 int register_prng(const struct ltc_prng_descriptor *prng);
182 int unregister_prng(const struct ltc_prng_descriptor *prng);
183 int prng_is_valid(int idx);
184 LTC_MUTEX_PROTO(ltc_prng_mutex)
185
186 /* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this
187 * might not work on all platforms as planned
188 */
189 unsigned long rng_get_bytes(unsigned char *out,
190 unsigned long outlen,
191 void (*callback)(void));
192
193 int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
194
195
196 /* $Source$ */
197 /* $Revision$ */
198 /* $Date$ */
+0
-77
libtom-src/mac/f9/f9_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_done.c
14 f9 Support, terminate the state
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /** Terminate the f9-MAC state
20 @param f9 f9 state to terminate
21 @param out [out] Destination for the MAC tag
22 @param outlen [in/out] Destination size and final tag size
23 Return CRYPT_OK on success
24 */
25 int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen)
26 {
27 int err, x;
28 LTC_ARGCHK(f9 != NULL);
29 LTC_ARGCHK(out != NULL);
30
31 /* check structure */
32 if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) {
33 return err;
34 }
35
36 if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) ||
37 (f9->buflen > f9->blocksize) || (f9->buflen < 0)) {
38 return CRYPT_INVALID_ARG;
39 }
40
41 if (f9->buflen != 0) {
42 /* encrypt */
43 cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key);
44 f9->buflen = 0;
45 for (x = 0; x < f9->blocksize; x++) {
46 f9->ACC[x] ^= f9->IV[x];
47 }
48 }
49
50 /* schedule modified key */
51 if ((err = cipher_descriptor[f9->cipher].setup(f9->akey, f9->keylen, 0, &f9->key)) != CRYPT_OK) {
52 return err;
53 }
54
55 /* encrypt the ACC */
56 cipher_descriptor[f9->cipher].ecb_encrypt(f9->ACC, f9->ACC, &f9->key);
57 cipher_descriptor[f9->cipher].done(&f9->key);
58
59 /* extract tag */
60 for (x = 0; x < f9->blocksize && (unsigned long)x < *outlen; x++) {
61 out[x] = f9->ACC[x];
62 }
63 *outlen = x;
64
65 #ifdef LTC_CLEAN_STACK
66 zeromem(f9, sizeof(*f9));
67 #endif
68 return CRYPT_OK;
69 }
70
71 #endif
72
73 /* $Source$ */
74 /* $Revision$ */
75 /* $Date$ */
76
+0
-83
libtom-src/mac/f9/f9_file.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_file.c
14 f9 support, process a file, Tom St Denis
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /**
20 f9 a file
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param filename The name of the file you wish to f9
25 @param out [out] Where the authentication tag is to be stored
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int f9_file(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const char *filename,
32 unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35 return CRYPT_NOP;
36 #else
37 int err, x;
38 f9_state f9;
39 FILE *in;
40 unsigned char buf[512];
41
42 LTC_ARGCHK(key != NULL);
43 LTC_ARGCHK(filename != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 in = fopen(filename, "rb");
48 if (in == NULL) {
49 return CRYPT_FILE_NOTFOUND;
50 }
51
52 if ((err = f9_init(&f9, cipher, key, keylen)) != CRYPT_OK) {
53 fclose(in);
54 return err;
55 }
56
57 do {
58 x = fread(buf, 1, sizeof(buf), in);
59 if ((err = f9_process(&f9, buf, x)) != CRYPT_OK) {
60 fclose(in);
61 return err;
62 }
63 } while (x == sizeof(buf));
64 fclose(in);
65
66 if ((err = f9_done(&f9, out, outlen)) != CRYPT_OK) {
67 return err;
68 }
69
70 #ifdef LTC_CLEAN_STACK
71 zeromem(buf, sizeof(buf));
72 #endif
73
74 return CRYPT_OK;
75 #endif
76 }
77
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
+0
-70
libtom-src/mac/f9/f9_init.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_init.c
14 F9 Support, start an F9 state
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /** Initialize F9-MAC state
20 @param f9 [out] f9 state to initialize
21 @param cipher Index of cipher to use
22 @param key [in] Secret key
23 @param keylen Length of secret key in octets
24 Return CRYPT_OK on success
25 */
26 int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen)
27 {
28 int x, err;
29
30 LTC_ARGCHK(f9 != NULL);
31 LTC_ARGCHK(key != NULL);
32
33 /* schedule the key */
34 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
35 return err;
36 }
37
38 #ifdef LTC_FAST
39 if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
40 return CRYPT_INVALID_ARG;
41 }
42 #endif
43
44 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &f9->key)) != CRYPT_OK) {
45 goto done;
46 }
47
48 /* make the second key */
49 for (x = 0; (unsigned)x < keylen; x++) {
50 f9->akey[x] = key[x] ^ 0xAA;
51 }
52
53 /* setup struct */
54 zeromem(f9->IV, cipher_descriptor[cipher].block_length);
55 zeromem(f9->ACC, cipher_descriptor[cipher].block_length);
56 f9->blocksize = cipher_descriptor[cipher].block_length;
57 f9->cipher = cipher;
58 f9->buflen = 0;
59 f9->keylen = keylen;
60 done:
61 return err;
62 }
63
64 #endif
65
66 /* $Source$ */
67 /* $Revision$ */
68 /* $Date$ */
69
+0
-71
libtom-src/mac/f9/f9_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_process.c
14 f9 Support, Process a block through F9-MAC
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /** f9-MAC a block of memory
20 @param cipher Index of cipher to use
21 @param key [in] Secret key
22 @param keylen Length of key in octets
23 @param in [in] Message to MAC
24 @param inlen Length of input in octets
25 @param out [out] Destination for the MAC tag
26 @param outlen [in/out] Output size and final tag size
27 Return CRYPT_OK on success.
28 */
29 int f9_memory(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long *outlen)
33 {
34 f9_state *f9;
35 int err;
36
37 /* is the cipher valid? */
38 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* Use accelerator if found */
43 if (cipher_descriptor[cipher].f9_memory != NULL) {
44 return cipher_descriptor[cipher].f9_memory(key, keylen, in, inlen, out, outlen);
45 }
46
47 f9 = XCALLOC(1, sizeof(*f9));
48 if (f9 == NULL) {
49 return CRYPT_MEM;
50 }
51
52 if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) {
53 goto done;
54 }
55
56 if ((err = f9_process(f9, in, inlen)) != CRYPT_OK) {
57 goto done;
58 }
59
60 err = f9_done(f9, out, outlen);
61 done:
62 XFREE(f9);
63 return err;
64 }
65
66 #endif
67
68 /* $Source$ */
69 /* $Revision$ */
70 /* $Date$ */
+0
-90
libtom-src/mac/f9/f9_memory_multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file f9_memory_multi.c
15 f9 support, process multiple blocks of memory, Tom St Denis
16 */
17
18 #ifdef LTC_F9_MODE
19
20 /**
21 f9 multiple blocks of memory
22 @param cipher The index of the desired cipher
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] The destination of the authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag (octets)
27 @param in The data to send through f9
28 @param inlen The length of the data to send through f9 (octets)
29 @param ... tuples of (data,len) pairs to f9, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int f9_memory_multi(int cipher,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36 {
37 int err;
38 f9_state *f9;
39 va_list args;
40 const unsigned char *curptr;
41 unsigned long curlen;
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 /* allocate ram for f9 state */
49 f9 = XMALLOC(sizeof(f9_state));
50 if (f9 == NULL) {
51 return CRYPT_MEM;
52 }
53
54 /* f9 process the message */
55 if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58 va_start(args, inlen);
59 curptr = in;
60 curlen = inlen;
61 for (;;) {
62 /* process buf */
63 if ((err = f9_process(f9, curptr, curlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 /* step to next */
67 curptr = va_arg(args, const unsigned char*);
68 if (curptr == NULL) {
69 break;
70 }
71 curlen = va_arg(args, unsigned long);
72 }
73 if ((err = f9_done(f9, out, outlen)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76 LBL_ERR:
77 #ifdef LTC_CLEAN_STACK
78 zeromem(f9, sizeof(f9_state));
79 #endif
80 XFREE(f9);
81 va_end(args);
82 return err;
83 }
84
85 #endif
86
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
+0
-78
libtom-src/mac/f9/f9_process.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_process.c
14 f9 Support, process blocks with f9
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /** Process data through f9-MAC
20 @param f9 The f9-MAC state
21 @param in Input data to process
22 @param inlen Length of input in octets
23 Return CRYPT_OK on success
24 */
25 int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen)
26 {
27 int err, x;
28
29 LTC_ARGCHK(f9 != NULL);
30 LTC_ARGCHK(in != NULL);
31
32 /* check structure */
33 if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) {
34 return err;
35 }
36
37 if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) ||
38 (f9->buflen > f9->blocksize) || (f9->buflen < 0)) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 #ifdef LTC_FAST
43 if (f9->buflen == 0) {
44 while (inlen >= (unsigned long)f9->blocksize) {
45 for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) {
46 *((LTC_FAST_TYPE*)&(f9->IV[x])) ^= *((LTC_FAST_TYPE*)&(in[x]));
47 }
48 cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key);
49 for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) {
50 *((LTC_FAST_TYPE*)&(f9->ACC[x])) ^= *((LTC_FAST_TYPE*)&(f9->IV[x]));
51 }
52 in += f9->blocksize;
53 inlen -= f9->blocksize;
54 }
55 }
56 #endif
57
58 while (inlen) {
59 if (f9->buflen == f9->blocksize) {
60 cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key);
61 for (x = 0; x < f9->blocksize; x++) {
62 f9->ACC[x] ^= f9->IV[x];
63 }
64 f9->buflen = 0;
65 }
66 f9->IV[f9->buflen++] ^= *in++;
67 --inlen;
68 }
69 return CRYPT_OK;
70 }
71
72 #endif
73
74 /* $Source$ */
75 /* $Revision$ */
76 /* $Date$ */
77
+0
-109
libtom-src/mac/hmac/hmac_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_done.c
14 LTC_HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
20
21 /**
22 Terminate an LTC_HMAC session
23 @param hmac The LTC_HMAC state
24 @param out [out] The destination of the LTC_HMAC authentication tag
25 @param outlen [in/out] The max size and resulting size of the LTC_HMAC authentication tag
26 @return CRYPT_OK if successful
27 */
28 int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
29 {
30 unsigned char *buf, *isha;
31 unsigned long hashsize, i;
32 int hash, err;
33
34 LTC_ARGCHK(hmac != NULL);
35 LTC_ARGCHK(out != NULL);
36
37 /* test hash */
38 hash = hmac->hash;
39 if((err = hash_is_valid(hash)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* get the hash message digest size */
44 hashsize = hash_descriptor[hash].hashsize;
45
46 /* allocate buffers */
47 buf = XMALLOC(LTC_HMAC_BLOCKSIZE);
48 isha = XMALLOC(hashsize);
49 if (buf == NULL || isha == NULL) {
50 if (buf != NULL) {
51 XFREE(buf);
52 }
53 if (isha != NULL) {
54 XFREE(isha);
55 }
56 return CRYPT_MEM;
57 }
58
59 /* Get the hash of the first LTC_HMAC vector plus the data */
60 if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
61 goto LBL_ERR;
62 }
63
64 /* Create the second LTC_HMAC vector vector for step (3) */
65 for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) {
66 buf[i] = hmac->key[i] ^ 0x5C;
67 }
68
69 /* Now calculate the "outer" hash for step (5), (6), and (7) */
70 if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
71 goto LBL_ERR;
72 }
73 if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76 if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79 if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) {
80 goto LBL_ERR;
81 }
82
83 /* copy to output */
84 for (i = 0; i < hashsize && i < *outlen; i++) {
85 out[i] = buf[i];
86 }
87 *outlen = i;
88
89 err = CRYPT_OK;
90 LBL_ERR:
91 XFREE(hmac->key);
92 #ifdef LTC_CLEAN_STACK
93 zeromem(isha, hashsize);
94 zeromem(buf, hashsize);
95 zeromem(hmac, sizeof(*hmac));
96 #endif
97
98 XFREE(isha);
99 XFREE(buf);
100
101 return err;
102 }
103
104 #endif
105
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
+0
-93
libtom-src/mac/hmac/hmac_file.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_file.c
14 LTC_HMAC support, process a file, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 /**
20 LTC_HMAC a file
21 @param hash The index of the hash you wish to use
22 @param fname The name of the file you wish to LTC_HMAC
23 @param key The secret key
24 @param keylen The length of the secret key
25 @param out [out] The LTC_HMAC authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int hmac_file(int hash, const char *fname,
30 const unsigned char *key, unsigned long keylen,
31 unsigned char *out, unsigned long *outlen)
32 {
33 #ifdef LTC_NO_FILE
34 return CRYPT_NOP;
35 #else
36 hmac_state hmac;
37 FILE *in;
38 unsigned char buf[512];
39 size_t x;
40 int err;
41
42 LTC_ARGCHK(fname != NULL);
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 if((err = hash_is_valid(hash)) != CRYPT_OK) {
48 return err;
49 }
50
51 if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
52 return err;
53 }
54
55 in = fopen(fname, "rb");
56 if (in == NULL) {
57 return CRYPT_FILE_NOTFOUND;
58 }
59
60 /* process the file contents */
61 do {
62 x = fread(buf, 1, sizeof(buf), in);
63 if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) {
64 /* we don't trap this error since we're already returning an error! */
65 fclose(in);
66 return err;
67 }
68 } while (x == sizeof(buf));
69
70 if (fclose(in) != 0) {
71 return CRYPT_ERROR;
72 }
73
74 /* get final hmac */
75 if ((err = hmac_done(&hmac, out, outlen)) != CRYPT_OK) {
76 return err;
77 }
78
79 #ifdef LTC_CLEAN_STACK
80 /* clear memory */
81 zeromem(buf, sizeof(buf));
82 #endif
83 return CRYPT_OK;
84 #endif
85 }
86
87 #endif
88
89
90 /* $Source$ */
91 /* $Revision$ */
92 /* $Date$ */
+0
-112
libtom-src/mac/hmac/hmac_init.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_init.c
14 LTC_HMAC support, initialize state, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
20
21 /**
22 Initialize an LTC_HMAC context.
23 @param hmac The LTC_HMAC state
24 @param hash The index of the hash you want to use
25 @param key The secret key
26 @param keylen The length of the secret key (octets)
27 @return CRYPT_OK if successful
28 */
29 int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen)
30 {
31 unsigned char *buf;
32 unsigned long hashsize;
33 unsigned long i, z;
34 int err;
35
36 LTC_ARGCHK(hmac != NULL);
37 LTC_ARGCHK(key != NULL);
38
39 /* valid hash? */
40 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
41 return err;
42 }
43 hmac->hash = hash;
44 hashsize = hash_descriptor[hash].hashsize;
45
46 /* valid key length? */
47 if (keylen == 0) {
48 return CRYPT_INVALID_KEYSIZE;
49 }
50
51 /* allocate ram for buf */
52 buf = XMALLOC(LTC_HMAC_BLOCKSIZE);
53 if (buf == NULL) {
54 return CRYPT_MEM;
55 }
56
57 /* allocate memory for key */
58 hmac->key = XMALLOC(LTC_HMAC_BLOCKSIZE);
59 if (hmac->key == NULL) {
60 XFREE(buf);
61 return CRYPT_MEM;
62 }
63
64 /* (1) make sure we have a large enough key */
65 if(keylen > LTC_HMAC_BLOCKSIZE) {
66 z = LTC_HMAC_BLOCKSIZE;
67 if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) {
68 goto LBL_ERR;
69 }
70 if(hashsize < LTC_HMAC_BLOCKSIZE) {
71 zeromem((hmac->key) + hashsize, (size_t)(LTC_HMAC_BLOCKSIZE - hashsize));
72 }
73 keylen = hashsize;
74 } else {
75 XMEMCPY(hmac->key, key, (size_t)keylen);
76 if(keylen < LTC_HMAC_BLOCKSIZE) {
77 zeromem((hmac->key) + keylen, (size_t)(LTC_HMAC_BLOCKSIZE - keylen));
78 }
79 }
80
81 /* Create the initial vector for step (3) */
82 for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) {
83 buf[i] = hmac->key[i] ^ 0x36;
84 }
85
86 /* Pre-pend that to the hash data */
87 if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
88 goto LBL_ERR;
89 }
90
91 if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) {
92 goto LBL_ERR;
93 }
94 goto done;
95 LBL_ERR:
96 /* free the key since we failed */
97 XFREE(hmac->key);
98 done:
99 #ifdef LTC_CLEAN_STACK
100 zeromem(buf, LTC_HMAC_BLOCKSIZE);
101 #endif
102
103 XFREE(buf);
104 return err;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
+0
-88
libtom-src/mac/hmac/hmac_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_memory.c
14 LTC_HMAC support, process a block of memory, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 /**
20 LTC_HMAC a block of memory to produce the authentication tag
21 @param hash The index of the hash to use
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param in The data to LTC_HMAC
25 @param inlen The length of the data to LTC_HMAC (octets)
26 @param out [out] Destination of the authentication tag
27 @param outlen [in/out] Max size and resulting size of authentication tag
28 @return CRYPT_OK if successful
29 */
30 int hmac_memory(int hash,
31 const unsigned char *key, unsigned long keylen,
32 const unsigned char *in, unsigned long inlen,
33 unsigned char *out, unsigned long *outlen)
34 {
35 hmac_state *hmac;
36 int err;
37
38 LTC_ARGCHK(key != NULL);
39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL);
42
43 /* make sure hash descriptor is valid */
44 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* is there a descriptor? */
49 if (hash_descriptor[hash].hmac_block != NULL) {
50 return hash_descriptor[hash].hmac_block(key, keylen, in, inlen, out, outlen);
51 }
52
53 /* nope, so call the hmac functions */
54 /* allocate ram for hmac state */
55 hmac = XMALLOC(sizeof(hmac_state));
56 if (hmac == NULL) {
57 return CRYPT_MEM;
58 }
59
60 if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) {
61 goto LBL_ERR;
62 }
63
64 if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) {
65 goto LBL_ERR;
66 }
67
68 if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) {
69 goto LBL_ERR;
70 }
71
72 err = CRYPT_OK;
73 LBL_ERR:
74 #ifdef LTC_CLEAN_STACK
75 zeromem(hmac, sizeof(hmac_state));
76 #endif
77
78 XFREE(hmac);
79 return err;
80 }
81
82 #endif
83
84
85 /* $Source$ */
86 /* $Revision$ */
87 /* $Date$ */
+0
-92
libtom-src/mac/hmac/hmac_memory_multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file hmac_memory_multi.c
15 LTC_HMAC support, process multiple blocks of memory, Tom St Denis/Dobes Vandermeer
16 */
17
18 #ifdef LTC_HMAC
19
20 /**
21 LTC_HMAC multiple blocks of memory to produce the authentication tag
22 @param hash The index of the hash to use
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] Destination of the authentication tag
26 @param outlen [in/out] Max size and resulting size of authentication tag
27 @param in The data to LTC_HMAC
28 @param inlen The length of the data to LTC_HMAC (octets)
29 @param ... tuples of (data,len) pairs to LTC_HMAC, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int hmac_memory_multi(int hash,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36
37 {
38 hmac_state *hmac;
39 int err;
40 va_list args;
41 const unsigned char *curptr;
42 unsigned long curlen;
43
44 LTC_ARGCHK(key != NULL);
45 LTC_ARGCHK(in != NULL);
46 LTC_ARGCHK(out != NULL);
47 LTC_ARGCHK(outlen != NULL);
48
49 /* allocate ram for hmac state */
50 hmac = XMALLOC(sizeof(hmac_state));
51 if (hmac == NULL) {
52 return CRYPT_MEM;
53 }
54
55 if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58
59 va_start(args, inlen);
60 curptr = in;
61 curlen = inlen;
62 for (;;) {
63 /* process buf */
64 if ((err = hmac_process(hmac, curptr, curlen)) != CRYPT_OK) {
65 goto LBL_ERR;
66 }
67 /* step to next */
68 curptr = va_arg(args, const unsigned char*);
69 if (curptr == NULL) {
70 break;
71 }
72 curlen = va_arg(args, unsigned long);
73 }
74 if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77 LBL_ERR:
78 #ifdef LTC_CLEAN_STACK
79 zeromem(hmac, sizeof(hmac_state));
80 #endif
81 XFREE(hmac);
82 va_end(args);
83 return err;
84 }
85
86 #endif
87
88
89 /* $Source$ */
90 /* $Revision$ */
91 /* $Date$ */
+0
-43
libtom-src/mac/hmac/hmac_process.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_process.c
14 LTC_HMAC support, process data, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 /**
20 Process data through LTC_HMAC
21 @param hmac The hmac state
22 @param in The data to send through LTC_HMAC
23 @param inlen The length of the data to LTC_HMAC (octets)
24 @return CRYPT_OK if successful
25 */
26 int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen)
27 {
28 int err;
29 LTC_ARGCHK(hmac != NULL);
30 LTC_ARGCHK(in != NULL);
31 if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) {
32 return err;
33 }
34 return hash_descriptor[hmac->hash].process(&hmac->md, in, inlen);
35 }
36
37 #endif
38
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
+0
-86
libtom-src/mac/omac/omac_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_done.c
14 LTC_OMAC1 support, terminate a stream, Tom St Denis
15 */
16
17 #ifdef LTC_OMAC
18
19 /**
20 Terminate an LTC_OMAC stream
21 @param omac The LTC_OMAC state
22 @param out [out] Destination for the authentication tag
23 @param outlen [in/out] The max size and resulting size of the authentication tag
24 @return CRYPT_OK if successful
25 */
26 int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen)
27 {
28 int err, mode;
29 unsigned x;
30
31 LTC_ARGCHK(omac != NULL);
32 LTC_ARGCHK(out != NULL);
33 LTC_ARGCHK(outlen != NULL);
34 if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) {
35 return err;
36 }
37
38 if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) ||
39 (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 /* figure out mode */
44 if (omac->buflen != omac->blklen) {
45 /* add the 0x80 byte */
46 omac->block[omac->buflen++] = 0x80;
47
48 /* pad with 0x00 */
49 while (omac->buflen < omac->blklen) {
50 omac->block[omac->buflen++] = 0x00;
51 }
52 mode = 1;
53 } else {
54 mode = 0;
55 }
56
57 /* now xor prev + Lu[mode] */
58 for (x = 0; x < (unsigned)omac->blklen; x++) {
59 omac->block[x] ^= omac->prev[x] ^ omac->Lu[mode][x];
60 }
61
62 /* encrypt it */
63 if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) {
64 return err;
65 }
66 cipher_descriptor[omac->cipher_idx].done(&omac->key);
67
68 /* output it */
69 for (x = 0; x < (unsigned)omac->blklen && x < *outlen; x++) {
70 out[x] = omac->block[x];
71 }
72 *outlen = x;
73
74 #ifdef LTC_CLEAN_STACK
75 zeromem(omac, sizeof(*omac));
76 #endif
77 return CRYPT_OK;
78 }
79
80 #endif
81
82
83 /* $Source$ */
84 /* $Revision$ */
85 /* $Date$ */
+0
-83
libtom-src/mac/omac/omac_file.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_file.c
14 LTC_OMAC1 support, process a file, Tom St Denis
15 */
16
17 #ifdef LTC_OMAC
18
19 /**
20 LTC_OMAC a file
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param filename The name of the file you wish to LTC_OMAC
25 @param out [out] Where the authentication tag is to be stored
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int omac_file(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const char *filename,
32 unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35 return CRYPT_NOP;
36 #else
37 int err, x;
38 omac_state omac;
39 FILE *in;
40 unsigned char buf[512];
41
42 LTC_ARGCHK(key != NULL);
43 LTC_ARGCHK(filename != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 in = fopen(filename, "rb");
48 if (in == NULL) {
49 return CRYPT_FILE_NOTFOUND;
50 }
51
52 if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) {
53 fclose(in);
54 return err;
55 }
56
57 do {
58 x = fread(buf, 1, sizeof(buf), in);
59 if ((err = omac_process(&omac, buf, x)) != CRYPT_OK) {
60 fclose(in);
61 return err;
62 }
63 } while (x == sizeof(buf));
64 fclose(in);
65
66 if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) {
67 return err;
68 }
69
70 #ifdef LTC_CLEAN_STACK
71 zeromem(buf, sizeof(buf));
72 #endif
73
74 return CRYPT_OK;
75 #endif
76 }
77
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
+0
-101
libtom-src/mac/omac/omac_init.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_init.c
14 LTC_OMAC1 support, initialize state, by Tom St Denis
15 */
16
17
18 #ifdef LTC_OMAC
19
20 /**
21 Initialize an LTC_OMAC state
22 @param omac The LTC_OMAC state to initialize
23 @param cipher The index of the desired cipher
24 @param key The secret key
25 @param keylen The length of the secret key (octets)
26 @return CRYPT_OK if successful
27 */
28 int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen)
29 {
30 int err, x, y, mask, msb, len;
31
32 LTC_ARGCHK(omac != NULL);
33 LTC_ARGCHK(key != NULL);
34
35 /* schedule the key */
36 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 #ifdef LTC_FAST
41 if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
42 return CRYPT_INVALID_ARG;
43 }
44 #endif
45
46 /* now setup the system */
47 switch (cipher_descriptor[cipher].block_length) {
48 case 8: mask = 0x1B;
49 len = 8;
50 break;
51 case 16: mask = 0x87;
52 len = 16;
53 break;
54 default: return CRYPT_INVALID_ARG;
55 }
56
57 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) {
58 return err;
59 }
60
61 /* ok now we need Lu and Lu^2 [calc one from the other] */
62
63 /* first calc L which is Ek(0) */
64 zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
65 if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) {
66 return err;
67 }
68
69 /* now do the mults, whoopy! */
70 for (x = 0; x < 2; x++) {
71 /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */
72 msb = omac->Lu[x][0] >> 7;
73
74 /* shift left */
75 for (y = 0; y < (len - 1); y++) {
76 omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255;
77 }
78 omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255;
79
80 /* copy up as require */
81 if (x == 0) {
82 XMEMCPY(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0]));
83 }
84 }
85
86 /* setup state */
87 omac->cipher_idx = cipher;
88 omac->buflen = 0;
89 omac->blklen = len;
90 zeromem(omac->prev, sizeof(omac->prev));
91 zeromem(omac->block, sizeof(omac->block));
92
93 return CRYPT_OK;
94 }
95
96 #endif
97
98 /* $Source$ */
99 /* $Revision$ */
100 /* $Date$ */
+0
-85
libtom-src/mac/omac/omac_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_memory.c
14 LTC_OMAC1 support, process a block of memory, Tom St Denis
15 */
16
17 #ifdef LTC_OMAC
18
19 /**
20 LTC_OMAC a block of memory
21 @param cipher The index of the desired cipher
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param in The data to send through LTC_OMAC
25 @param inlen The length of the data to send through LTC_OMAC (octets)
26 @param out [out] The destination of the authentication tag
27 @param outlen [in/out] The max size and resulting size of the authentication tag (octets)
28 @return CRYPT_OK if successful
29 */
30 int omac_memory(int cipher,
31 const unsigned char *key, unsigned long keylen,
32 const unsigned char *in, unsigned long inlen,
33 unsigned char *out, unsigned long *outlen)
34 {
35 int err;
36 omac_state *omac;
37
38 LTC_ARGCHK(key != NULL);
39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL);
42
43 /* is the cipher valid? */
44 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* Use accelerator if found */
49 if (cipher_descriptor[cipher].omac_memory != NULL) {
50 return cipher_descriptor[cipher].omac_memory(key, keylen, in, inlen, out, outlen);
51 }
52
53 /* allocate ram for omac state */
54 omac = XMALLOC(sizeof(omac_state));
55 if (omac == NULL) {
56 return CRYPT_MEM;
57 }
58
59 /* omac process the message */
60 if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
61 goto LBL_ERR;
62 }
63 if ((err = omac_process(omac, in, inlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) {
67 goto LBL_ERR;
68 }
69
70 err = CRYPT_OK;
71 LBL_ERR:
72 #ifdef LTC_CLEAN_STACK
73 zeromem(omac, sizeof(omac_state));
74 #endif
75
76 XFREE(omac);
77 return err;
78 }
79
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
+0
-90
libtom-src/mac/omac/omac_memory_multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file omac_memory_multi.c
15 LTC_OMAC1 support, process multiple blocks of memory, Tom St Denis
16 */
17
18 #ifdef LTC_OMAC
19
20 /**
21 LTC_OMAC multiple blocks of memory
22 @param cipher The index of the desired cipher
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] The destination of the authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag (octets)
27 @param in The data to send through LTC_OMAC
28 @param inlen The length of the data to send through LTC_OMAC (octets)
29 @param ... tuples of (data,len) pairs to LTC_OMAC, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int omac_memory_multi(int cipher,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36 {
37 int err;
38 omac_state *omac;
39 va_list args;
40 const unsigned char *curptr;
41 unsigned long curlen;
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 /* allocate ram for omac state */
49 omac = XMALLOC(sizeof(omac_state));
50 if (omac == NULL) {
51 return CRYPT_MEM;
52 }
53
54 /* omac process the message */
55 if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58 va_start(args, inlen);
59 curptr = in;
60 curlen = inlen;
61 for (;;) {
62 /* process buf */
63 if ((err = omac_process(omac, curptr, curlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 /* step to next */
67 curptr = va_arg(args, const unsigned char*);
68 if (curptr == NULL) {
69 break;
70 }
71 curlen = va_arg(args, unsigned long);
72 }
73 if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76 LBL_ERR:
77 #ifdef LTC_CLEAN_STACK
78 zeromem(omac, sizeof(omac_state));
79 #endif
80 XFREE(omac);
81 va_end(args);
82 return err;
83 }
84
85 #endif
86
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
+0
-93
libtom-src/mac/omac/omac_process.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_process.c
14 LTC_OMAC1 support, process data, Tom St Denis
15 */
16
17
18 #ifdef LTC_OMAC
19
20 /**
21 Process data through LTC_OMAC
22 @param omac The LTC_OMAC state
23 @param in The input data to send through LTC_OMAC
24 @param inlen The length of the input (octets)
25 @return CRYPT_OK if successful
26 */
27 int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
28 {
29 unsigned long n, x;
30 int err;
31
32 LTC_ARGCHK(omac != NULL);
33 LTC_ARGCHK(in != NULL);
34 if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) {
35 return err;
36 }
37
38 if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) ||
39 (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 #ifdef LTC_FAST
44 {
45 unsigned long blklen;
46
47 blklen = cipher_descriptor[omac->cipher_idx].block_length;
48 if (omac->buflen == 0 && inlen > blklen) {
49 unsigned long y;
50 for (x = 0; x < (inlen - blklen); x += blklen) {
51 for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) {
52 *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y]));
53 }
54 in += blklen;
55 if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) {
56 return err;
57 }
58 }
59 inlen -= x;
60 }
61 }
62 #endif
63
64 while (inlen != 0) {
65 /* ok if the block is full we xor in prev, encrypt and replace prev */
66 if (omac->buflen == omac->blklen) {
67 for (x = 0; x < (unsigned long)omac->blklen; x++) {
68 omac->block[x] ^= omac->prev[x];
69 }
70 if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) {
71 return err;
72 }
73 omac->buflen = 0;
74 }
75
76 /* add bytes */
77 n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen));
78 XMEMCPY(omac->block + omac->buflen, in, n);
79 omac->buflen += n;
80 inlen -= n;
81 in += n;
82 }
83
84 return CRYPT_OK;
85 }
86
87 #endif
88
89
90 /* $Source$ */
91 /* $Revision$ */
92 /* $Date$ */
+0
-165
libtom-src/mac/pelican/pelican.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pelican.c
14 Pelican MAC, initialize state, by Tom St Denis
15 */
16
17 #ifdef LTC_PELICAN
18
19 #define ENCRYPT_ONLY
20 #define PELI_TAB
21 #include "../../ciphers/aes/aes_tab.c.inc"
22
23 /**
24 Initialize a Pelican state
25 @param pelmac The Pelican state to initialize
26 @param key The secret key
27 @param keylen The length of the secret key (octets)
28 @return CRYPT_OK if successful
29 */
30 int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen)
31 {
32 int err;
33
34 LTC_ARGCHK(pelmac != NULL);
35 LTC_ARGCHK(key != NULL);
36
37 #ifdef LTC_FAST
38 if (16 % sizeof(LTC_FAST_TYPE)) {
39 return CRYPT_INVALID_ARG;
40 }
41 #endif
42
43 if ((err = aes_setup(key, keylen, 0, &pelmac->K)) != CRYPT_OK) {
44 return err;
45 }
46
47 zeromem(pelmac->state, 16);
48 aes_ecb_encrypt(pelmac->state, pelmac->state, &pelmac->K);
49 pelmac->buflen = 0;
50
51 return CRYPT_OK;
52 }
53
54 static void four_rounds(pelican_state *pelmac)
55 {
56 ulong32 s0, s1, s2, s3, t0, t1, t2, t3;
57 int r;
58
59 LOAD32H(s0, pelmac->state );
60 LOAD32H(s1, pelmac->state + 4);
61 LOAD32H(s2, pelmac->state + 8);
62 LOAD32H(s3, pelmac->state + 12);
63 for (r = 0; r < 4; r++) {
64 t0 =
65 Te0(byte(s0, 3)) ^
66 Te1(byte(s1, 2)) ^
67 Te2(byte(s2, 1)) ^
68 Te3(byte(s3, 0));
69 t1 =
70 Te0(byte(s1, 3)) ^
71 Te1(byte(s2, 2)) ^
72 Te2(byte(s3, 1)) ^
73 Te3(byte(s0, 0));
74 t2 =
75 Te0(byte(s2, 3)) ^
76 Te1(byte(s3, 2)) ^
77 Te2(byte(s0, 1)) ^
78 Te3(byte(s1, 0));
79 t3 =
80 Te0(byte(s3, 3)) ^
81 Te1(byte(s0, 2)) ^
82 Te2(byte(s1, 1)) ^
83 Te3(byte(s2, 0));
84 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
85 }
86 STORE32H(s0, pelmac->state );
87 STORE32H(s1, pelmac->state + 4);
88 STORE32H(s2, pelmac->state + 8);
89 STORE32H(s3, pelmac->state + 12);
90 }
91
92 /**
93 Process a block of text through Pelican
94 @param pelmac The Pelican MAC state
95 @param in The input
96 @param inlen The length input (octets)
97 @return CRYPT_OK on success
98 */
99 int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen)
100 {
101
102 LTC_ARGCHK(pelmac != NULL);
103 LTC_ARGCHK(in != NULL);
104
105 /* check range */
106 if (pelmac->buflen < 0 || pelmac->buflen > 15) {
107 return CRYPT_INVALID_ARG;
108 }
109
110 #ifdef LTC_FAST
111 if (pelmac->buflen == 0) {
112 while (inlen & ~15) {
113 int x;
114 for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
115 *((LTC_FAST_TYPE*)((unsigned char *)pelmac->state + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)in + x));
116 }
117 four_rounds(pelmac);
118 in += 16;
119 inlen -= 16;
120 }
121 }
122 #endif
123
124 while (inlen--) {
125 pelmac->state[pelmac->buflen++] ^= *in++;
126 if (pelmac->buflen == 16) {
127 four_rounds(pelmac);
128 pelmac->buflen = 0;
129 }
130 }
131 return CRYPT_OK;
132 }
133
134 /**
135 Terminate Pelican MAC
136 @param pelmac The Pelican MAC state
137 @param out [out] The TAG
138 @return CRYPT_OK on sucess
139 */
140 int pelican_done(pelican_state *pelmac, unsigned char *out)
141 {
142 LTC_ARGCHK(pelmac != NULL);
143 LTC_ARGCHK(out != NULL);
144
145 /* check range */
146 if (pelmac->buflen < 0 || pelmac->buflen > 16) {
147 return CRYPT_INVALID_ARG;
148 }
149
150 if (pelmac->buflen == 16) {
151 four_rounds(pelmac);
152 pelmac->buflen = 0;
153 }
154 pelmac->state[pelmac->buflen++] ^= 0x80;
155 aes_ecb_encrypt(pelmac->state, out, &pelmac->K);
156 aes_done(&pelmac->K);
157 return CRYPT_OK;
158 }
159
160 #endif
161
162 /* $Source$ */
163 /* $Revision$ */
164 /* $Date$ */
+0
-59
libtom-src/mac/pelican/pelican_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pelican_memory.c
14 Pelican MAC, MAC a block of memory, by Tom St Denis
15 */
16
17 #ifdef LTC_PELICAN
18
19 /**
20 Pelican block of memory
21 @param key The key for the MAC
22 @param keylen The length of the key (octets)
23 @param in The input to MAC
24 @param inlen The length of the input (octets)
25 @param out [out] The output TAG
26 @return CRYPT_OK on success
27 */
28 int pelican_memory(const unsigned char *key, unsigned long keylen,
29 const unsigned char *in, unsigned long inlen,
30 unsigned char *out)
31 {
32 pelican_state *pel;
33 int err;
34
35 pel = XMALLOC(sizeof(*pel));
36 if (pel == NULL) {
37 return CRYPT_MEM;
38 }
39
40 if ((err = pelican_init(pel, key, keylen)) != CRYPT_OK) {
41 XFREE(pel);
42 return err;
43 }
44 if ((err = pelican_process(pel, in ,inlen)) != CRYPT_OK) {
45 XFREE(pel);
46 return err;
47 }
48 err = pelican_done(pel, out);
49 XFREE(pel);
50 return err;
51 }
52
53
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
+0
-74
libtom-src/mac/pmac/pmac_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_done.c
14 PMAC implementation, terminate a session, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen)
20 {
21 int err, x;
22
23 LTC_ARGCHK(state != NULL);
24 LTC_ARGCHK(out != NULL);
25 if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) {
26 return err;
27 }
28
29 if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) ||
30 (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) {
31 return CRYPT_INVALID_ARG;
32 }
33
34
35 /* handle padding. If multiple xor in L/x */
36
37 if (state->buflen == state->block_len) {
38 /* xor Lr against the checksum */
39 for (x = 0; x < state->block_len; x++) {
40 state->checksum[x] ^= state->block[x] ^ state->Lr[x];
41 }
42 } else {
43 /* otherwise xor message bytes then the 0x80 byte */
44 for (x = 0; x < state->buflen; x++) {
45 state->checksum[x] ^= state->block[x];
46 }
47 state->checksum[x] ^= 0x80;
48 }
49
50 /* encrypt it */
51 if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) {
52 return err;
53 }
54 cipher_descriptor[state->cipher_idx].done(&state->key);
55
56 /* store it */
57 for (x = 0; x < state->block_len && x < (int)*outlen; x++) {
58 out[x] = state->checksum[x];
59 }
60 *outlen = x;
61
62 #ifdef LTC_CLEAN_STACK
63 zeromem(state, sizeof(*state));
64 #endif
65 return CRYPT_OK;
66 }
67
68 #endif
69
70
71 /* $Source$ */
72 /* $Revision$ */
73 /* $Date$ */
+0
-84
libtom-src/mac/pmac/pmac_file.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_file.c
14 PMAC implementation, process a file, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 /**
20 PMAC a file
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param filename The name of the file to send through PMAC
25 @param out [out] Destination for the authentication tag
26 @param outlen [in/out] Max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int pmac_file(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const char *filename,
32 unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35 return CRYPT_NOP;
36 #else
37 int err, x;
38 pmac_state pmac;
39 FILE *in;
40 unsigned char buf[512];
41
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(filename != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 in = fopen(filename, "rb");
49 if (in == NULL) {
50 return CRYPT_FILE_NOTFOUND;
51 }
52
53 if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) {
54 fclose(in);
55 return err;
56 }
57
58 do {
59 x = fread(buf, 1, sizeof(buf), in);
60 if ((err = pmac_process(&pmac, buf, x)) != CRYPT_OK) {
61 fclose(in);
62 return err;
63 }
64 } while (x == sizeof(buf));
65 fclose(in);
66
67 if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) {
68 return err;
69 }
70
71 #ifdef LTC_CLEAN_STACK
72 zeromem(buf, sizeof(buf));
73 #endif
74
75 return CRYPT_OK;
76 #endif
77 }
78
79 #endif
80
81 /* $Source$ */
82 /* $Revision$ */
83 /* $Date$ */
+0
-147
libtom-src/mac/pmac/pmac_init.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_init.c
14 PMAC implementation, initialize state, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 static const struct {
20 int len;
21 unsigned char poly_div[MAXBLOCKSIZE],
22 poly_mul[MAXBLOCKSIZE];
23 } polys[] = {
24 {
25 8,
26 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
27 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
28 }, {
29 16,
30 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
32 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
34 }
35 };
36
37 /**
38 Initialize a PMAC state
39 @param pmac The PMAC state to initialize
40 @param cipher The index of the desired cipher
41 @param key The secret key
42 @param keylen The length of the secret key (octets)
43 @return CRYPT_OK if successful
44 */
45 int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen)
46 {
47 int poly, x, y, m, err;
48 unsigned char *L;
49
50 LTC_ARGCHK(pmac != NULL);
51 LTC_ARGCHK(key != NULL);
52
53 /* valid cipher? */
54 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
55 return err;
56 }
57
58 /* determine which polys to use */
59 pmac->block_len = cipher_descriptor[cipher].block_length;
60 for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) {
61 if (polys[poly].len == pmac->block_len) {
62 break;
63 }
64 }
65 if (polys[poly].len != pmac->block_len) {
66 return CRYPT_INVALID_ARG;
67 }
68
69 #ifdef LTC_FAST
70 if (pmac->block_len % sizeof(LTC_FAST_TYPE)) {
71 return CRYPT_INVALID_ARG;
72 }
73 #endif
74
75
76 /* schedule the key */
77 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) {
78 return err;
79 }
80
81 /* allocate L */
82 L = XMALLOC(pmac->block_len);
83 if (L == NULL) {
84 return CRYPT_MEM;
85 }
86
87 /* find L = E[0] */
88 zeromem(L, pmac->block_len);
89 if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) {
90 goto error;
91 }
92
93 /* find Ls[i] = L << i for i == 0..31 */
94 XMEMCPY(pmac->Ls[0], L, pmac->block_len);
95 for (x = 1; x < 32; x++) {
96 m = pmac->Ls[x-1][0] >> 7;
97 for (y = 0; y < pmac->block_len-1; y++) {
98 pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255;
99 }
100 pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255;
101
102 if (m == 1) {
103 for (y = 0; y < pmac->block_len; y++) {
104 pmac->Ls[x][y] ^= polys[poly].poly_mul[y];
105 }
106 }
107 }
108
109 /* find Lr = L / x */
110 m = L[pmac->block_len-1] & 1;
111
112 /* shift right */
113 for (x = pmac->block_len - 1; x > 0; x--) {
114 pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255;
115 }
116 pmac->Lr[0] = L[0] >> 1;
117
118 if (m == 1) {
119 for (x = 0; x < pmac->block_len; x++) {
120 pmac->Lr[x] ^= polys[poly].poly_div[x];
121 }
122 }
123
124 /* zero buffer, counters, etc... */
125 pmac->block_index = 1;
126 pmac->cipher_idx = cipher;
127 pmac->buflen = 0;
128 zeromem(pmac->block, sizeof(pmac->block));
129 zeromem(pmac->Li, sizeof(pmac->Li));
130 zeromem(pmac->checksum, sizeof(pmac->checksum));
131 err = CRYPT_OK;
132 error:
133 #ifdef LTC_CLEAN_STACK
134 zeromem(L, pmac->block_len);
135 #endif
136
137 XFREE(L);
138
139 return err;
140 }
141
142 #endif
143
144 /* $Source$ */
145 /* $Revision$ */
146 /* $Date$ */
+0
-74
libtom-src/mac/pmac/pmac_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_memory.c
14 PMAC implementation, process a block of memory, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 /**
20 PMAC a block of memory
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param in The data you wish to send through PMAC
25 @param inlen The length of data you wish to send through PMAC (octets)
26 @param out [out] Destination for the authentication tag
27 @param outlen [in/out] The max size and resulting size of the authentication tag
28 @return CRYPT_OK if successful
29 */
30 int pmac_memory(int cipher,
31 const unsigned char *key, unsigned long keylen,
32 const unsigned char *in, unsigned long inlen,
33 unsigned char *out, unsigned long *outlen)
34 {
35 int err;
36 pmac_state *pmac;
37
38 LTC_ARGCHK(key != NULL);
39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL);
42
43 /* allocate ram for pmac state */
44 pmac = XMALLOC(sizeof(pmac_state));
45 if (pmac == NULL) {
46 return CRYPT_MEM;
47 }
48
49 if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) {
50 goto LBL_ERR;
51 }
52 if ((err = pmac_process(pmac, in, inlen)) != CRYPT_OK) {
53 goto LBL_ERR;
54 }
55 if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58
59 err = CRYPT_OK;
60 LBL_ERR:
61 #ifdef LTC_CLEAN_STACK
62 zeromem(pmac, sizeof(pmac_state));
63 #endif
64
65 XFREE(pmac);
66 return err;
67 }
68
69 #endif
70
71 /* $Source$ */
72 /* $Revision$ */
73 /* $Date$ */
+0
-89
libtom-src/mac/pmac/pmac_memory_multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file pmac_memory_multi.c
15 PMAC implementation, process multiple blocks of memory, by Tom St Denis
16 */
17
18 #ifdef LTC_PMAC
19
20 /**
21 PMAC multiple blocks of memory
22 @param cipher The index of the cipher desired
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] Destination for the authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @param in The data you wish to send through PMAC
28 @param inlen The length of data you wish to send through PMAC (octets)
29 @param ... tuples of (data,len) pairs to PMAC, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int pmac_memory_multi(int cipher,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36 {
37 int err;
38 pmac_state *pmac;
39 va_list args;
40 const unsigned char *curptr;
41 unsigned long curlen;
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 /* allocate ram for pmac state */
49 pmac = XMALLOC(sizeof(pmac_state));
50 if (pmac == NULL) {
51 return CRYPT_MEM;
52 }
53
54 if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57 va_start(args, inlen);
58 curptr = in;
59 curlen = inlen;
60 for (;;) {
61 /* process buf */
62 if ((err = pmac_process(pmac, curptr, curlen)) != CRYPT_OK) {
63 goto LBL_ERR;
64 }
65 /* step to next */
66 curptr = va_arg(args, const unsigned char*);
67 if (curptr == NULL) {
68 break;
69 }
70 curlen = va_arg(args, unsigned long);
71 }
72 if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) {
73 goto LBL_ERR;
74 }
75 LBL_ERR:
76 #ifdef LTC_CLEAN_STACK
77 zeromem(pmac, sizeof(pmac_state));
78 #endif
79 XFREE(pmac);
80 va_end(args);
81 return err;
82 }
83
84 #endif
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
+0
-39
libtom-src/mac/pmac/pmac_ntz.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_ntz.c
14 PMAC implementation, internal function, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 /**
20 Internal PMAC function
21 */
22 int pmac_ntz(unsigned long x)
23 {
24 int c;
25 x &= 0xFFFFFFFFUL;
26 c = 0;
27 while ((x & 1) == 0) {
28 ++c;
29 x >>= 1;
30 }
31 return c;
32 }
33
34 #endif
35
36 /* $Source$ */
37 /* $Revision$ */
38 /* $Date$ */
+0
-100
libtom-src/mac/pmac/pmac_process.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_process.c
14 PMAC implementation, process data, by Tom St Denis
15 */
16
17
18 #ifdef LTC_PMAC
19
20 /**
21 Process data in a PMAC stream
22 @param pmac The PMAC state
23 @param in The data to send through PMAC
24 @param inlen The length of the data to send through PMAC
25 @return CRYPT_OK if successful
26 */
27 int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen)
28 {
29 int err, n;
30 unsigned long x;
31 unsigned char Z[MAXBLOCKSIZE];
32
33 LTC_ARGCHK(pmac != NULL);
34 LTC_ARGCHK(in != NULL);
35 if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) {
36 return err;
37 }
38
39 if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) ||
40 (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 #ifdef LTC_FAST
45 if (pmac->buflen == 0 && inlen > 16) {
46 unsigned long y;
47 for (x = 0; x < (inlen - 16); x += 16) {
48 pmac_shift_xor(pmac);
49 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
50 *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y]));
51 }
52 if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
53 return err;
54 }
55 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
56 *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y]));
57 }
58 in += 16;
59 }
60 inlen -= x;
61 }
62 #endif
63
64 while (inlen != 0) {
65 /* ok if the block is full we xor in prev, encrypt and replace prev */
66 if (pmac->buflen == pmac->block_len) {
67 pmac_shift_xor(pmac);
68 for (x = 0; x < (unsigned long)pmac->block_len; x++) {
69 Z[x] = pmac->Li[x] ^ pmac->block[x];
70 }
71 if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
72 return err;
73 }
74 for (x = 0; x < (unsigned long)pmac->block_len; x++) {
75 pmac->checksum[x] ^= Z[x];
76 }
77 pmac->buflen = 0;
78 }
79
80 /* add bytes */
81 n = MIN(inlen, (unsigned long)(pmac->block_len - pmac->buflen));
82 XMEMCPY(pmac->block + pmac->buflen, in, n);
83 pmac->buflen += n;
84 inlen -= n;
85 in += n;
86 }
87
88 #ifdef LTC_CLEAN_STACK
89 zeromem(Z, sizeof(Z));
90 #endif
91
92 return CRYPT_OK;
93 }
94
95 #endif
96
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
+0
-44
libtom-src/mac/pmac/pmac_shift_xor.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_shift_xor.c
14 PMAC implementation, internal function, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 /**
20 Internal function. Performs the state update (adding correct multiple)
21 @param pmac The PMAC state.
22 */
23 void pmac_shift_xor(pmac_state *pmac)
24 {
25 int x, y;
26 y = pmac_ntz(pmac->block_index++);
27 #ifdef LTC_FAST
28 for (x = 0; x < pmac->block_len; x += sizeof(LTC_FAST_TYPE)) {
29 *((LTC_FAST_TYPE*)((unsigned char *)pmac->Li + x)) ^=
30 *((LTC_FAST_TYPE*)((unsigned char *)pmac->Ls[y] + x));
31 }
32 #else
33 for (x = 0; x < pmac->block_len; x++) {
34 pmac->Li[x] ^= pmac->Ls[y][x];
35 }
36 #endif
37 }
38
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-77
libtom-src/mac/xcbc/xcbc_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_done.c
14 XCBC Support, terminate the state
15 */
16
17 #ifdef LTC_XCBC
18
19 /** Terminate the XCBC-MAC state
20 @param xcbc XCBC state to terminate
21 @param out [out] Destination for the MAC tag
22 @param outlen [in/out] Destination size and final tag size
23 Return CRYPT_OK on success
24 */
25 int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen)
26 {
27 int err, x;
28 LTC_ARGCHK(xcbc != NULL);
29 LTC_ARGCHK(out != NULL);
30
31 /* check structure */
32 if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) {
33 return err;
34 }
35
36 if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) ||
37 (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) {
38 return CRYPT_INVALID_ARG;
39 }
40
41 /* which key do we use? */
42 if (xcbc->buflen == xcbc->blocksize) {
43 /* k2 */
44 for (x = 0; x < xcbc->blocksize; x++) {
45 xcbc->IV[x] ^= xcbc->K[1][x];
46 }
47 } else {
48 xcbc->IV[xcbc->buflen] ^= 0x80;
49 /* k3 */
50 for (x = 0; x < xcbc->blocksize; x++) {
51 xcbc->IV[x] ^= xcbc->K[2][x];
52 }
53 }
54
55 /* encrypt */
56 cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
57 cipher_descriptor[xcbc->cipher].done(&xcbc->key);
58
59 /* extract tag */
60 for (x = 0; x < xcbc->blocksize && (unsigned long)x < *outlen; x++) {
61 out[x] = xcbc->IV[x];
62 }
63 *outlen = x;
64
65 #ifdef LTC_CLEAN_STACK
66 zeromem(xcbc, sizeof(*xcbc));
67 #endif
68 return CRYPT_OK;
69 }
70
71 #endif
72
73 /* $Source$ */
74 /* $Revision$ */
75 /* $Date$ */
76
+0
-83
libtom-src/mac/xcbc/xcbc_file.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_file.c
14 XCBC support, process a file, Tom St Denis
15 */
16
17 #ifdef LTC_XCBC
18
19 /**
20 XCBC a file
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param filename The name of the file you wish to XCBC
25 @param out [out] Where the authentication tag is to be stored
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int xcbc_file(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const char *filename,
32 unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35 return CRYPT_NOP;
36 #else
37 int err, x;
38 xcbc_state xcbc;
39 FILE *in;
40 unsigned char buf[512];
41
42 LTC_ARGCHK(key != NULL);
43 LTC_ARGCHK(filename != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 in = fopen(filename, "rb");
48 if (in == NULL) {
49 return CRYPT_FILE_NOTFOUND;
50 }
51
52 if ((err = xcbc_init(&xcbc, cipher, key, keylen)) != CRYPT_OK) {
53 fclose(in);
54 return err;
55 }
56
57 do {
58 x = fread(buf, 1, sizeof(buf), in);
59 if ((err = xcbc_process(&xcbc, buf, x)) != CRYPT_OK) {
60 fclose(in);
61 return err;
62 }
63 } while (x == sizeof(buf));
64 fclose(in);
65
66 if ((err = xcbc_done(&xcbc, out, outlen)) != CRYPT_OK) {
67 return err;
68 }
69
70 #ifdef LTC_CLEAN_STACK
71 zeromem(buf, sizeof(buf));
72 #endif
73
74 return CRYPT_OK;
75 #endif
76 }
77
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
+0
-108
libtom-src/mac/xcbc/xcbc_init.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_init.c
14 XCBC Support, start an XCBC state
15 */
16
17 #ifdef LTC_XCBC
18
19 /** Initialize XCBC-MAC state
20 @param xcbc [out] XCBC state to initialize
21 @param cipher Index of cipher to use
22 @param key [in] Secret key
23 @param keylen Length of secret key in octets
24 Return CRYPT_OK on success
25 */
26 int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen)
27 {
28 int x, y, err;
29 symmetric_key *skey;
30 unsigned long k1;
31
32 LTC_ARGCHK(xcbc != NULL);
33 LTC_ARGCHK(key != NULL);
34
35 /* schedule the key */
36 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 #ifdef LTC_FAST
41 if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
42 return CRYPT_INVALID_ARG;
43 }
44 #endif
45
46 skey = NULL;
47
48 /* are we in pure XCBC mode with three keys? */
49 if (keylen & LTC_XCBC_PURE) {
50 keylen &= ~LTC_XCBC_PURE;
51
52 if (keylen < 2UL*cipher_descriptor[cipher].block_length) {
53 return CRYPT_INVALID_ARG;
54 }
55
56 k1 = keylen - 2*cipher_descriptor[cipher].block_length;
57 XMEMCPY(xcbc->K[0], key, k1);
58 XMEMCPY(xcbc->K[1], key+k1, cipher_descriptor[cipher].block_length);
59 XMEMCPY(xcbc->K[2], key+k1 + cipher_descriptor[cipher].block_length, cipher_descriptor[cipher].block_length);
60 } else {
61 /* use the key expansion */
62 k1 = cipher_descriptor[cipher].block_length;
63
64 /* schedule the user key */
65 skey = XCALLOC(1, sizeof(*skey));
66 if (skey == NULL) {
67 return CRYPT_MEM;
68 }
69
70 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
71 goto done;
72 }
73
74 /* make the three keys */
75 for (y = 0; y < 3; y++) {
76 for (x = 0; x < cipher_descriptor[cipher].block_length; x++) {
77 xcbc->K[y][x] = y + 1;
78 }
79 cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey);
80 }
81 }
82
83 /* setup K1 */
84 err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key);
85
86 /* setup struct */
87 zeromem(xcbc->IV, cipher_descriptor[cipher].block_length);
88 xcbc->blocksize = cipher_descriptor[cipher].block_length;
89 xcbc->cipher = cipher;
90 xcbc->buflen = 0;
91 done:
92 cipher_descriptor[cipher].done(skey);
93 if (skey != NULL) {
94 #ifdef LTC_CLEAN_STACK
95 zeromem(skey, sizeof(*skey));
96 #endif
97 XFREE(skey);
98 }
99 return err;
100 }
101
102 #endif
103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
107
+0
-71
libtom-src/mac/xcbc/xcbc_memory.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_process.c
14 XCBC Support, XCBC-MAC a block of memory
15 */
16
17 #ifdef LTC_XCBC
18
19 /** XCBC-MAC a block of memory
20 @param cipher Index of cipher to use
21 @param key [in] Secret key
22 @param keylen Length of key in octets
23 @param in [in] Message to MAC
24 @param inlen Length of input in octets
25 @param out [out] Destination for the MAC tag
26 @param outlen [in/out] Output size and final tag size
27 Return CRYPT_OK on success.
28 */
29 int xcbc_memory(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long *outlen)
33 {
34 xcbc_state *xcbc;
35 int err;
36
37 /* is the cipher valid? */
38 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* Use accelerator if found */
43 if (cipher_descriptor[cipher].xcbc_memory != NULL) {
44 return cipher_descriptor[cipher].xcbc_memory(key, keylen, in, inlen, out, outlen);
45 }
46
47 xcbc = XCALLOC(1, sizeof(*xcbc));
48 if (xcbc == NULL) {
49 return CRYPT_MEM;
50 }
51
52 if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) {
53 goto done;
54 }
55
56 if ((err = xcbc_process(xcbc, in, inlen)) != CRYPT_OK) {
57 goto done;
58 }
59
60 err = xcbc_done(xcbc, out, outlen);
61 done:
62 XFREE(xcbc);
63 return err;
64 }
65
66 #endif
67
68 /* $Source$ */
69 /* $Revision$ */
70 /* $Date$ */
+0
-90
libtom-src/mac/xcbc/xcbc_memory_multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file xcbc_memory_multi.c
15 XCBC support, process multiple blocks of memory, Tom St Denis
16 */
17
18 #ifdef LTC_XCBC
19
20 /**
21 XCBC multiple blocks of memory
22 @param cipher The index of the desired cipher
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] The destination of the authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag (octets)
27 @param in The data to send through XCBC
28 @param inlen The length of the data to send through XCBC (octets)
29 @param ... tuples of (data,len) pairs to XCBC, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int xcbc_memory_multi(int cipher,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36 {
37 int err;
38 xcbc_state *xcbc;
39 va_list args;
40 const unsigned char *curptr;
41 unsigned long curlen;
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 /* allocate ram for xcbc state */
49 xcbc = XMALLOC(sizeof(xcbc_state));
50 if (xcbc == NULL) {
51 return CRYPT_MEM;
52 }
53
54 /* xcbc process the message */
55 if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58 va_start(args, inlen);
59 curptr = in;
60 curlen = inlen;
61 for (;;) {
62 /* process buf */
63 if ((err = xcbc_process(xcbc, curptr, curlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 /* step to next */
67 curptr = va_arg(args, const unsigned char*);
68 if (curptr == NULL) {
69 break;
70 }
71 curlen = va_arg(args, unsigned long);
72 }
73 if ((err = xcbc_done(xcbc, out, outlen)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76 LBL_ERR:
77 #ifdef LTC_CLEAN_STACK
78 zeromem(xcbc, sizeof(xcbc_state));
79 #endif
80 XFREE(xcbc);
81 va_end(args);
82 return err;
83 }
84
85 #endif
86
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
+0
-75
libtom-src/mac/xcbc/xcbc_process.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_process.c
14 XCBC Support, process blocks with XCBC
15 */
16
17 #ifdef LTC_XCBC
18
19 /** Process data through XCBC-MAC
20 @param xcbc The XCBC-MAC state
21 @param in Input data to process
22 @param inlen Length of input in octets
23 Return CRYPT_OK on success
24 */
25 int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen)
26 {
27 int err;
28 #ifdef LTC_FAST
29 int x;
30 #endif
31
32 LTC_ARGCHK(xcbc != NULL);
33 LTC_ARGCHK(in != NULL);
34
35 /* check structure */
36 if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) ||
41 (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 #ifdef LTC_FAST
46 if (xcbc->buflen == 0) {
47 while (inlen > (unsigned long)xcbc->blocksize) {
48 for (x = 0; x < xcbc->blocksize; x += sizeof(LTC_FAST_TYPE)) {
49 *((LTC_FAST_TYPE*)&(xcbc->IV[x])) ^= *((LTC_FAST_TYPE*)&(in[x]));
50 }
51 cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
52 in += xcbc->blocksize;
53 inlen -= xcbc->blocksize;
54 }
55 }
56 #endif
57
58 while (inlen) {
59 if (xcbc->buflen == xcbc->blocksize) {
60 cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
61 xcbc->buflen = 0;
62 }
63 xcbc->IV[xcbc->buflen++] ^= *in++;
64 --inlen;
65 }
66 return CRYPT_OK;
67 }
68
69 #endif
70
71 /* $Source$ */
72 /* $Revision$ */
73 /* $Date$ */
74
+0
-1587
libtom-src/math/fp/ltc_ecc_fp_mulmod.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ltc_ecc_fp_mulmod.c
14 ECC Crypto, Tom St Denis
15 */
16
17 #if defined(LTC_MECC) && defined(LTC_MECC_FP)
18 #include <limits.h>
19
20 /* number of entries in the cache */
21 #ifndef FP_ENTRIES
22 #define FP_ENTRIES 16
23 #endif
24
25 /* number of bits in LUT */
26 #ifndef FP_LUT
27 #define FP_LUT 8U
28 #endif
29
30 #if (FP_LUT > 12) || (FP_LUT < 2)
31 #error FP_LUT must be between 2 and 12 inclusively
32 #endif
33
34 /** Our FP cache */
35 static struct {
36 ecc_point *g, /* cached COPY of base point */
37 *LUT[1U<<FP_LUT]; /* fixed point lookup */
38 void *mu; /* copy of the montgomery constant */
39 int lru_count; /* amount of times this entry has been used */
40 int lock; /* flag to indicate cache eviction permitted (0) or not (1) */
41 } fp_cache[FP_ENTRIES];
42
43 LTC_MUTEX_GLOBAL(ltc_ecc_fp_lock)
44
45 /* simple table to help direct the generation of the LUT */
46 static const struct {
47 int ham, terma, termb;
48 } lut_orders[] = {
49 { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
50 { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
51 { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
52 { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
53 { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
54 { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
55 { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
56 { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
57 #if FP_LUT > 6
58 { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
59 { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
60 { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
61 { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
62 { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
63 { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
64 { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
65 { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
66 #if FP_LUT > 7
67 { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
68 { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
69 { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
70 { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
71 { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
72 { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
73 { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
74 { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
75 { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
76 { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
77 { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
78 { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
79 { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
80 { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
81 { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
82 { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
83 #if FP_LUT > 8
84 { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
85 { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
86 { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
87 { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
88 { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
89 { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
90 { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
91 { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
92 { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
93 { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
94 { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
95 { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
96 { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
97 { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
98 { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
99 { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
100 { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
101 { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
102 { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
103 { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
104 { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
105 { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
106 { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
107 { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
108 { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
109 { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
110 { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
111 { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
112 { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
113 { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
114 { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
115 { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
116 #if FP_LUT > 9
117 { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
118 { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
119 { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
120 { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
121 { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
122 { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
123 { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
124 { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
125 { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
126 { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
127 { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
128 { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
129 { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
130 { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
131 { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
132 { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
133 { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
134 { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
135 { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
136 { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
137 { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
138 { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
139 { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
140 { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
141 { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
142 { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
143 { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
144 { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
145 { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
146 { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
147 { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
148 { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
149 { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
150 { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
151 { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
152 { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
153 { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
154 { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
155 { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
156 { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
157 { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
158 { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
159 { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
160 { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
161 { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
162 { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
163 { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
164 { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
165 { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
166 { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
167 { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
168 { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
169 { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
170 { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
171 { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
172 { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
173 { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
174 { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
175 { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
176 { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
177 { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
178 { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
179 { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
180 { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
181 #if FP_LUT > 10
182 { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
183 { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
184 { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
185 { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
186 { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
187 { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
188 { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
189 { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
190 { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
191 { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
192 { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
193 { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
194 { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
195 { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
196 { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
197 { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
198 { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
199 { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
200 { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
201 { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
202 { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
203 { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
204 { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
205 { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
206 { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
207 { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
208 { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
209 { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
210 { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
211 { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
212 { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
213 { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
214 { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
215 { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
216 { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
217 { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
218 { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
219 { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
220 { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
221 { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
222 { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
223 { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
224 { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
225 { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
226 { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
227 { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
228 { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
229 { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
230 { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
231 { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
232 { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
233 { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
234 { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
235 { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
236 { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
237 { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
238 { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
239 { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
240 { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
241 { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
242 { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
243 { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
244 { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
245 { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
246 { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
247 { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
248 { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
249 { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
250 { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
251 { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
252 { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
253 { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
254 { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
255 { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
256 { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
257 { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
258 { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
259 { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
260 { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
261 { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
262 { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
263 { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
264 { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
265 { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
266 { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
267 { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
268 { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
269 { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
270 { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
271 { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
272 { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
273 { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
274 { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
275 { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
276 { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
277 { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
278 { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
279 { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
280 { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
281 { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
282 { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
283 { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
284 { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
285 { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
286 { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
287 { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
288 { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
289 { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
290 { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
291 { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
292 { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
293 { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
294 { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
295 { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
296 { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
297 { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
298 { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
299 { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
300 { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
301 { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
302 { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
303 { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
304 { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
305 { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
306 { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
307 { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
308 { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
309 { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
310 #if FP_LUT > 11
311 { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
312 { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
313 { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
314 { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
315 { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
316 { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
317 { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
318 { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
319 { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
320 { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
321 { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
322 { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
323 { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
324 { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
325 { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
326 { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
327 { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
328 { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
329 { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
330 { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
331 { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
332 { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
333 { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
334 { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
335 { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
336 { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
337 { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
338 { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
339 { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
340 { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
341 { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
342 { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
343 { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
344 { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
345 { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
346 { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
347 { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
348 { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
349 { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
350 { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
351 { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
352 { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
353 { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
354 { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
355 { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
356 { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
357 { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
358 { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
359 { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
360 { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
361 { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
362 { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
363 { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
364 { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
365 { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
366 { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
367 { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
368 { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
369 { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
370 { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
371 { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
372 { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
373 { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
374 { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
375 { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
376 { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
377 { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
378 { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
379 { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
380 { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
381 { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
382 { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
383 { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
384 { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
385 { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
386 { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
387 { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
388 { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
389 { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
390 { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
391 { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
392 { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
393 { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
394 { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
395 { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
396 { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
397 { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
398 { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
399 { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
400 { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
401 { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
402 { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
403 { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
404 { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
405 { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
406 { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
407 { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
408 { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
409 { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
410 { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
411 { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
412 { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
413 { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
414 { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
415 { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
416 { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
417 { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
418 { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
419 { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
420 { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
421 { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
422 { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
423 { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
424 { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
425 { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
426 { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
427 { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
428 { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
429 { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
430 { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
431 { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
432 { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
433 { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
434 { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
435 { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
436 { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
437 { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
438 { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
439 { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
440 { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
441 { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
442 { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
443 { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
444 { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
445 { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
446 { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
447 { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
448 { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
449 { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
450 { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
451 { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
452 { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
453 { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
454 { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
455 { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
456 { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
457 { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
458 { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
459 { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
460 { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
461 { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
462 { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
463 { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
464 { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
465 { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
466 { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
467 { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
468 { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
469 { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
470 { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
471 { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
472 { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
473 { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
474 { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
475 { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
476 { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
477 { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
478 { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
479 { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
480 { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
481 { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
482 { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
483 { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
484 { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
485 { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
486 { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
487 { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
488 { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
489 { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
490 { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
491 { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
492 { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
493 { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
494 { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
495 { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
496 { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
497 { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
498 { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
499 { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
500 { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
501 { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
502 { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
503 { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
504 { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
505 { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
506 { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
507 { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
508 { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
509 { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
510 { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
511 { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
512 { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
513 { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
514 { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
515 { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
516 { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
517 { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
518 { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
519 { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
520 { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
521 { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
522 { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
523 { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
524 { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
525 { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
526 { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
527 { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
528 { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
529 { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
530 { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
531 { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
532 { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
533 { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
534 { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
535 { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
536 { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
537 { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
538 { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
539 { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
540 { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
541 { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
542 { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
543 { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
544 { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
545 { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
546 { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
547 { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
548 { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
549 { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
550 { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
551 { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
552 { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
553 { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
554 { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
555 { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
556 { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
557 { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
558 { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
559 { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
560 { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
561 { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
562 { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
563 { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
564 { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
565 { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
566 { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
567 #endif
568 #endif
569 #endif
570 #endif
571 #endif
572 #endif
573 };
574
575 /* find a hole and free as required, return -1 if no hole found */
576 static int find_hole(void)
577 {
578 unsigned x;
579 int y, z;
580 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
581 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
582 z = x;
583 y = fp_cache[x].lru_count;
584 }
585 }
586
587 /* decrease all */
588 for (x = 0; x < FP_ENTRIES; x++) {
589 if (fp_cache[x].lru_count > 3) {
590 --(fp_cache[x].lru_count);
591 }
592 }
593
594 /* free entry z */
595 if (z >= 0 && fp_cache[z].g) {
596 if (fp_cache[z].mu != NULL) {
597 mp_clear(fp_cache[z].mu);
598 fp_cache[z].mu = NULL;
599 }
600 ltc_ecc_del_point(fp_cache[z].g);
601 fp_cache[z].g = NULL;
602 for (x = 0; x < (1U<<FP_LUT); x++) {
603 ltc_ecc_del_point(fp_cache[z].LUT[x]);
604 fp_cache[z].LUT[x] = NULL;
605 }
606 fp_cache[z].lru_count = 0;
607 }
608 return z;
609 }
610
611 /* determine if a base is already in the cache and if so, where */
612 static int find_base(ecc_point *g)
613 {
614 int x;
615 for (x = 0; x < FP_ENTRIES; x++) {
616 if (fp_cache[x].g != NULL &&
617 mp_cmp(fp_cache[x].g->x, g->x) == LTC_MP_EQ &&
618 mp_cmp(fp_cache[x].g->y, g->y) == LTC_MP_EQ &&
619 mp_cmp(fp_cache[x].g->z, g->z) == LTC_MP_EQ) {
620 break;
621 }
622 }
623 if (x == FP_ENTRIES) {
624 x = -1;
625 }
626 return x;
627 }
628
629 /* add a new base to the cache */
630 static int add_entry(int idx, ecc_point *g)
631 {
632 unsigned x, y;
633
634 /* allocate base and LUT */
635 fp_cache[idx].g = ltc_ecc_new_point();
636 if (fp_cache[idx].g == NULL) {
637 return CRYPT_MEM;
638 }
639
640 /* copy x and y */
641 if ((mp_copy(g->x, fp_cache[idx].g->x) != CRYPT_OK) ||
642 (mp_copy(g->y, fp_cache[idx].g->y) != CRYPT_OK) ||
643 (mp_copy(g->z, fp_cache[idx].g->z) != CRYPT_OK)) {
644 ltc_ecc_del_point(fp_cache[idx].g);
645 fp_cache[idx].g = NULL;
646 return CRYPT_MEM;
647 }
648
649 for (x = 0; x < (1U<<FP_LUT); x++) {
650 fp_cache[idx].LUT[x] = ltc_ecc_new_point();
651 if (fp_cache[idx].LUT[x] == NULL) {
652 for (y = 0; y < x; y++) {
653 ltc_ecc_del_point(fp_cache[idx].LUT[y]);
654 fp_cache[idx].LUT[y] = NULL;
655 }
656 ltc_ecc_del_point(fp_cache[idx].g);
657 fp_cache[idx].g = NULL;
658 fp_cache[idx].lru_count = 0;
659 return CRYPT_MEM;
660 }
661 }
662
663 fp_cache[idx].lru_count = 0;
664 return CRYPT_OK;
665 }
666
667 /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
668 *
669 * The algorithm builds patterns in increasing bit order by first making all
670 * single bit input patterns, then all two bit input patterns and so on
671 */
672 static int build_lut(int idx, void *modulus, void *mp, void *mu)
673 {
674 unsigned x, y, err, bitlen, lut_gap;
675 void *tmp;
676
677 tmp = NULL;
678
679 /* sanity check to make sure lut_order table is of correct size, should compile out to a NOP if true */
680 if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
681 err = CRYPT_INVALID_ARG;
682 goto DONE;
683 }
684
685 /* get bitlen and round up to next multiple of FP_LUT */
686 bitlen = mp_unsigned_bin_size(modulus) << 3;
687 x = bitlen % FP_LUT;
688 if (x) {
689 bitlen += FP_LUT - x;
690 }
691 lut_gap = bitlen / FP_LUT;
692
693 /* init the mu */
694 if ((err = mp_init_copy(&fp_cache[idx].mu, mu)) != CRYPT_OK) {
695 goto ERR;
696 }
697
698 /* copy base */
699 if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus, fp_cache[idx].LUT[1]->x) != CRYPT_OK) ||
700 (mp_mulmod(fp_cache[idx].g->y, mu, modulus, fp_cache[idx].LUT[1]->y) != CRYPT_OK) ||
701 (mp_mulmod(fp_cache[idx].g->z, mu, modulus, fp_cache[idx].LUT[1]->z) != CRYPT_OK)) { goto ERR; }
702
703 /* make all single bit entries */
704 for (x = 1; x < FP_LUT; x++) {
705 if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, fp_cache[idx].LUT[1<<x]->x) != CRYPT_OK) ||
706 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, fp_cache[idx].LUT[1<<x]->y) != CRYPT_OK) ||
707 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, fp_cache[idx].LUT[1<<x]->z) != CRYPT_OK)) { goto ERR; }
708
709 /* now double it bitlen/FP_LUT times */
710 for (y = 0; y < lut_gap; y++) {
711 if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<<x], fp_cache[idx].LUT[1<<x], modulus, mp)) != CRYPT_OK) {
712 goto ERR;
713 }
714 }
715 }
716
717 /* now make all entries in increase order of hamming weight */
718 for (x = 2; x <= FP_LUT; x++) {
719 for (y = 0; y < (1UL<<FP_LUT); y++) {
720 if (lut_orders[y].ham != (int)x) continue;
721
722 /* perform the add */
723 if ((err = ltc_mp.ecc_ptadd(fp_cache[idx].LUT[lut_orders[y].terma], fp_cache[idx].LUT[lut_orders[y].termb],
724 fp_cache[idx].LUT[y], modulus, mp)) != CRYPT_OK) {
725 goto ERR;
726 }
727 }
728 }
729
730 /* now map all entries back to affine space to make point addition faster */
731 if ((err = mp_init(&tmp)) != CRYPT_OK) { goto ERR; }
732 for (x = 1; x < (1UL<<FP_LUT); x++) {
733 /* convert z to normal from montgomery */
734 if ((err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp)) != CRYPT_OK) { goto ERR; }
735
736 /* invert it */
737 if ((err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, fp_cache[idx].LUT[x]->z)) != CRYPT_OK) { goto ERR; }
738
739 /* now square it */
740 if ((err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; }
741
742 /* fix x */
743 if ((err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus, fp_cache[idx].LUT[x]->x)) != CRYPT_OK) { goto ERR; }
744
745 /* get 1/z^3 */
746 if ((err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; }
747
748 /* fix y */
749 if ((err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus, fp_cache[idx].LUT[x]->y)) != CRYPT_OK) { goto ERR; }
750
751 /* free z */
752 mp_clear(fp_cache[idx].LUT[x]->z);
753 fp_cache[idx].LUT[x]->z = NULL;
754 }
755 mp_clear(tmp);
756
757 return CRYPT_OK;
758 ERR:
759 err = CRYPT_MEM;
760 DONE:
761 for (y = 0; y < (1U<<FP_LUT); y++) {
762 ltc_ecc_del_point(fp_cache[idx].LUT[y]);
763 fp_cache[idx].LUT[y] = NULL;
764 }
765 ltc_ecc_del_point(fp_cache[idx].g);
766 fp_cache[idx].g = NULL;
767 fp_cache[idx].lru_count = 0;
768 if (fp_cache[idx].mu != NULL) {
769 mp_clear(fp_cache[idx].mu);
770 fp_cache[idx].mu = NULL;
771 }
772 if (tmp != NULL) {
773 mp_clear(tmp);
774 }
775 return err;
776 }
777
778 /* perform a fixed point ECC mulmod */
779 static int accel_fp_mul(int idx, void *k, ecc_point *R, void *modulus, void *mp, int map)
780 {
781 unsigned char kb[128];
782 int x;
783 unsigned y, z, err, bitlen, bitpos, lut_gap, first;
784 void *tk, *order;
785
786 /* if it's smaller than modulus we fine */
787 if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
788 /* find order */
789 y = mp_unsigned_bin_size(modulus);
790 for (x = 0; ltc_ecc_sets[x].size; x++) {
791 if (y <= (unsigned)ltc_ecc_sets[x].size) break;
792 }
793
794 /* back off if we are on the 521 bit curve */
795 if (y == 66) --x;
796
797 if ((err = mp_init(&order)) != CRYPT_OK) {
798 return err;
799 }
800 if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) {
801 mp_clear(&order);
802 return err;
803 }
804
805 /* k must be less than modulus */
806 if (mp_cmp(k, order) != LTC_MP_LT) {
807 if ((err = mp_init(&tk)) != CRYPT_OK) {
808 mp_clear(order);
809 return err;
810 }
811 if ((err = mp_mod(k, order, tk)) != CRYPT_OK) {
812 mp_clear(tk);
813 mp_clear(order);
814 return err;
815 }
816 } else {
817 tk = k;
818 }
819 mp_clear(order);
820 } else {
821 tk = k;
822 }
823
824 /* get bitlen and round up to next multiple of FP_LUT */
825 bitlen = mp_unsigned_bin_size(modulus) << 3;
826 x = bitlen % FP_LUT;
827 if (x) {
828 bitlen += FP_LUT - x;
829 }
830 lut_gap = bitlen / FP_LUT;
831
832 /* get the k value */
833 if (mp_unsigned_bin_size(tk) > (sizeof(kb) - 2)) {
834 if (tk != k) {
835 mp_clear(tk);
836 }
837 return CRYPT_BUFFER_OVERFLOW;
838 }
839
840 /* store k */
841 zeromem(kb, sizeof(kb));
842 if ((err = mp_to_unsigned_bin(tk, kb)) != CRYPT_OK) {
843 if (tk != k) {
844 mp_clear(tk);
845 }
846 return err;
847 }
848
849 /* let's reverse kb so it's little endian */
850 x = 0;
851 y = mp_unsigned_bin_size(tk) - 1;
852 if (tk != k) {
853 mp_clear(tk);
854 }
855 while ((unsigned)x < y) {
856 z = kb[x]; kb[x] = kb[y]; kb[y] = z;
857 ++x; --y;
858 }
859
860 /* at this point we can start, yipee */
861 first = 1;
862 for (x = lut_gap-1; x >= 0; x--) {
863 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */
864 bitpos = x;
865 for (y = z = 0; y < FP_LUT; y++) {
866 z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;
867 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */
868 }
869
870 /* double if not first */
871 if (!first) {
872 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) {
873 return err;
874 }
875 }
876
877 /* add if not first, otherwise copy */
878 if (!first && z) {
879 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, modulus, mp)) != CRYPT_OK) {
880 return err;
881 }
882 } else if (z) {
883 if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != CRYPT_OK) ||
884 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != CRYPT_OK) ||
885 (mp_copy(fp_cache[idx].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; }
886 first = 0;
887 }
888 }
889 z = 0;
890 zeromem(kb, sizeof(kb));
891 /* map R back from projective space */
892 if (map) {
893 err = ltc_ecc_map(R, modulus, mp);
894 } else {
895 err = CRYPT_OK;
896 }
897 return err;
898 }
899
900 #ifdef LTC_ECC_SHAMIR
901 /* perform a fixed point ECC mulmod */
902 static int accel_fp_mul2add(int idx1, int idx2,
903 void *kA, void *kB,
904 ecc_point *R, void *modulus, void *mp)
905 {
906 unsigned char kb[2][128];
907 int x;
908 unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB;
909 void *tka, *tkb, *order;
910
911 /* if it's smaller than modulus we fine */
912 if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
913 /* find order */
914 y = mp_unsigned_bin_size(modulus);
915 for (x = 0; ltc_ecc_sets[x].size; x++) {
916 if (y <= (unsigned)ltc_ecc_sets[x].size) break;
917 }
918
919 /* back off if we are on the 521 bit curve */
920 if (y == 66) --x;
921
922 if ((err = mp_init(&order)) != CRYPT_OK) {
923 return err;
924 }
925 if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) {
926 mp_clear(&order);
927 return err;
928 }
929
930 /* kA must be less than modulus */
931 if (mp_cmp(kA, order) != LTC_MP_LT) {
932 if ((err = mp_init(&tka)) != CRYPT_OK) {
933 mp_clear(order);
934 return err;
935 }
936 if ((err = mp_mod(kA, order, tka)) != CRYPT_OK) {
937 mp_clear(tka);
938 mp_clear(order);
939 return err;
940 }
941 } else {
942 tka = kA;
943 }
944 mp_clear(order);
945 } else {
946 tka = kA;
947 }
948
949 /* if it's smaller than modulus we fine */
950 if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
951 /* find order */
952 y = mp_unsigned_bin_size(modulus);
953 for (x = 0; ltc_ecc_sets[x].size; x++) {
954 if (y <= (unsigned)ltc_ecc_sets[x].size) break;
955 }
956
957 /* back off if we are on the 521 bit curve */
958 if (y == 66) --x;
959
960 if ((err = mp_init(&order)) != CRYPT_OK) {
961 return err;
962 }
963 if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) {
964 mp_clear(&order);
965 return err;
966 }
967
968 /* kB must be less than modulus */
969 if (mp_cmp(kB, order) != LTC_MP_LT) {
970 if ((err = mp_init(&tkb)) != CRYPT_OK) {
971 mp_clear(order);
972 return err;
973 }
974 if ((err = mp_mod(kB, order, tkb)) != CRYPT_OK) {
975 mp_clear(tkb);
976 mp_clear(order);
977 return err;
978 }
979 } else {
980 tkb = kB;
981 }
982 mp_clear(order);
983 } else {
984 tkb = kB;
985 }
986
987 /* get bitlen and round up to next multiple of FP_LUT */
988 bitlen = mp_unsigned_bin_size(modulus) << 3;
989 x = bitlen % FP_LUT;
990 if (x) {
991 bitlen += FP_LUT - x;
992 }
993 lut_gap = bitlen / FP_LUT;
994
995 /* get the k value */
996 if ((mp_unsigned_bin_size(tka) > (sizeof(kb[0]) - 2)) || (mp_unsigned_bin_size(tkb) > (sizeof(kb[0]) - 2)) ) {
997 if (tka != kA) {
998 mp_clear(tka);
999 }
1000 if (tkb != kB) {
1001 mp_clear(tkb);
1002 }
1003 return CRYPT_BUFFER_OVERFLOW;
1004 }
1005
1006 /* store k */
1007 zeromem(kb, sizeof(kb));
1008 if ((err = mp_to_unsigned_bin(tka, kb[0])) != CRYPT_OK) {
1009 if (tka != kA) {
1010 mp_clear(tka);
1011 }
1012 if (tkb != kB) {
1013 mp_clear(tkb);
1014 }
1015 return err;
1016 }
1017
1018 /* let's reverse kb so it's little endian */
1019 x = 0;
1020 y = mp_unsigned_bin_size(tka) - 1;
1021 if (tka != kA) {
1022 mp_clear(tka);
1023 }
1024 while ((unsigned)x < y) {
1025 z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z;
1026 ++x; --y;
1027 }
1028
1029 /* store b */
1030 if ((err = mp_to_unsigned_bin(tkb, kb[1])) != CRYPT_OK) {
1031 if (tkb != kB) {
1032 mp_clear(tkb);
1033 }
1034 return err;
1035 }
1036
1037 x = 0;
1038 y = mp_unsigned_bin_size(tkb) - 1;
1039 if (tkb != kB) {
1040 mp_clear(tkb);
1041 }
1042 while ((unsigned)x < y) {
1043 z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z;
1044 ++x; --y;
1045 }
1046
1047 /* at this point we can start, yipee */
1048 first = 1;
1049 for (x = lut_gap-1; x >= 0; x--) {
1050 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */
1051 bitpos = x;
1052 for (y = zA = zB = 0; y < FP_LUT; y++) {
1053 zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
1054 zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
1055 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */
1056 }
1057
1058 /* double if not first */
1059 if (!first) {
1060 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) {
1061 return err;
1062 }
1063 }
1064
1065 /* add if not first, otherwise copy */
1066 if (!first) {
1067 if (zA) {
1068 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, modulus, mp)) != CRYPT_OK) {
1069 return err;
1070 }
1071 }
1072 if (zB) {
1073 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) {
1074 return err;
1075 }
1076 }
1077 } else {
1078 if (zA) {
1079 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != CRYPT_OK) ||
1080 (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != CRYPT_OK) ||
1081 (mp_copy(fp_cache[idx1].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; }
1082 first = 0;
1083 }
1084 if (zB && first == 0) {
1085 if (zB) {
1086 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) {
1087 return err;
1088 }
1089 }
1090 } else if (zB && first == 1) {
1091 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != CRYPT_OK) ||
1092 (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != CRYPT_OK) ||
1093 (mp_copy(fp_cache[idx2].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; }
1094 first = 0;
1095 }
1096 }
1097 }
1098 zeromem(kb, sizeof(kb));
1099 return ltc_ecc_map(R, modulus, mp);
1100 }
1101
1102 /** ECC Fixed Point mulmod global
1103 Computes kA*A + kB*B = C using Shamir's Trick
1104 @param A First point to multiply
1105 @param kA What to multiple A by
1106 @param B Second point to multiply
1107 @param kB What to multiple B by
1108 @param C [out] Destination point (can overlap with A or B)
1109 @param modulus Modulus for curve
1110 @return CRYPT_OK on success
1111 */
1112 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
1113 ecc_point *B, void *kB,
1114 ecc_point *C, void *modulus)
1115 {
1116 int idx1, idx2, err;
1117 void *mp, *mu;
1118
1119 mp = NULL;
1120 mu = NULL;
1121 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1122 /* find point */
1123 idx1 = find_base(A);
1124
1125 /* no entry? */
1126 if (idx1 == -1) {
1127 /* find hole and add it */
1128 if ((idx1 = find_hole()) >= 0) {
1129 if ((err = add_entry(idx1, A)) != CRYPT_OK) {
1130 goto LBL_ERR;
1131 }
1132 }
1133 }
1134 if (idx1 != -1) {
1135 /* increment LRU */
1136 ++(fp_cache[idx1].lru_count);
1137 }
1138
1139 /* find point */
1140 idx2 = find_base(B);
1141
1142 /* no entry? */
1143 if (idx2 == -1) {
1144 /* find hole and add it */
1145 if ((idx2 = find_hole()) >= 0) {
1146 if ((err = add_entry(idx2, B)) != CRYPT_OK) {
1147 goto LBL_ERR;
1148 }
1149 }
1150 }
1151 if (idx2 != -1) {
1152 /* increment LRU */
1153 ++(fp_cache[idx2].lru_count);
1154 }
1155
1156 /* if it's 2 build the LUT, if it's higher just use the LUT */
1157 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
1158 /* compute mp */
1159 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1160
1161 /* compute mu */
1162 if ((err = mp_init(&mu)) != CRYPT_OK) {
1163 goto LBL_ERR;
1164 }
1165 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1166 goto LBL_ERR;
1167 }
1168
1169 /* build the LUT */
1170 if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) {
1171 goto LBL_ERR;;
1172 }
1173 }
1174
1175 /* if it's 2 build the LUT, if it's higher just use the LUT */
1176 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
1177 if (mp == NULL) {
1178 /* compute mp */
1179 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1180
1181 /* compute mu */
1182 if ((err = mp_init(&mu)) != CRYPT_OK) {
1183 goto LBL_ERR;
1184 }
1185 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1186 goto LBL_ERR;
1187 }
1188 }
1189
1190 /* build the LUT */
1191 if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) {
1192 goto LBL_ERR;;
1193 }
1194 }
1195
1196
1197 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) {
1198 if (mp == NULL) {
1199 /* compute mp */
1200 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1201 }
1202 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp);
1203 } else {
1204 err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus);
1205 }
1206 LBL_ERR:
1207 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1208 if (mp != NULL) {
1209 mp_montgomery_free(mp);
1210 }
1211 if (mu != NULL) {
1212 mp_clear(mu);
1213 }
1214 return err;
1215 }
1216 #endif
1217
1218 /** ECC Fixed Point mulmod global
1219 @param k The multiplicand
1220 @param G Base point to multiply
1221 @param R [out] Destination of product
1222 @param modulus The modulus for the curve
1223 @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form
1224 @return CRYPT_OK if successful
1225 */
1226 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
1227 {
1228 int idx, err;
1229 void *mp, *mu;
1230
1231 mp = NULL;
1232 mu = NULL;
1233 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1234 /* find point */
1235 idx = find_base(G);
1236
1237 /* no entry? */
1238 if (idx == -1) {
1239 /* find hole and add it */
1240 idx = find_hole();
1241
1242 if (idx >= 0) {
1243 if ((err = add_entry(idx, G)) != CRYPT_OK) {
1244 goto LBL_ERR;
1245 }
1246 }
1247 }
1248 if (idx != -1) {
1249 /* increment LRU */
1250 ++(fp_cache[idx].lru_count);
1251 }
1252
1253
1254 /* if it's 2 build the LUT, if it's higher just use the LUT */
1255 if (idx >= 0 && fp_cache[idx].lru_count == 2) {
1256 /* compute mp */
1257 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1258
1259 /* compute mu */
1260 if ((err = mp_init(&mu)) != CRYPT_OK) {
1261 goto LBL_ERR;
1262 }
1263 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1264 goto LBL_ERR;
1265 }
1266
1267 /* build the LUT */
1268 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1269 goto LBL_ERR;;
1270 }
1271 }
1272
1273 if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
1274 if (mp == NULL) {
1275 /* compute mp */
1276 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1277 }
1278 err = accel_fp_mul(idx, k, R, modulus, mp, map);
1279 } else {
1280 err = ltc_ecc_mulmod(k, G, R, modulus, map);
1281 }
1282 LBL_ERR:
1283 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1284 if (mp != NULL) {
1285 mp_montgomery_free(mp);
1286 }
1287 if (mu != NULL) {
1288 mp_clear(mu);
1289 }
1290 return err;
1291 }
1292
1293 /* helper function for freeing the cache ... must be called with the cache mutex locked */
1294 static void ltc_ecc_fp_free_cache(void)
1295 {
1296 unsigned x, y;
1297 for (x = 0; x < FP_ENTRIES; x++) {
1298 if (fp_cache[x].g != NULL) {
1299 for (y = 0; y < (1U<<FP_LUT); y++) {
1300 ltc_ecc_del_point(fp_cache[x].LUT[y]);
1301 fp_cache[x].LUT[y] = NULL;
1302 }
1303 ltc_ecc_del_point(fp_cache[x].g);
1304 fp_cache[x].g = NULL;
1305 if (fp_cache[x].mu != NULL) {
1306 mp_clear(fp_cache[x].mu);
1307 fp_cache[x].mu = NULL;
1308 }
1309 fp_cache[x].lru_count = 0;
1310 fp_cache[x].lock = 0;
1311 }
1312 }
1313 }
1314
1315 /** Free the Fixed Point cache */
1316 void ltc_ecc_fp_free(void)
1317 {
1318 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1319 ltc_ecc_fp_free_cache();
1320 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1321 }
1322
1323 /** Add a point to the cache and initialize the LUT
1324 @param g The point to add
1325 @param modulus Modulus for curve
1326 @param lock Flag to indicate if this entry should be locked into the cache or not
1327 @return CRYPT_OK on success
1328 */
1329 int
1330 ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock)
1331 {
1332 int idx;
1333 int err;
1334 void *mp = NULL;
1335 void *mu = NULL;
1336
1337 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1338 if ((idx = find_base(g)) >= 0) {
1339 /* it is already in the cache ... just check that the LUT is initialized */
1340 if(fp_cache[idx].lru_count >= 2) {
1341 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1342 return CRYPT_OK;
1343 }
1344 }
1345
1346 if(idx == -1 && (idx = find_hole()) == -1) {
1347 err = CRYPT_BUFFER_OVERFLOW;
1348 goto LBL_ERR;
1349 }
1350 if ((err = add_entry(idx, g)) != CRYPT_OK) {
1351 goto LBL_ERR;
1352 }
1353 /* compute mp */
1354 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
1355 goto LBL_ERR;
1356 }
1357
1358 /* compute mu */
1359 if ((err = mp_init(&mu)) != CRYPT_OK) {
1360 goto LBL_ERR;
1361 }
1362 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1363 goto LBL_ERR;
1364 }
1365
1366 /* build the LUT */
1367 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1368 goto LBL_ERR;
1369 }
1370 fp_cache[idx].lru_count = 2;
1371 fp_cache[idx].lock = lock;
1372 LBL_ERR:
1373 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1374 if (mp != NULL) {
1375 mp_montgomery_free(mp);
1376 }
1377 if (mu != NULL) {
1378 mp_clear(mu);
1379 }
1380 return err;
1381 }
1382
1383 /** Prevent/permit the FP cache from being updated
1384 @param flag If flag is 0, remove cache lock (unlock), otherwise lock it
1385 */
1386 void ltc_ecc_fp_tablelock(int lock)
1387 {
1388 int i;
1389
1390 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1391 for (i = 0; i < FP_ENTRIES; i++) {
1392 fp_cache[i].lock = lock;
1393 }
1394 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1395 }
1396
1397 /** Export the current cache as a binary packet
1398 @param out [out] pointer to malloc'ed space containing the packet
1399 @param outlen [out] size of exported packet
1400 @return CRYPT_OK if successful
1401 */
1402 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen)
1403 {
1404 ltc_asn1_list *cache_entry;
1405 unsigned int i, j, k;
1406 unsigned long fp_entries, fp_lut, num_entries;
1407 int err;
1408
1409 LTC_ARGCHK(out != NULL);
1410 LTC_ARGCHK(outlen != NULL);
1411
1412 fp_entries = FP_ENTRIES;
1413 fp_lut = FP_LUT;
1414 num_entries = 0;
1415
1416 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1417 /*
1418 * build the list;
1419 Cache DEFINITIONS ::=
1420 BEGIN
1421 CacheDump ::= SEQUENCE {
1422 numEntries SHORTINTEGER,
1423 maxEntries SHORTINTEGER,
1424 numLUT SHORTINTEGER,
1425 cache SEQUENCE OF INTEGER
1426 }
1427 END
1428 *
1429 */
1430 /*
1431 * The cache itself is a point (3 INTEGERS),
1432 * the LUT as pairs of INTEGERS (2 * 1<<FP_LUT),
1433 * and the mu INTEGER
1434 */
1435 cache_entry = XCALLOC(FP_ENTRIES*(2*(1U<<FP_LUT)+4)+3, sizeof(ltc_asn1_list));
1436 if (cache_entry == NULL)
1437 return CRYPT_MEM;
1438 j = 1; /* handle the zero'th element later */
1439
1440 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1);
1441 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1);
1442
1443 for (i = 0; i < FP_ENTRIES; i++) {
1444 /*
1445 * do not save empty entries, or entries that have not yet had the lut built
1446 */
1447 if (fp_cache[i].g == NULL || fp_cache[i].lru_count < 2) {
1448 continue;
1449 }
1450 num_entries++;
1451 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1);
1452 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1);
1453 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1);
1454 for (k = 0; k < (1U<<FP_LUT); k++) {
1455 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->x, 1);
1456 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->y, 1);
1457 }
1458 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1);
1459 }
1460 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_EOL, 0, 0);
1461
1462 LTC_SET_ASN1(cache_entry, 0, LTC_ASN1_SHORT_INTEGER, &num_entries, 1);
1463
1464 if ((err = der_length_sequence(cache_entry, j, outlen)) != CRYPT_OK) {
1465 goto save_err;
1466 }
1467 if ((*out = XMALLOC(*outlen)) == NULL) {
1468 err = CRYPT_MEM;
1469 goto save_err;
1470 }
1471 err = der_encode_sequence(cache_entry, j, *out, outlen);
1472 save_err:
1473 XFREE(cache_entry);
1474 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1475 return err;
1476 }
1477
1478 /** Import a binary packet into the current cache
1479 @param in [in] pointer to packet
1480 @param inlen [in] size of packet (bytes)
1481 @return CRYPT_OK if successful
1482 */
1483 int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen)
1484 {
1485 int err;
1486 ltc_asn1_list *asn1_list;
1487 unsigned long num_entries, fp_entries, fp_lut;
1488 unsigned long i, j;
1489 unsigned int x;
1490
1491 LTC_ARGCHK(in != NULL);
1492 if (inlen == 0) {
1493 return CRYPT_INVALID_ARG;
1494 }
1495
1496 /* zero indecies */
1497 i = 0;
1498 j = 0;
1499 asn1_list = NULL;
1500
1501 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1502 /*
1503 * start with an empty cache
1504 */
1505 ltc_ecc_fp_free_cache();
1506
1507 /*
1508 * decode the input packet: It consists of a sequence with a few
1509 * integers (including the FP_ENTRIES and FP_LUT sizes), followed by a
1510 * SEQUENCE which is the cache itself.
1511 *
1512 * use standard decoding for the first part, then flexible for the second
1513 */
1514 if((err = der_decode_sequence_multi(in, inlen,
1515 LTC_ASN1_SHORT_INTEGER, 1, &num_entries,
1516 LTC_ASN1_SHORT_INTEGER, 1, &fp_entries,
1517 LTC_ASN1_SHORT_INTEGER, 1, &fp_lut,
1518 LTC_ASN1_EOL, 0, 0)) != CRYPT_OK) {
1519 goto ERR_OUT;
1520 }
1521 if (fp_entries != FP_ENTRIES || fp_lut != FP_LUT || num_entries > fp_entries) {
1522 err = CRYPT_INVALID_PACKET;
1523 goto ERR_OUT;
1524 }
1525 if ((asn1_list = XCALLOC(3+num_entries*(4+2*(1<<FP_LUT))+1, sizeof(ltc_asn1_list))) == NULL) {
1526 err = CRYPT_MEM;
1527 goto ERR_OUT;
1528 }
1529 j = 0;
1530 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &num_entries, 1);
1531 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1);
1532 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1);
1533 for (i = 0; i < num_entries; i++) {
1534 if((fp_cache[i].g = ltc_ecc_new_point()) == NULL) {
1535 err = CRYPT_MEM;
1536 goto ERR_OUT;
1537 }
1538 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1);
1539 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1);
1540 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1);
1541 for (x = 0; x < (1U<<FP_LUT); x++) {
1542 /* since we don't store z in the cache, don't use ltc_ecc_new_point()
1543 * (which allocates space for z, only to have to free it later) */
1544 ecc_point *p = XCALLOC(1, sizeof(*p));
1545
1546 if (p == NULL) {
1547 err = CRYPT_MEM;
1548 goto ERR_OUT;
1549 }
1550 fp_cache[i].LUT[x] = p;
1551 if ((err = mp_init_multi(&p->x, &p->y, NULL)) != CRYPT_OK) {
1552 goto ERR_OUT;
1553 }
1554 p->z = NULL;
1555 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->x, 1);
1556 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->y, 1);
1557 }
1558 if((err = mp_init(&fp_cache[i].mu)) != CRYPT_OK) {
1559 goto ERR_OUT;
1560 }
1561 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1);
1562 fp_cache[i].lru_count = 3;
1563 fp_cache[i].lock = 1;
1564 }
1565
1566 if ((err = der_decode_sequence(in, inlen, asn1_list, j)) != CRYPT_OK) {
1567 goto ERR_OUT;
1568 }
1569 XFREE(asn1_list);
1570 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1571 return CRYPT_OK;
1572 ERR_OUT:
1573 if(asn1_list)
1574 XFREE(asn1_list);
1575 ltc_ecc_fp_free_cache();
1576 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1577 return err;
1578 }
1579
1580 #endif
1581
1582
1583 /* $Source$ */
1584 /* $Revision$ */
1585 /* $Date$ */
1586
+0
-512
libtom-src/math/ltm_desc.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #define DESC_DEF_ONLY
12 #include "tomcrypt.h"
13
14 #ifdef LTM_DESC
15
16 #include <tommath.h>
17
18 static const struct {
19 int mpi_code, ltc_code;
20 } mpi_to_ltc_codes[] = {
21 { MP_OKAY , CRYPT_OK},
22 { MP_MEM , CRYPT_MEM},
23 { MP_VAL , CRYPT_INVALID_ARG},
24 };
25
26 /**
27 Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no)
28 @param err The error to convert
29 @return The equivalent LTC error code or CRYPT_ERROR if none found
30 */
31 static int mpi_to_ltc_error(int err)
32 {
33 int x;
34
35 for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
36 if (err == mpi_to_ltc_codes[x].mpi_code) {
37 return mpi_to_ltc_codes[x].ltc_code;
38 }
39 }
40 return CRYPT_ERROR;
41 }
42
43 static int init(void **a)
44 {
45 int err;
46
47 LTC_ARGCHK(a != NULL);
48
49 *a = XCALLOC(1, sizeof(mp_int));
50 if (*a == NULL) {
51 return CRYPT_MEM;
52 }
53
54 if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) {
55 XFREE(*a);
56 }
57 return err;
58 }
59
60 static void deinit(void *a)
61 {
62 LTC_ARGCHKVD(a != NULL);
63 mp_clear(a);
64 XFREE(a);
65 }
66
67 static int neg(void *a, void *b)
68 {
69 LTC_ARGCHK(a != NULL);
70 LTC_ARGCHK(b != NULL);
71 return mpi_to_ltc_error(mp_neg(a, b));
72 }
73
74 static int copy(void *a, void *b)
75 {
76 LTC_ARGCHK(a != NULL);
77 LTC_ARGCHK(b != NULL);
78 return mpi_to_ltc_error(mp_copy(a, b));
79 }
80
81 static int init_copy(void **a, void *b)
82 {
83 if (init(a) != CRYPT_OK) {
84 return CRYPT_MEM;
85 }
86 return copy(b, *a);
87 }
88
89 /* ---- trivial ---- */
90 static int set_int(void *a, unsigned long b)
91 {
92 LTC_ARGCHK(a != NULL);
93 return mpi_to_ltc_error(mp_set_int(a, b));
94 }
95
96 static unsigned long get_int(void *a)
97 {
98 LTC_ARGCHK(a != NULL);
99 return mp_get_int(a);
100 }
101
102 static unsigned long get_digit(void *a, int n)
103 {
104 mp_int *A;
105 LTC_ARGCHK(a != NULL);
106 A = a;
107 return (n >= A->used || n < 0) ? 0 : A->dp[n];
108 }
109
110 static int get_digit_count(void *a)
111 {
112 mp_int *A;
113 LTC_ARGCHK(a != NULL);
114 A = a;
115 return A->used;
116 }
117
118 static int compare(void *a, void *b)
119 {
120 int ret;
121 LTC_ARGCHK(a != NULL);
122 LTC_ARGCHK(b != NULL);
123 ret = mp_cmp(a, b);
124 switch (ret) {
125 case MP_LT: return LTC_MP_LT;
126 case MP_EQ: return LTC_MP_EQ;
127 case MP_GT: return LTC_MP_GT;
128 }
129 return 0;
130 }
131
132 static int compare_d(void *a, unsigned long b)
133 {
134 int ret;
135 LTC_ARGCHK(a != NULL);
136 ret = mp_cmp_d(a, b);
137 switch (ret) {
138 case MP_LT: return LTC_MP_LT;
139 case MP_EQ: return LTC_MP_EQ;
140 case MP_GT: return LTC_MP_GT;
141 }
142 return 0;
143 }
144
145 static int count_bits(void *a)
146 {
147 LTC_ARGCHK(a != NULL);
148 return mp_count_bits(a);
149 }
150
151 static int count_lsb_bits(void *a)
152 {
153 LTC_ARGCHK(a != NULL);
154 return mp_cnt_lsb(a);
155 }
156
157
158 static int twoexpt(void *a, int n)
159 {
160 LTC_ARGCHK(a != NULL);
161 return mpi_to_ltc_error(mp_2expt(a, n));
162 }
163
164 /* ---- conversions ---- */
165
166 /* read ascii string */
167 static int read_radix(void *a, const char *b, int radix)
168 {
169 LTC_ARGCHK(a != NULL);
170 LTC_ARGCHK(b != NULL);
171 return mpi_to_ltc_error(mp_read_radix(a, b, radix));
172 }
173
174 /* write one */
175 static int write_radix(void *a, char *b, int radix)
176 {
177 LTC_ARGCHK(a != NULL);
178 LTC_ARGCHK(b != NULL);
179 return mpi_to_ltc_error(mp_toradix(a, b, radix));
180 }
181
182 /* get size as unsigned char string */
183 static unsigned long unsigned_size(void *a)
184 {
185 LTC_ARGCHK(a != NULL);
186 return mp_unsigned_bin_size(a);
187 }
188
189 /* store */
190 static int unsigned_write(void *a, unsigned char *b)
191 {
192 LTC_ARGCHK(a != NULL);
193 LTC_ARGCHK(b != NULL);
194 return mpi_to_ltc_error(mp_to_unsigned_bin(a, b));
195 }
196
197 /* read */
198 static int unsigned_read(void *a, unsigned char *b, unsigned long len)
199 {
200 LTC_ARGCHK(a != NULL);
201 LTC_ARGCHK(b != NULL);
202 return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len));
203 }
204
205 /* add */
206 static int add(void *a, void *b, void *c)
207 {
208 LTC_ARGCHK(a != NULL);
209 LTC_ARGCHK(b != NULL);
210 LTC_ARGCHK(c != NULL);
211 return mpi_to_ltc_error(mp_add(a, b, c));
212 }
213
214 static int addi(void *a, unsigned long b, void *c)
215 {
216 LTC_ARGCHK(a != NULL);
217 LTC_ARGCHK(c != NULL);
218 return mpi_to_ltc_error(mp_add_d(a, b, c));
219 }
220
221 /* sub */
222 static int sub(void *a, void *b, void *c)
223 {
224 LTC_ARGCHK(a != NULL);
225 LTC_ARGCHK(b != NULL);
226 LTC_ARGCHK(c != NULL);
227 return mpi_to_ltc_error(mp_sub(a, b, c));
228 }
229
230 static int subi(void *a, unsigned long b, void *c)
231 {
232 LTC_ARGCHK(a != NULL);
233 LTC_ARGCHK(c != NULL);
234 return mpi_to_ltc_error(mp_sub_d(a, b, c));
235 }
236
237 /* mul */
238 static int mul(void *a, void *b, void *c)
239 {
240 LTC_ARGCHK(a != NULL);
241 LTC_ARGCHK(b != NULL);
242 LTC_ARGCHK(c != NULL);
243 return mpi_to_ltc_error(mp_mul(a, b, c));
244 }
245
246 static int muli(void *a, unsigned long b, void *c)
247 {
248 LTC_ARGCHK(a != NULL);
249 LTC_ARGCHK(c != NULL);
250 return mpi_to_ltc_error(mp_mul_d(a, b, c));
251 }
252
253 /* sqr */
254 static int sqr(void *a, void *b)
255 {
256 LTC_ARGCHK(a != NULL);
257 LTC_ARGCHK(b != NULL);
258 return mpi_to_ltc_error(mp_sqr(a, b));
259 }
260
261 /* div */
262 static int divide(void *a, void *b, void *c, void *d)
263 {
264 LTC_ARGCHK(a != NULL);
265 LTC_ARGCHK(b != NULL);
266 return mpi_to_ltc_error(mp_div(a, b, c, d));
267 }
268
269 static int div_2(void *a, void *b)
270 {
271 LTC_ARGCHK(a != NULL);
272 LTC_ARGCHK(b != NULL);
273 return mpi_to_ltc_error(mp_div_2(a, b));
274 }
275
276 /* modi */
277 static int modi(void *a, unsigned long b, unsigned long *c)
278 {
279 mp_digit tmp;
280 int err;
281
282 LTC_ARGCHK(a != NULL);
283 LTC_ARGCHK(c != NULL);
284
285 if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) {
286 return err;
287 }
288 *c = tmp;
289 return CRYPT_OK;
290 }
291
292 /* gcd */
293 static int gcd(void *a, void *b, void *c)
294 {
295 LTC_ARGCHK(a != NULL);
296 LTC_ARGCHK(b != NULL);
297 LTC_ARGCHK(c != NULL);
298 return mpi_to_ltc_error(mp_gcd(a, b, c));
299 }
300
301 /* lcm */
302 static int lcm(void *a, void *b, void *c)
303 {
304 LTC_ARGCHK(a != NULL);
305 LTC_ARGCHK(b != NULL);
306 LTC_ARGCHK(c != NULL);
307 return mpi_to_ltc_error(mp_lcm(a, b, c));
308 }
309
310 static int addmod(void *a, void *b, void *c, void *d)
311 {
312 LTC_ARGCHK(a != NULL);
313 LTC_ARGCHK(b != NULL);
314 LTC_ARGCHK(c != NULL);
315 LTC_ARGCHK(d != NULL);
316 return mpi_to_ltc_error(mp_addmod(a,b,c,d));
317 }
318
319 static int submod(void *a, void *b, void *c, void *d)
320 {
321 LTC_ARGCHK(a != NULL);
322 LTC_ARGCHK(b != NULL);
323 LTC_ARGCHK(c != NULL);
324 LTC_ARGCHK(d != NULL);
325 return mpi_to_ltc_error(mp_submod(a,b,c,d));
326 }
327
328 static int mulmod(void *a, void *b, void *c, void *d)
329 {
330 LTC_ARGCHK(a != NULL);
331 LTC_ARGCHK(b != NULL);
332 LTC_ARGCHK(c != NULL);
333 LTC_ARGCHK(d != NULL);
334 return mpi_to_ltc_error(mp_mulmod(a,b,c,d));
335 }
336
337 static int sqrmod(void *a, void *b, void *c)
338 {
339 LTC_ARGCHK(a != NULL);
340 LTC_ARGCHK(b != NULL);
341 LTC_ARGCHK(c != NULL);
342 return mpi_to_ltc_error(mp_sqrmod(a,b,c));
343 }
344
345 /* invmod */
346 static int invmod(void *a, void *b, void *c)
347 {
348 LTC_ARGCHK(a != NULL);
349 LTC_ARGCHK(b != NULL);
350 LTC_ARGCHK(c != NULL);
351 return mpi_to_ltc_error(mp_invmod(a, b, c));
352 }
353
354 /* setup */
355 static int montgomery_setup(void *a, void **b)
356 {
357 int err;
358 LTC_ARGCHK(a != NULL);
359 LTC_ARGCHK(b != NULL);
360 *b = XCALLOC(1, sizeof(mp_digit));
361 if (*b == NULL) {
362 return CRYPT_MEM;
363 }
364 if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) {
365 XFREE(*b);
366 }
367 return err;
368 }
369
370 /* get normalization value */
371 static int montgomery_normalization(void *a, void *b)
372 {
373 LTC_ARGCHK(a != NULL);
374 LTC_ARGCHK(b != NULL);
375 return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b));
376 }
377
378 /* reduce */
379 static int montgomery_reduce(void *a, void *b, void *c)
380 {
381 LTC_ARGCHK(a != NULL);
382 LTC_ARGCHK(b != NULL);
383 LTC_ARGCHK(c != NULL);
384 return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c)));
385 }
386
387 /* clean up */
388 static void montgomery_deinit(void *a)
389 {
390 XFREE(a);
391 }
392
393 static int exptmod(void *a, void *b, void *c, void *d)
394 {
395 LTC_ARGCHK(a != NULL);
396 LTC_ARGCHK(b != NULL);
397 LTC_ARGCHK(c != NULL);
398 LTC_ARGCHK(d != NULL);
399 return mpi_to_ltc_error(mp_exptmod(a,b,c,d));
400 }
401
402 static int isprime(void *a, int *b)
403 {
404 int err;
405 LTC_ARGCHK(a != NULL);
406 LTC_ARGCHK(b != NULL);
407 err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b));
408 *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO;
409 return err;
410 }
411
412 static int set_rand(void *a, int size)
413 {
414 LTC_ARGCHK(a != NULL);
415 return mpi_to_ltc_error(mp_rand(a, size));
416 }
417
418 const ltc_math_descriptor ltm_desc = {
419
420 "LibTomMath",
421 (int)DIGIT_BIT,
422
423 &init,
424 &init_copy,
425 &deinit,
426
427 &neg,
428 &copy,
429
430 &set_int,
431 &get_int,
432 &get_digit,
433 &get_digit_count,
434 &compare,
435 &compare_d,
436 &count_bits,
437 &count_lsb_bits,
438 &twoexpt,
439
440 &read_radix,
441 &write_radix,
442 &unsigned_size,
443 &unsigned_write,
444 &unsigned_read,
445
446 &add,
447 &addi,
448 &sub,
449 &subi,
450 &mul,
451 &muli,
452 &sqr,
453 &divide,
454 &div_2,
455 &modi,
456 &gcd,
457 &lcm,
458
459 &mulmod,
460 &sqrmod,
461 &invmod,
462
463 &montgomery_setup,
464 &montgomery_normalization,
465 &montgomery_reduce,
466 &montgomery_deinit,
467
468 &exptmod,
469 &isprime,
470
471 #ifdef LTC_MECC
472 #ifdef LTC_MECC_FP
473 &ltc_ecc_fp_mulmod,
474 #else
475 &ltc_ecc_mulmod,
476 #endif
477 &ltc_ecc_projective_add_point,
478 &ltc_ecc_projective_dbl_point,
479 &ltc_ecc_map,
480 #ifdef LTC_ECC_SHAMIR
481 #ifdef LTC_MECC_FP
482 &ltc_ecc_fp_mul2add,
483 #else
484 &ltc_ecc_mul2add,
485 #endif /* LTC_MECC_FP */
486 #else
487 NULL,
488 #endif /* LTC_ECC_SHAMIR */
489 #else
490 NULL, NULL, NULL, NULL, NULL,
491 #endif /* LTC_MECC */
492
493 #ifdef LTC_MRSA
494 &rsa_make_key,
495 &rsa_exptmod,
496 #else
497 NULL, NULL,
498 #endif
499 &addmod,
500 &submod,
501
502 &set_rand,
503
504 };
505
506
507 #endif
508
509 /* $Source$ */
510 /* $Revision$ */
511 /* $Date$ */
+0
-61
libtom-src/math/multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 #ifdef MPI
13 #include <stdarg.h>
14
15 int ltc_init_multi(void **a, ...)
16 {
17 void **cur = a;
18 int np = 0;
19 va_list args;
20
21 va_start(args, a);
22 while (cur != NULL) {
23 if (mp_init(cur) != CRYPT_OK) {
24 /* failed */
25 va_list clean_list;
26
27 va_start(clean_list, a);
28 cur = a;
29 while (np--) {
30 mp_clear(*cur);
31 cur = va_arg(clean_list, void**);
32 }
33 va_end(clean_list);
34 return CRYPT_MEM;
35 }
36 ++np;
37 cur = va_arg(args, void**);
38 }
39 va_end(args);
40 return CRYPT_OK;
41 }
42
43 void ltc_deinit_multi(void *a, ...)
44 {
45 void *cur = a;
46 va_list args;
47
48 va_start(args, a);
49 while (cur != NULL) {
50 mp_clear(cur);
51 cur = va_arg(args, void *);
52 }
53 va_end(args);
54 }
55
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
+0
-87
libtom-src/math/rand_prime.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rand_prime.c
14 Generate a random prime, Tom St Denis
15 */
16
17 #define USE_BBS 1
18
19 int rand_prime(void *N, long len, prng_state *prng, int wprng)
20 {
21 int err, res, type;
22 unsigned char *buf;
23
24 LTC_ARGCHK(N != NULL);
25
26 /* get type */
27 if (len < 0) {
28 type = USE_BBS;
29 len = -len;
30 } else {
31 type = 0;
32 }
33
34 /* allow sizes between 2 and 512 bytes for a prime size */
35 if (len < 2 || len > 512) {
36 return CRYPT_INVALID_PRIME_SIZE;
37 }
38
39 /* valid PRNG? Better be! */
40 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
41 return err;
42 }
43
44 /* allocate buffer to work with */
45 buf = XCALLOC(1, len);
46 if (buf == NULL) {
47 return CRYPT_MEM;
48 }
49
50 do {
51 /* generate value */
52 if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) {
53 XFREE(buf);
54 return CRYPT_ERROR_READPRNG;
55 }
56
57 /* munge bits */
58 buf[0] |= 0x80 | 0x40;
59 buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
60
61 /* load value */
62 if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) {
63 XFREE(buf);
64 return err;
65 }
66
67 /* test */
68 if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) {
69 XFREE(buf);
70 return err;
71 }
72 } while (res == LTC_MP_NO);
73
74 #ifdef LTC_CLEAN_STACK
75 zeromem(buf, len);
76 #endif
77
78 XFREE(buf);
79 return CRYPT_OK;
80 }
81
82
83
84 /* $Source$ */
85 /* $Revision$ */
86 /* $Date$ */
+0
-799
libtom-src/math/tfm_desc.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #define DESC_DEF_ONLY
12 #include "tomcrypt.h"
13
14 #ifdef TFM_DESC
15
16 #include <tfm.h>
17
18 static const struct {
19 int tfm_code, ltc_code;
20 } tfm_to_ltc_codes[] = {
21 { FP_OKAY , CRYPT_OK},
22 { FP_MEM , CRYPT_MEM},
23 { FP_VAL , CRYPT_INVALID_ARG},
24 };
25
26 /**
27 Convert a tfm error to a LTC error (Possibly the most powerful function ever! Oh wait... no)
28 @param err The error to convert
29 @return The equivalent LTC error code or CRYPT_ERROR if none found
30 */
31 static int tfm_to_ltc_error(int err)
32 {
33 int x;
34
35 for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) {
36 if (err == tfm_to_ltc_codes[x].tfm_code) {
37 return tfm_to_ltc_codes[x].ltc_code;
38 }
39 }
40 return CRYPT_ERROR;
41 }
42
43 static int init(void **a)
44 {
45 LTC_ARGCHK(a != NULL);
46
47 *a = XCALLOC(1, sizeof(fp_int));
48 if (*a == NULL) {
49 return CRYPT_MEM;
50 }
51 fp_init(*a);
52 return CRYPT_OK;
53 }
54
55 static void deinit(void *a)
56 {
57 LTC_ARGCHKVD(a != NULL);
58 XFREE(a);
59 }
60
61 static int neg(void *a, void *b)
62 {
63 LTC_ARGCHK(a != NULL);
64 LTC_ARGCHK(b != NULL);
65 fp_neg(((fp_int*)a), ((fp_int*)b));
66 return CRYPT_OK;
67 }
68
69 static int copy(void *a, void *b)
70 {
71 LTC_ARGCHK(a != NULL);
72 LTC_ARGCHK(b != NULL);
73 fp_copy(a, b);
74 return CRYPT_OK;
75 }
76
77 static int init_copy(void **a, void *b)
78 {
79 if (init(a) != CRYPT_OK) {
80 return CRYPT_MEM;
81 }
82 return copy(b, *a);
83 }
84
85 /* ---- trivial ---- */
86 static int set_int(void *a, unsigned long b)
87 {
88 LTC_ARGCHK(a != NULL);
89 fp_set(a, b);
90 return CRYPT_OK;
91 }
92
93 static unsigned long get_int(void *a)
94 {
95 fp_int *A;
96 LTC_ARGCHK(a != NULL);
97 A = a;
98 return A->used > 0 ? A->dp[0] : 0;
99 }
100
101 static unsigned long get_digit(void *a, int n)
102 {
103 fp_int *A;
104 LTC_ARGCHK(a != NULL);
105 A = a;
106 return (n >= A->used || n < 0) ? 0 : A->dp[n];
107 }
108
109 static int get_digit_count(void *a)
110 {
111 fp_int *A;
112 LTC_ARGCHK(a != NULL);
113 A = a;
114 return A->used;
115 }
116
117 static int compare(void *a, void *b)
118 {
119 int ret;
120 LTC_ARGCHK(a != NULL);
121 LTC_ARGCHK(b != NULL);
122 ret = fp_cmp(a, b);
123 switch (ret) {
124 case FP_LT: return LTC_MP_LT;
125 case FP_EQ: return LTC_MP_EQ;
126 case FP_GT: return LTC_MP_GT;
127 }
128 return 0;
129 }
130
131 static int compare_d(void *a, unsigned long b)
132 {
133 int ret;
134 LTC_ARGCHK(a != NULL);
135 ret = fp_cmp_d(a, b);
136 switch (ret) {
137 case FP_LT: return LTC_MP_LT;
138 case FP_EQ: return LTC_MP_EQ;
139 case FP_GT: return LTC_MP_GT;
140 }
141 return 0;
142 }
143
144 static int count_bits(void *a)
145 {
146 LTC_ARGCHK(a != NULL);
147 return fp_count_bits(a);
148 }
149
150 static int count_lsb_bits(void *a)
151 {
152 LTC_ARGCHK(a != NULL);
153 return fp_cnt_lsb(a);
154 }
155
156 static int twoexpt(void *a, int n)
157 {
158 LTC_ARGCHK(a != NULL);
159 fp_2expt(a, n);
160 return CRYPT_OK;
161 }
162
163 /* ---- conversions ---- */
164
165 /* read ascii string */
166 static int read_radix(void *a, const char *b, int radix)
167 {
168 LTC_ARGCHK(a != NULL);
169 LTC_ARGCHK(b != NULL);
170 return tfm_to_ltc_error(fp_read_radix(a, (char *)b, radix));
171 }
172
173 /* write one */
174 static int write_radix(void *a, char *b, int radix)
175 {
176 LTC_ARGCHK(a != NULL);
177 LTC_ARGCHK(b != NULL);
178 return tfm_to_ltc_error(fp_toradix(a, b, radix));
179 }
180
181 /* get size as unsigned char string */
182 static unsigned long unsigned_size(void *a)
183 {
184 LTC_ARGCHK(a != NULL);
185 return fp_unsigned_bin_size(a);
186 }
187
188 /* store */
189 static int unsigned_write(void *a, unsigned char *b)
190 {
191 LTC_ARGCHK(a != NULL);
192 LTC_ARGCHK(b != NULL);
193 fp_to_unsigned_bin(a, b);
194 return CRYPT_OK;
195 }
196
197 /* read */
198 static int unsigned_read(void *a, unsigned char *b, unsigned long len)
199 {
200 LTC_ARGCHK(a != NULL);
201 LTC_ARGCHK(b != NULL);
202 fp_read_unsigned_bin(a, b, len);
203 return CRYPT_OK;
204 }
205
206 /* add */
207 static int add(void *a, void *b, void *c)
208 {
209 LTC_ARGCHK(a != NULL);
210 LTC_ARGCHK(b != NULL);
211 LTC_ARGCHK(c != NULL);
212 fp_add(a, b, c);
213 return CRYPT_OK;
214 }
215
216 static int addi(void *a, unsigned long b, void *c)
217 {
218 LTC_ARGCHK(a != NULL);
219 LTC_ARGCHK(c != NULL);
220 fp_add_d(a, b, c);
221 return CRYPT_OK;
222 }
223
224 /* sub */
225 static int sub(void *a, void *b, void *c)
226 {
227 LTC_ARGCHK(a != NULL);
228 LTC_ARGCHK(b != NULL);
229 LTC_ARGCHK(c != NULL);
230 fp_sub(a, b, c);
231 return CRYPT_OK;
232 }
233
234 static int subi(void *a, unsigned long b, void *c)
235 {
236 LTC_ARGCHK(a != NULL);
237 LTC_ARGCHK(c != NULL);
238 fp_sub_d(a, b, c);
239 return CRYPT_OK;
240 }
241
242 /* mul */
243 static int mul(void *a, void *b, void *c)
244 {
245 LTC_ARGCHK(a != NULL);
246 LTC_ARGCHK(b != NULL);
247 LTC_ARGCHK(c != NULL);
248 fp_mul(a, b, c);
249 return CRYPT_OK;
250 }
251
252 static int muli(void *a, unsigned long b, void *c)
253 {
254 LTC_ARGCHK(a != NULL);
255 LTC_ARGCHK(c != NULL);
256 fp_mul_d(a, b, c);
257 return CRYPT_OK;
258 }
259
260 /* sqr */
261 static int sqr(void *a, void *b)
262 {
263 LTC_ARGCHK(a != NULL);
264 LTC_ARGCHK(b != NULL);
265 fp_sqr(a, b);
266 return CRYPT_OK;
267 }
268
269 /* div */
270 static int divide(void *a, void *b, void *c, void *d)
271 {
272 LTC_ARGCHK(a != NULL);
273 LTC_ARGCHK(b != NULL);
274 return tfm_to_ltc_error(fp_div(a, b, c, d));
275 }
276
277 static int div_2(void *a, void *b)
278 {
279 LTC_ARGCHK(a != NULL);
280 LTC_ARGCHK(b != NULL);
281 fp_div_2(a, b);
282 return CRYPT_OK;
283 }
284
285 /* modi */
286 static int modi(void *a, unsigned long b, unsigned long *c)
287 {
288 fp_digit tmp;
289 int err;
290
291 LTC_ARGCHK(a != NULL);
292 LTC_ARGCHK(c != NULL);
293
294 if ((err = tfm_to_ltc_error(fp_mod_d(a, b, &tmp))) != CRYPT_OK) {
295 return err;
296 }
297 *c = tmp;
298 return CRYPT_OK;
299 }
300
301 /* gcd */
302 static int gcd(void *a, void *b, void *c)
303 {
304 LTC_ARGCHK(a != NULL);
305 LTC_ARGCHK(b != NULL);
306 LTC_ARGCHK(c != NULL);
307 fp_gcd(a, b, c);
308 return CRYPT_OK;
309 }
310
311 /* lcm */
312 static int lcm(void *a, void *b, void *c)
313 {
314 LTC_ARGCHK(a != NULL);
315 LTC_ARGCHK(b != NULL);
316 LTC_ARGCHK(c != NULL);
317 fp_lcm(a, b, c);
318 return CRYPT_OK;
319 }
320
321 static int addmod(void *a, void *b, void *c, void *d)
322 {
323 LTC_ARGCHK(a != NULL);
324 LTC_ARGCHK(b != NULL);
325 LTC_ARGCHK(c != NULL);
326 LTC_ARGCHK(d != NULL);
327 return tfm_to_ltc_error(fp_addmod(a,b,c,d));
328 }
329
330 static int submod(void *a, void *b, void *c, void *d)
331 {
332 LTC_ARGCHK(a != NULL);
333 LTC_ARGCHK(b != NULL);
334 LTC_ARGCHK(c != NULL);
335 LTC_ARGCHK(d != NULL);
336 return tfm_to_ltc_error(fp_submod(a,b,c,d));
337 }
338
339 static int mulmod(void *a, void *b, void *c, void *d)
340 {
341 LTC_ARGCHK(a != NULL);
342 LTC_ARGCHK(b != NULL);
343 LTC_ARGCHK(c != NULL);
344 LTC_ARGCHK(d != NULL);
345 return tfm_to_ltc_error(fp_mulmod(a,b,c,d));
346 }
347
348 static int sqrmod(void *a, void *b, void *c)
349 {
350 LTC_ARGCHK(a != NULL);
351 LTC_ARGCHK(b != NULL);
352 LTC_ARGCHK(c != NULL);
353 return tfm_to_ltc_error(fp_sqrmod(a,b,c));
354 }
355
356 /* invmod */
357 static int invmod(void *a, void *b, void *c)
358 {
359 LTC_ARGCHK(a != NULL);
360 LTC_ARGCHK(b != NULL);
361 LTC_ARGCHK(c != NULL);
362 return tfm_to_ltc_error(fp_invmod(a, b, c));
363 }
364
365 /* setup */
366 static int montgomery_setup(void *a, void **b)
367 {
368 int err;
369 LTC_ARGCHK(a != NULL);
370 LTC_ARGCHK(b != NULL);
371 *b = XCALLOC(1, sizeof(fp_digit));
372 if (*b == NULL) {
373 return CRYPT_MEM;
374 }
375 if ((err = tfm_to_ltc_error(fp_montgomery_setup(a, (fp_digit *)*b))) != CRYPT_OK) {
376 XFREE(*b);
377 }
378 return err;
379 }
380
381 /* get normalization value */
382 static int montgomery_normalization(void *a, void *b)
383 {
384 LTC_ARGCHK(a != NULL);
385 LTC_ARGCHK(b != NULL);
386 fp_montgomery_calc_normalization(a, b);
387 return CRYPT_OK;
388 }
389
390 /* reduce */
391 static int montgomery_reduce(void *a, void *b, void *c)
392 {
393 LTC_ARGCHK(a != NULL);
394 LTC_ARGCHK(b != NULL);
395 LTC_ARGCHK(c != NULL);
396 fp_montgomery_reduce(a, b, *((fp_digit *)c));
397 return CRYPT_OK;
398 }
399
400 /* clean up */
401 static void montgomery_deinit(void *a)
402 {
403 XFREE(a);
404 }
405
406 static int exptmod(void *a, void *b, void *c, void *d)
407 {
408 LTC_ARGCHK(a != NULL);
409 LTC_ARGCHK(b != NULL);
410 LTC_ARGCHK(c != NULL);
411 LTC_ARGCHK(d != NULL);
412 return tfm_to_ltc_error(fp_exptmod(a,b,c,d));
413 }
414
415 static int isprime(void *a, int *b)
416 {
417 LTC_ARGCHK(a != NULL);
418 LTC_ARGCHK(b != NULL);
419 *b = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO;
420 return CRYPT_OK;
421 }
422
423 #if defined(LTC_MECC) && defined(LTC_MECC_ACCEL)
424
425 static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp)
426 {
427 fp_int t1, t2;
428 fp_digit mp;
429
430 LTC_ARGCHK(P != NULL);
431 LTC_ARGCHK(R != NULL);
432 LTC_ARGCHK(modulus != NULL);
433 LTC_ARGCHK(Mp != NULL);
434
435 mp = *((fp_digit*)Mp);
436
437 fp_init(&t1);
438 fp_init(&t2);
439
440 if (P != R) {
441 fp_copy(P->x, R->x);
442 fp_copy(P->y, R->y);
443 fp_copy(P->z, R->z);
444 }
445
446 /* t1 = Z * Z */
447 fp_sqr(R->z, &t1);
448 fp_montgomery_reduce(&t1, modulus, mp);
449 /* Z = Y * Z */
450 fp_mul(R->z, R->y, R->z);
451 fp_montgomery_reduce(R->z, modulus, mp);
452 /* Z = 2Z */
453 fp_add(R->z, R->z, R->z);
454 if (fp_cmp(R->z, modulus) != FP_LT) {
455 fp_sub(R->z, modulus, R->z);
456 }
457
458 /* &t2 = X - T1 */
459 fp_sub(R->x, &t1, &t2);
460 if (fp_cmp_d(&t2, 0) == FP_LT) {
461 fp_add(&t2, modulus, &t2);
462 }
463 /* T1 = X + T1 */
464 fp_add(&t1, R->x, &t1);
465 if (fp_cmp(&t1, modulus) != FP_LT) {
466 fp_sub(&t1, modulus, &t1);
467 }
468 /* T2 = T1 * T2 */
469 fp_mul(&t1, &t2, &t2);
470 fp_montgomery_reduce(&t2, modulus, mp);
471 /* T1 = 2T2 */
472 fp_add(&t2, &t2, &t1);
473 if (fp_cmp(&t1, modulus) != FP_LT) {
474 fp_sub(&t1, modulus, &t1);
475 }
476 /* T1 = T1 + T2 */
477 fp_add(&t1, &t2, &t1);
478 if (fp_cmp(&t1, modulus) != FP_LT) {
479 fp_sub(&t1, modulus, &t1);
480 }
481
482 /* Y = 2Y */
483 fp_add(R->y, R->y, R->y);
484 if (fp_cmp(R->y, modulus) != FP_LT) {
485 fp_sub(R->y, modulus, R->y);
486 }
487 /* Y = Y * Y */
488 fp_sqr(R->y, R->y);
489 fp_montgomery_reduce(R->y, modulus, mp);
490 /* T2 = Y * Y */
491 fp_sqr(R->y, &t2);
492 fp_montgomery_reduce(&t2, modulus, mp);
493 /* T2 = T2/2 */
494 if (fp_isodd(&t2)) {
495 fp_add(&t2, modulus, &t2);
496 }
497 fp_div_2(&t2, &t2);
498 /* Y = Y * X */
499 fp_mul(R->y, R->x, R->y);
500 fp_montgomery_reduce(R->y, modulus, mp);
501
502 /* X = T1 * T1 */
503 fp_sqr(&t1, R->x);
504 fp_montgomery_reduce(R->x, modulus, mp);
505 /* X = X - Y */
506 fp_sub(R->x, R->y, R->x);
507 if (fp_cmp_d(R->x, 0) == FP_LT) {
508 fp_add(R->x, modulus, R->x);
509 }
510 /* X = X - Y */
511 fp_sub(R->x, R->y, R->x);
512 if (fp_cmp_d(R->x, 0) == FP_LT) {
513 fp_add(R->x, modulus, R->x);
514 }
515
516 /* Y = Y - X */
517 fp_sub(R->y, R->x, R->y);
518 if (fp_cmp_d(R->y, 0) == FP_LT) {
519 fp_add(R->y, modulus, R->y);
520 }
521 /* Y = Y * T1 */
522 fp_mul(R->y, &t1, R->y);
523 fp_montgomery_reduce(R->y, modulus, mp);
524 /* Y = Y - T2 */
525 fp_sub(R->y, &t2, R->y);
526 if (fp_cmp_d(R->y, 0) == FP_LT) {
527 fp_add(R->y, modulus, R->y);
528 }
529
530 return CRYPT_OK;
531 }
532
533 /**
534 Add two ECC points
535 @param P The point to add
536 @param Q The point to add
537 @param R [out] The destination of the double
538 @param modulus The modulus of the field the ECC curve is in
539 @param mp The "b" value from montgomery_setup()
540 @return CRYPT_OK on success
541 */
542 static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp)
543 {
544 fp_int t1, t2, x, y, z;
545 fp_digit mp;
546
547 LTC_ARGCHK(P != NULL);
548 LTC_ARGCHK(Q != NULL);
549 LTC_ARGCHK(R != NULL);
550 LTC_ARGCHK(modulus != NULL);
551 LTC_ARGCHK(Mp != NULL);
552
553 mp = *((fp_digit*)Mp);
554
555 fp_init(&t1);
556 fp_init(&t2);
557 fp_init(&x);
558 fp_init(&y);
559 fp_init(&z);
560
561 /* should we dbl instead? */
562 fp_sub(modulus, Q->y, &t1);
563 if ( (fp_cmp(P->x, Q->x) == FP_EQ) &&
564 (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) &&
565 (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) {
566 return tfm_ecc_projective_dbl_point(P, R, modulus, Mp);
567 }
568
569 fp_copy(P->x, &x);
570 fp_copy(P->y, &y);
571 fp_copy(P->z, &z);
572
573 /* if Z is one then these are no-operations */
574 if (Q->z != NULL) {
575 /* T1 = Z' * Z' */
576 fp_sqr(Q->z, &t1);
577 fp_montgomery_reduce(&t1, modulus, mp);
578 /* X = X * T1 */
579 fp_mul(&t1, &x, &x);
580 fp_montgomery_reduce(&x, modulus, mp);
581 /* T1 = Z' * T1 */
582 fp_mul(Q->z, &t1, &t1);
583 fp_montgomery_reduce(&t1, modulus, mp);
584 /* Y = Y * T1 */
585 fp_mul(&t1, &y, &y);
586 fp_montgomery_reduce(&y, modulus, mp);
587 }
588
589 /* T1 = Z*Z */
590 fp_sqr(&z, &t1);
591 fp_montgomery_reduce(&t1, modulus, mp);
592 /* T2 = X' * T1 */
593 fp_mul(Q->x, &t1, &t2);
594 fp_montgomery_reduce(&t2, modulus, mp);
595 /* T1 = Z * T1 */
596 fp_mul(&z, &t1, &t1);
597 fp_montgomery_reduce(&t1, modulus, mp);
598 /* T1 = Y' * T1 */
599 fp_mul(Q->y, &t1, &t1);
600 fp_montgomery_reduce(&t1, modulus, mp);
601
602 /* Y = Y - T1 */
603 fp_sub(&y, &t1, &y);
604 if (fp_cmp_d(&y, 0) == FP_LT) {
605 fp_add(&y, modulus, &y);
606 }
607 /* T1 = 2T1 */
608 fp_add(&t1, &t1, &t1);
609 if (fp_cmp(&t1, modulus) != FP_LT) {
610 fp_sub(&t1, modulus, &t1);
611 }
612 /* T1 = Y + T1 */
613 fp_add(&t1, &y, &t1);
614 if (fp_cmp(&t1, modulus) != FP_LT) {
615 fp_sub(&t1, modulus, &t1);
616 }
617 /* X = X - T2 */
618 fp_sub(&x, &t2, &x);
619 if (fp_cmp_d(&x, 0) == FP_LT) {
620 fp_add(&x, modulus, &x);
621 }
622 /* T2 = 2T2 */
623 fp_add(&t2, &t2, &t2);
624 if (fp_cmp(&t2, modulus) != FP_LT) {
625 fp_sub(&t2, modulus, &t2);
626 }
627 /* T2 = X + T2 */
628 fp_add(&t2, &x, &t2);
629 if (fp_cmp(&t2, modulus) != FP_LT) {
630 fp_sub(&t2, modulus, &t2);
631 }
632
633 /* if Z' != 1 */
634 if (Q->z != NULL) {
635 /* Z = Z * Z' */
636 fp_mul(&z, Q->z, &z);
637 fp_montgomery_reduce(&z, modulus, mp);
638 }
639
640 /* Z = Z * X */
641 fp_mul(&z, &x, &z);
642 fp_montgomery_reduce(&z, modulus, mp);
643
644 /* T1 = T1 * X */
645 fp_mul(&t1, &x, &t1);
646 fp_montgomery_reduce(&t1, modulus, mp);
647 /* X = X * X */
648 fp_sqr(&x, &x);
649 fp_montgomery_reduce(&x, modulus, mp);
650 /* T2 = T2 * x */
651 fp_mul(&t2, &x, &t2);
652 fp_montgomery_reduce(&t2, modulus, mp);
653 /* T1 = T1 * X */
654 fp_mul(&t1, &x, &t1);
655 fp_montgomery_reduce(&t1, modulus, mp);
656
657 /* X = Y*Y */
658 fp_sqr(&y, &x);
659 fp_montgomery_reduce(&x, modulus, mp);
660 /* X = X - T2 */
661 fp_sub(&x, &t2, &x);
662 if (fp_cmp_d(&x, 0) == FP_LT) {
663 fp_add(&x, modulus, &x);
664 }
665
666 /* T2 = T2 - X */
667 fp_sub(&t2, &x, &t2);
668 if (fp_cmp_d(&t2, 0) == FP_LT) {
669 fp_add(&t2, modulus, &t2);
670 }
671 /* T2 = T2 - X */
672 fp_sub(&t2, &x, &t2);
673 if (fp_cmp_d(&t2, 0) == FP_LT) {
674 fp_add(&t2, modulus, &t2);
675 }
676 /* T2 = T2 * Y */
677 fp_mul(&t2, &y, &t2);
678 fp_montgomery_reduce(&t2, modulus, mp);
679 /* Y = T2 - T1 */
680 fp_sub(&t2, &t1, &y);
681 if (fp_cmp_d(&y, 0) == FP_LT) {
682 fp_add(&y, modulus, &y);
683 }
684 /* Y = Y/2 */
685 if (fp_isodd(&y)) {
686 fp_add(&y, modulus, &y);
687 }
688 fp_div_2(&y, &y);
689
690 fp_copy(&x, R->x);
691 fp_copy(&y, R->y);
692 fp_copy(&z, R->z);
693
694 return CRYPT_OK;
695 }
696
697
698 #endif
699
700 const ltc_math_descriptor tfm_desc = {
701
702 "TomsFastMath",
703 (int)DIGIT_BIT,
704
705 &init,
706 &init_copy,
707 &deinit,
708
709 &neg,
710 &copy,
711
712 &set_int,
713 &get_int,
714 &get_digit,
715 &get_digit_count,
716 &compare,
717 &compare_d,
718 &count_bits,
719 &count_lsb_bits,
720 &twoexpt,
721
722 &read_radix,
723 &write_radix,
724 &unsigned_size,
725 &unsigned_write,
726 &unsigned_read,
727
728 &add,
729 &addi,
730 &sub,
731 &subi,
732 &mul,
733 &muli,
734 &sqr,
735 &divide,
736 &div_2,
737 &modi,
738 &gcd,
739 &lcm,
740
741 &mulmod,
742 &sqrmod,
743 &invmod,
744
745 &montgomery_setup,
746 &montgomery_normalization,
747 &montgomery_reduce,
748 &montgomery_deinit,
749
750 &exptmod,
751 &isprime,
752
753 #ifdef LTC_MECC
754 #ifdef LTC_MECC_FP
755 &ltc_ecc_fp_mulmod,
756 #else
757 &ltc_ecc_mulmod,
758 #endif /* LTC_MECC_FP */
759 #ifdef LTC_MECC_ACCEL
760 &tfm_ecc_projective_add_point,
761 &tfm_ecc_projective_dbl_point,
762 #else
763 &ltc_ecc_projective_add_point,
764 &ltc_ecc_projective_dbl_point,
765 #endif /* LTC_MECC_ACCEL */
766 &ltc_ecc_map,
767 #ifdef LTC_ECC_SHAMIR
768 #ifdef LTC_MECC_FP
769 &ltc_ecc_fp_mul2add,
770 #else
771 &ltc_ecc_mul2add,
772 #endif /* LTC_MECC_FP */
773 #else
774 NULL,
775 #endif /* LTC_ECC_SHAMIR */
776 #else
777 NULL, NULL, NULL, NULL, NULL,
778 #endif /* LTC_MECC */
779
780 #ifdef LTC_MRSA
781 &rsa_make_key,
782 &rsa_exptmod,
783 #else
784 NULL, NULL,
785 #endif
786 &addmod,
787 &submod,
788
789 NULL,
790
791 };
792
793
794 #endif
795
796 /* $Source$ */
797 /* $Revision$ */
798 /* $Date$ */
+0
-150
libtom-src/misc/base64/base64_decode.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file base64_decode.c
14 Compliant base64 code donated by Wayne Scott (wscott@bitmover.com)
15 base64 URL Safe variant (RFC 4648 section 5) by Karel Miko
16 */
17
18
19 #ifdef LTC_BASE64
20
21 static const unsigned char map_base64[256] = {
22 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
23 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
24 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
25 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
26 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
27 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
28 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
29 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
30 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
31 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
32 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
33 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
34 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
35 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
36 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
37 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
39 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255 };
44
45 static const unsigned char map_base64url[256] = {
46 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
47 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
48 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
49 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255,
50 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
51 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
52 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
53 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63,
54 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
55 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
56 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
64 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
65 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
66 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
67 255, 255, 255, 255 };
68
69 /**
70 base64 decode a block of memory
71 @param in The base64 data to decode
72 @param inlen The length of the base64 data
73 @param out [out] The destination of the binary decoded data
74 @param outlen [in/out] The max size and resulting size of the decoded data
75 @return CRYPT_OK if successful
76 */
77 int base64_decode(const unsigned char *in, unsigned long inlen,
78 unsigned char *out, unsigned long *outlen)
79 {
80 return base64_decode_internal(in, inlen, out, outlen, map_base64);
81 }
82
83 /**
84 base64 (URL Safe, RFC 4648 section 5) decode a block of memory
85 @param in The base64 data to decode
86 @param inlen The length of the base64 data
87 @param out [out] The destination of the binary decoded data
88 @param outlen [in/out] The max size and resulting size of the decoded data
89 @return CRYPT_OK if successful
90 */
91 int base64url_decode(const unsigned char *in, unsigned long inlen,
92 unsigned char *out, unsigned long *outlen)
93 {
94 return base64_decode_internal(in, inlen, out, outlen, map_base64url);
95 }
96
97 int base64_decode_internal(const unsigned char *in, unsigned long inlen,
98 unsigned char *out, unsigned long *outlen,
99 const unsigned char *map)
100 {
101 unsigned long t, x, y, z;
102 unsigned char c;
103 int g;
104
105 LTC_ARGCHK(in != NULL);
106 LTC_ARGCHK(out != NULL);
107 LTC_ARGCHK(outlen != NULL);
108
109 g = 3;
110 for (x = y = z = t = 0; x < inlen; x++) {
111 c = map[in[x]&0xFF];
112 if (c == 255) continue;
113 /* the final = symbols are read and used to trim the remaining bytes */
114 if (c == 254) {
115 c = 0;
116 /* prevent g < 0 which would potentially allow an overflow later */
117 if (--g < 0) {
118 return CRYPT_INVALID_PACKET;
119 }
120 } else if (g != 3) {
121 /* we only allow = to be at the end */
122 return CRYPT_INVALID_PACKET;
123 }
124
125 t = (t<<6)|c;
126
127 if (++y == 4) {
128 if (z + g > *outlen) {
129 return CRYPT_BUFFER_OVERFLOW;
130 }
131 out[z++] = (unsigned char)((t>>16)&255);
132 if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
133 if (g > 2) out[z++] = (unsigned char)(t&255);
134 y = t = 0;
135 }
136 }
137 if (y != 0) {
138 return CRYPT_INVALID_PACKET;
139 }
140 *outlen = z;
141 return CRYPT_OK;
142 }
143
144 #endif
145
146
147 /* $Source$ */
148 /* $Revision$ */
149 /* $Date$ */
+0
-111
libtom-src/misc/base64/base64_encode.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file base64_encode.c
14 Compliant base64 encoder donated by Wayne Scott (wscott@bitmover.com)
15 base64 URL Safe variant (RFC 4648 section 5) by Karel Miko
16 */
17
18
19 #ifdef LTC_BASE64
20
21 static const char *codes_base64 =
22 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
23
24 static const char *codes_base64url =
25 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
26
27 /**
28 base64 Encode a buffer (NUL terminated)
29 @param in The input buffer to encode
30 @param inlen The length of the input buffer
31 @param out [out] The destination of the base64 encoded data
32 @param outlen [in/out] The max size and resulting size
33 @return CRYPT_OK if successful
34 */
35 int base64_encode(const unsigned char *in, unsigned long inlen,
36 unsigned char *out, unsigned long *outlen)
37 {
38 return base64_encode_internal(in, inlen, out, outlen, codes_base64, 1);
39 }
40
41 /**
42 base64 (URL Safe, RFC 4648 section 5) Encode a buffer (NUL terminated)
43 @param in The input buffer to encode
44 @param inlen The length of the input buffer
45 @param out [out] The destination of the base64 encoded data
46 @param outlen [in/out] The max size and resulting size
47 @return CRYPT_OK if successful
48 */
49 int base64url_encode(const unsigned char *in, unsigned long inlen,
50 unsigned char *out, unsigned long *outlen)
51 {
52 return base64_encode_internal(in, inlen, out, outlen, codes_base64url, 0);
53 }
54
55 int base64_encode_internal(const unsigned char *in, unsigned long inlen,
56 unsigned char *out, unsigned long *outlen,
57 const char *codes, int pad)
58 {
59 unsigned long i, len2, leven;
60 unsigned char *p;
61
62 LTC_ARGCHK(in != NULL);
63 LTC_ARGCHK(out != NULL);
64 LTC_ARGCHK(outlen != NULL);
65
66 /* valid output size ? */
67 len2 = 4 * ((inlen + 2) / 3);
68 if (*outlen < len2 + 1) {
69 *outlen = len2 + 1;
70 return CRYPT_BUFFER_OVERFLOW;
71 }
72 p = out;
73 leven = 3*(inlen / 3);
74 for (i = 0; i < leven; i += 3) {
75 *p++ = codes[(in[0] >> 2) & 0x3F];
76 *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F];
77 *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
78 *p++ = codes[in[2] & 0x3F];
79 in += 3;
80 }
81 /* Pad it if necessary... */
82 if (i < inlen) {
83 unsigned a = in[0];
84 unsigned b = (i+1 < inlen) ? in[1] : 0;
85
86 *p++ = codes[(a >> 2) & 0x3F];
87 *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
88 if (pad) {
89 *p++ = (i+1 < inlen) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
90 *p++ = '=';
91 }
92 else {
93 if (i+1 < inlen) *p++ = codes[(((b & 0xf) << 2)) & 0x3F];
94 }
95 }
96
97 /* append a NULL byte */
98 *p = '\0';
99
100 /* return ok */
101 *outlen = p - out;
102 return CRYPT_OK;
103 }
104
105 #endif
106
107
108 /* $Source$ */
109 /* $Revision$ */
110 /* $Date$ */
+0
-34
libtom-src/misc/burn_stack.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file burn_stack.c
14 Burn stack, Tom St Denis
15 */
16
17 /**
18 Burn some stack memory
19 @param len amount of stack to burn in bytes
20 */
21 void burn_stack(unsigned long len)
22 {
23 unsigned char buf[32];
24 zeromem(buf, sizeof(buf));
25 if (len > (unsigned long)sizeof(buf))
26 burn_stack(len - sizeof(buf));
27 }
28
29
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
+0
-384
libtom-src/misc/crypt/crypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt.c
14 Build strings, Tom St Denis
15 */
16
17 const char *crypt_build_settings =
18 "LibTomCrypt " SCRYPT " (Tom St Denis, tomstdenis@gmail.com)\n"
19 "LibTomCrypt is public domain software.\n"
20 "Built on " __DATE__ " at " __TIME__ "\n\n\n"
21 "Endianess: "
22 #if defined(ENDIAN_NEUTRAL)
23 "neutral\n"
24 #elif defined(ENDIAN_LITTLE)
25 "little"
26 #if defined(ENDIAN_32BITWORD)
27 " (32-bit words)\n"
28 #else
29 " (64-bit words)\n"
30 #endif
31 #elif defined(ENDIAN_BIG)
32 "big"
33 #if defined(ENDIAN_32BITWORD)
34 " (32-bit words)\n"
35 #else
36 " (64-bit words)\n"
37 #endif
38 #endif
39 "Clean stack: "
40 #if defined(LTC_CLEAN_STACK)
41 "enabled\n"
42 #else
43 "disabled\n"
44 #endif
45 "Ciphers built-in:\n"
46 #if defined(LTC_BLOWFISH)
47 " Blowfish\n"
48 #endif
49 #if defined(LTC_RC2)
50 " LTC_RC2\n"
51 #endif
52 #if defined(LTC_RC5)
53 " LTC_RC5\n"
54 #endif
55 #if defined(LTC_RC6)
56 " LTC_RC6\n"
57 #endif
58 #if defined(LTC_SAFERP)
59 " Safer+\n"
60 #endif
61 #if defined(LTC_SAFER)
62 " Safer\n"
63 #endif
64 #if defined(LTC_RIJNDAEL)
65 " Rijndael\n"
66 #endif
67 #if defined(LTC_XTEA)
68 " LTC_XTEA\n"
69 #endif
70 #if defined(LTC_TWOFISH)
71 " Twofish "
72 #if defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES)
73 "(small, tables, all_tables)\n"
74 #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES)
75 "(small, tables)\n"
76 #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_ALL_TABLES)
77 "(small, all_tables)\n"
78 #elif defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES)
79 "(tables, all_tables)\n"
80 #elif defined(LTC_TWOFISH_SMALL)
81 "(small)\n"
82 #elif defined(LTC_TWOFISH_TABLES)
83 "(tables)\n"
84 #elif defined(LTC_TWOFISH_ALL_TABLES)
85 "(all_tables)\n"
86 #else
87 "\n"
88 #endif
89 #endif
90 #if defined(LTC_DES)
91 " LTC_DES\n"
92 #endif
93 #if defined(LTC_CAST5)
94 " LTC_CAST5\n"
95 #endif
96 #if defined(LTC_NOEKEON)
97 " Noekeon\n"
98 #endif
99 #if defined(LTC_SKIPJACK)
100 " Skipjack\n"
101 #endif
102 #if defined(LTC_KHAZAD)
103 " Khazad\n"
104 #endif
105 #if defined(LTC_ANUBIS)
106 " Anubis "
107 #endif
108 #if defined(LTC_ANUBIS_TWEAK)
109 " (tweaked)"
110 #endif
111 "\n"
112 #if defined(LTC_KSEED)
113 " LTC_KSEED\n"
114 #endif
115 #if defined(LTC_KASUMI)
116 " KASUMI\n"
117 #endif
118 #if defined(LTC_MULTI2)
119 " MULTI2\n"
120 #endif
121 #if defined(LTC_CAMELLIA)
122 " Camellia\n"
123 #endif
124
125 "\nHashes built-in:\n"
126 #if defined(LTC_SHA512)
127 " LTC_SHA-512\n"
128 #endif
129 #if defined(LTC_SHA384)
130 " LTC_SHA-384\n"
131 #endif
132 #if defined(LTC_SHA256)
133 " LTC_SHA-256\n"
134 #endif
135 #if defined(LTC_SHA224)
136 " LTC_SHA-224\n"
137 #endif
138 #if defined(LTC_TIGER)
139 " LTC_TIGER\n"
140 #endif
141 #if defined(LTC_SHA1)
142 " LTC_SHA1\n"
143 #endif
144 #if defined(LTC_MD5)
145 " LTC_MD5\n"
146 #endif
147 #if defined(LTC_MD4)
148 " LTC_MD4\n"
149 #endif
150 #if defined(LTC_MD2)
151 " LTC_MD2\n"
152 #endif
153 #if defined(LTC_RIPEMD128)
154 " LTC_RIPEMD128\n"
155 #endif
156 #if defined(LTC_RIPEMD160)
157 " LTC_RIPEMD160\n"
158 #endif
159 #if defined(LTC_RIPEMD256)
160 " LTC_RIPEMD256\n"
161 #endif
162 #if defined(LTC_RIPEMD320)
163 " LTC_RIPEMD320\n"
164 #endif
165 #if defined(LTC_WHIRLPOOL)
166 " LTC_WHIRLPOOL\n"
167 #endif
168 #if defined(LTC_CHC_HASH)
169 " LTC_CHC_HASH \n"
170 #endif
171
172 "\nBlock Chaining Modes:\n"
173 #if defined(LTC_CFB_MODE)
174 " CFB\n"
175 #endif
176 #if defined(LTC_OFB_MODE)
177 " OFB\n"
178 #endif
179 #if defined(LTC_ECB_MODE)
180 " ECB\n"
181 #endif
182 #if defined(LTC_CBC_MODE)
183 " CBC\n"
184 #endif
185 #if defined(LTC_CTR_MODE)
186 " CTR "
187 #endif
188 #if defined(LTC_CTR_OLD)
189 " (CTR_OLD) "
190 #endif
191 "\n"
192 #if defined(LRW_MODE)
193 " LRW_MODE"
194 #if defined(LRW_TABLES)
195 " (LRW_TABLES) "
196 #endif
197 "\n"
198 #endif
199 #if defined(LTC_F8_MODE)
200 " F8 MODE\n"
201 #endif
202 #if defined(LTC_XTS_MODE)
203 " LTC_XTS_MODE\n"
204 #endif
205
206 "\nMACs:\n"
207 #if defined(LTC_HMAC)
208 " LTC_HMAC\n"
209 #endif
210 #if defined(LTC_OMAC)
211 " LTC_OMAC\n"
212 #endif
213 #if defined(LTC_PMAC)
214 " PMAC\n"
215 #endif
216 #if defined(LTC_PELICAN)
217 " LTC_PELICAN\n"
218 #endif
219 #if defined(LTC_XCBC)
220 " XCBC-MAC\n"
221 #endif
222 #if defined(LTC_F9_MODE)
223 " F9-MAC\n"
224 #endif
225
226 "\nENC + AUTH modes:\n"
227 #if defined(LTC_EAX_MODE)
228 " LTC_EAX_MODE\n"
229 #endif
230 #if defined(LTC_OCB_MODE)
231 " LTC_OCB_MODE\n"
232 #endif
233 #if defined(LTC_OCB3_MODE)
234 " LTC_OCB3_MODE\n"
235 #endif
236 #if defined(LTC_CCM_MODE)
237 " LTC_CCM_MODE\n"
238 #endif
239 #if defined(LTC_GCM_MODE)
240 " LTC_GCM_MODE "
241 #endif
242 #if defined(LTC_GCM_TABLES)
243 " (LTC_GCM_TABLES) "
244 #endif
245 "\n"
246
247 "\nPRNG:\n"
248 #if defined(LTC_YARROW)
249 " Yarrow\n"
250 #endif
251 #if defined(LTC_SPRNG)
252 " LTC_SPRNG\n"
253 #endif
254 #if defined(LTC_RC4)
255 " LTC_RC4\n"
256 #endif
257 #if defined(LTC_FORTUNA)
258 " Fortuna\n"
259 #endif
260 #if defined(LTC_SOBER128)
261 " LTC_SOBER128\n"
262 #endif
263
264 "\nPK Algs:\n"
265 #if defined(LTC_MRSA)
266 " RSA \n"
267 #endif
268 #if defined(LTC_MECC)
269 " ECC\n"
270 #endif
271 #if defined(LTC_MDSA)
272 " DSA\n"
273 #endif
274 #if defined(MKAT)
275 " Katja\n"
276 #endif
277
278 "\nCompiler:\n"
279 #if defined(WIN32)
280 " WIN32 platform detected.\n"
281 #endif
282 #if defined(__CYGWIN__)
283 " CYGWIN Detected.\n"
284 #endif
285 #if defined(__DJGPP__)
286 " DJGPP Detected.\n"
287 #endif
288 #if defined(_MSC_VER)
289 " MSVC compiler detected.\n"
290 #endif
291 #if defined(__clang_version__)
292 " Clang compiler " __clang_version__ ".\n"
293 #elif defined(__GNUC__) /* clang also defines __GNUC__ */
294 " GCC compiler detected.\n"
295 #endif
296 #if defined(INTEL_CC)
297 " Intel C Compiler detected.\n"
298 #endif
299 #if defined(__x86_64__)
300 " x86-64 detected.\n"
301 #endif
302 #if defined(LTC_PPC32)
303 " LTC_PPC32 defined \n"
304 #endif
305
306 "\nVarious others: "
307 #if defined(LTC_BASE64)
308 " LTC_BASE64 "
309 #endif
310 #if defined(MPI)
311 " MPI "
312 #endif
313 #if defined(TRY_UNRANDOM_FIRST)
314 " TRY_UNRANDOM_FIRST "
315 #endif
316 #if defined(LTC_TEST)
317 " LTC_TEST "
318 #endif
319 #if defined(LTC_PKCS_1)
320 " LTC_PKCS#1 "
321 #endif
322 #if defined(LTC_PKCS_5)
323 " LTC_PKCS#5 "
324 #endif
325 #if defined(LTC_SMALL_CODE)
326 " LTC_SMALL_CODE "
327 #endif
328 #if defined(LTC_NO_FILE)
329 " LTC_NO_FILE "
330 #endif
331 #if defined(LTC_DER)
332 " LTC_DER "
333 #endif
334 #if defined(LTC_FAST)
335 " LTC_FAST "
336 #endif
337 #if defined(LTC_NO_FAST)
338 " LTC_NO_FAST "
339 #endif
340 #if defined(LTC_NO_BSWAP)
341 " LTC_NO_BSWAP "
342 #endif
343 #if defined(LTC_NO_ASM)
344 " LTC_NO_ASM "
345 #endif
346 #if defined(LTC_NO_TEST)
347 " LTC_NO_TEST "
348 #endif
349 #if defined(LTC_NO_TABLES)
350 " LTC_NO_TABLES "
351 #endif
352 #if defined(LTC_PTHREAD)
353 " LTC_PTHREAD "
354 #endif
355 #if defined(LTM_LTC_DESC)
356 " LTM_DESC "
357 #endif
358 #if defined(TFM_LTC_DESC)
359 " TFM_DESC "
360 #endif
361 #if defined(LTC_MECC_ACCEL)
362 " LTC_MECC_ACCEL "
363 #endif
364 #if defined(GMP_LTC_DESC)
365 " GMP_DESC "
366 #endif
367 #if defined(LTC_EASY)
368 " (easy) "
369 #endif
370 #if defined(LTC_MECC_FP)
371 " LTC_MECC_FP "
372 #endif
373 #if defined(LTC_ECC_SHAMIR)
374 " LTC_ECC_SHAMIR "
375 #endif
376 "\n"
377 "\n\n\n"
378 ;
379
380
381 /* $Source$ */
382 /* $Revision$ */
383 /* $Date$ */
+0
-30
libtom-src/misc/crypt/crypt_argchk.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <signal.h>
12
13 /**
14 @file crypt_argchk.c
15 Perform argument checking, Tom St Denis
16 */
17
18 #if (ARGTYPE == 0)
19 void crypt_argchk(char *v, char *s, int d)
20 {
21 fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n",
22 v, d, s);
23 (void)raise(SIGABRT);
24 }
25 #endif
26
27 /* $Source$ */
28 /* $Revision$ */
29 /* $Date$ */
+0
-27
libtom-src/misc/crypt/crypt_cipher_descriptor.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_cipher_descriptor.c
14 Stores the cipher descriptor table, Tom St Denis
15 */
16
17 struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = {
18 { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
19 };
20
21 LTC_MUTEX_GLOBAL(ltc_cipher_mutex)
22
23
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
+0
-36
libtom-src/misc/crypt/crypt_cipher_is_valid.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_cipher_is_valid.c
14 Determine if cipher is valid, Tom St Denis
15 */
16
17 /*
18 Test if a cipher index is valid
19 @param idx The index of the cipher to search for
20 @return CRYPT_OK if valid
21 */
22 int cipher_is_valid(int idx)
23 {
24 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
25 if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
26 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
27 return CRYPT_INVALID_CIPHER;
28 }
29 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
30 return CRYPT_OK;
31 }
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
+0
-41
libtom-src/misc/crypt/crypt_find_cipher.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_cipher.c
14 Find a cipher in the descriptor tables, Tom St Denis
15 */
16
17 /**
18 Find a registered cipher by name
19 @param name The name of the cipher to look for
20 @return >= 0 if found, -1 if not present
21 */
22 int find_cipher(const char *name)
23 {
24 int x;
25 LTC_ARGCHK(name != NULL);
26 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
27 for (x = 0; x < TAB_SIZE; x++) {
28 if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) {
29 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
34 return -1;
35 }
36
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
+0
-50
libtom-src/misc/crypt/crypt_find_cipher_any.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_cipher_any.c
14 Find a cipher in the descriptor tables, Tom St Denis
15 */
16
17 /**
18 Find a cipher flexibly. First by name then if not present by block and key size
19 @param name The name of the cipher desired
20 @param blocklen The minimum length of the block cipher desired (octets)
21 @param keylen The minimum length of the key size desired (octets)
22 @return >= 0 if found, -1 if not present
23 */
24 int find_cipher_any(const char *name, int blocklen, int keylen)
25 {
26 int x;
27
28 LTC_ARGCHK(name != NULL);
29
30 x = find_cipher(name);
31 if (x != -1) return x;
32
33 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
34 for (x = 0; x < TAB_SIZE; x++) {
35 if (cipher_descriptor[x].name == NULL) {
36 continue;
37 }
38 if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
39 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
40 return x;
41 }
42 }
43 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
44 return -1;
45 }
46
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
+0
-40
libtom-src/misc/crypt/crypt_find_cipher_id.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_cipher_id.c
14 Find cipher by ID, Tom St Denis
15 */
16
17 /**
18 Find a cipher by ID number
19 @param ID The ID (not same as index) of the cipher to find
20 @return >= 0 if found, -1 if not present
21 */
22 int find_cipher_id(unsigned char ID)
23 {
24 int x;
25 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
26 for (x = 0; x < TAB_SIZE; x++) {
27 if (cipher_descriptor[x].ID == ID) {
28 x = (cipher_descriptor[x].name == NULL) ? -1 : x;
29 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
34 return -1;
35 }
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
+0
-40
libtom-src/misc/crypt/crypt_find_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_hash.c
14 Find a hash, Tom St Denis
15 */
16
17 /**
18 Find a registered hash by name
19 @param name The name of the hash to look for
20 @return >= 0 if found, -1 if not present
21 */
22 int find_hash(const char *name)
23 {
24 int x;
25 LTC_ARGCHK(name != NULL);
26 LTC_MUTEX_LOCK(&ltc_hash_mutex);
27 for (x = 0; x < TAB_SIZE; x++) {
28 if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) {
29 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
34 return -1;
35 }
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
+0
-49
libtom-src/misc/crypt/crypt_find_hash_any.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_hash_any.c
14 Find a hash, Tom St Denis
15 */
16
17 /**
18 Find a hash flexibly. First by name then if not present by digest size
19 @param name The name of the hash desired
20 @param digestlen The minimum length of the digest size (octets)
21 @return >= 0 if found, -1 if not present
22 */int find_hash_any(const char *name, int digestlen)
23 {
24 int x, y, z;
25 LTC_ARGCHK(name != NULL);
26
27 x = find_hash(name);
28 if (x != -1) return x;
29
30 LTC_MUTEX_LOCK(&ltc_hash_mutex);
31 y = MAXBLOCKSIZE+1;
32 z = -1;
33 for (x = 0; x < TAB_SIZE; x++) {
34 if (hash_descriptor[x].name == NULL) {
35 continue;
36 }
37 if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) {
38 z = x;
39 y = hash_descriptor[x].hashsize;
40 }
41 }
42 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
43 return z;
44 }
45
46 /* $Source$ */
47 /* $Revision$ */
48 /* $Date$ */
+0
-40
libtom-src/misc/crypt/crypt_find_hash_id.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_hash_id.c
14 Find hash by ID, Tom St Denis
15 */
16
17 /**
18 Find a hash by ID number
19 @param ID The ID (not same as index) of the hash to find
20 @return >= 0 if found, -1 if not present
21 */
22 int find_hash_id(unsigned char ID)
23 {
24 int x;
25 LTC_MUTEX_LOCK(&ltc_hash_mutex);
26 for (x = 0; x < TAB_SIZE; x++) {
27 if (hash_descriptor[x].ID == ID) {
28 x = (hash_descriptor[x].name == NULL) ? -1 : x;
29 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
34 return -1;
35 }
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
+0
-35
libtom-src/misc/crypt/crypt_find_hash_oid.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_hash_oid.c
14 Find a hash, Tom St Denis
15 */
16
17 int find_hash_oid(const unsigned long *ID, unsigned long IDlen)
18 {
19 int x;
20 LTC_ARGCHK(ID != NULL);
21 LTC_MUTEX_LOCK(&ltc_hash_mutex);
22 for (x = 0; x < TAB_SIZE; x++) {
23 if (hash_descriptor[x].name != NULL && hash_descriptor[x].OIDlen == IDlen && !XMEMCMP(hash_descriptor[x].OID, ID, sizeof(unsigned long) * IDlen)) {
24 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
25 return x;
26 }
27 }
28 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
29 return -1;
30 }
31
32 /* $Source$ */
33 /* $Revision$ */
34 /* $Date$ */
+0
-41
libtom-src/misc/crypt/crypt_find_prng.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_prng.c
14 Find a PRNG, Tom St Denis
15 */
16
17 /**
18 Find a registered PRNG by name
19 @param name The name of the PRNG to look for
20 @return >= 0 if found, -1 if not present
21 */
22 int find_prng(const char *name)
23 {
24 int x;
25 LTC_ARGCHK(name != NULL);
26 LTC_MUTEX_LOCK(&ltc_prng_mutex);
27 for (x = 0; x < TAB_SIZE; x++) {
28 if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) {
29 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
34 return -1;
35 }
36
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
+0
-58
libtom-src/misc/crypt/crypt_fsa.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file crypt_fsa.c
15 LibTomCrypt FULL SPEED AHEAD!, Tom St Denis
16 */
17
18 /* format is ltc_mp, cipher_desc, [cipher_desc], NULL, hash_desc, [hash_desc], NULL, prng_desc, [prng_desc], NULL */
19 int crypt_fsa(void *mp, ...)
20 {
21 va_list args;
22 void *p;
23
24 va_start(args, mp);
25 if (mp != NULL) {
26 XMEMCPY(&ltc_mp, mp, sizeof(ltc_mp));
27 }
28
29 while ((p = va_arg(args, void*)) != NULL) {
30 if (register_cipher(p) == -1) {
31 va_end(args);
32 return CRYPT_INVALID_CIPHER;
33 }
34 }
35
36 while ((p = va_arg(args, void*)) != NULL) {
37 if (register_hash(p) == -1) {
38 va_end(args);
39 return CRYPT_INVALID_HASH;
40 }
41 }
42
43 while ((p = va_arg(args, void*)) != NULL) {
44 if (register_prng(p) == -1) {
45 va_end(args);
46 return CRYPT_INVALID_PRNG;
47 }
48 }
49
50 va_end(args);
51 return CRYPT_OK;
52 }
53
54
55 /* $Source$ */
56 /* $Revision$ */
57 /* $Date$ */
+0
-27
libtom-src/misc/crypt/crypt_hash_descriptor.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_hash_descriptor.c
14 Stores the hash descriptor table, Tom St Denis
15 */
16
17 struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = {
18 { NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL }
19 };
20
21 LTC_MUTEX_GLOBAL(ltc_hash_mutex)
22
23
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
+0
-36
libtom-src/misc/crypt/crypt_hash_is_valid.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_hash_is_valid.c
14 Determine if hash is valid, Tom St Denis
15 */
16
17 /*
18 Test if a hash index is valid
19 @param idx The index of the hash to search for
20 @return CRYPT_OK if valid
21 */
22 int hash_is_valid(int idx)
23 {
24 LTC_MUTEX_LOCK(&ltc_hash_mutex);
25 if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
26 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
27 return CRYPT_INVALID_HASH;
28 }
29 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
30 return CRYPT_OK;
31 }
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
+0
-13
libtom-src/misc/crypt/crypt_ltc_mp_descriptor.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 ltc_math_descriptor ltc_mp;
+0
-26
libtom-src/misc/crypt/crypt_prng_descriptor.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_prng_descriptor.c
14 Stores the PRNG descriptors, Tom St Denis
15 */
16 struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = {
17 { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
18 };
19
20 LTC_MUTEX_GLOBAL(ltc_prng_mutex)
21
22
23 /* $Source$ */
24 /* $Revision$ */
25 /* $Date$ */
+0
-36
libtom-src/misc/crypt/crypt_prng_is_valid.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_prng_is_valid.c
14 Determine if PRNG is valid, Tom St Denis
15 */
16
17 /*
18 Test if a PRNG index is valid
19 @param idx The index of the PRNG to search for
20 @return CRYPT_OK if valid
21 */
22 int prng_is_valid(int idx)
23 {
24 LTC_MUTEX_LOCK(&ltc_prng_mutex);
25 if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
26 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
27 return CRYPT_INVALID_PRNG;
28 }
29 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
30 return CRYPT_OK;
31 }
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
+0
-54
libtom-src/misc/crypt/crypt_register_cipher.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_register_cipher.c
14 Register a cipher, Tom St Denis
15 */
16
17 /**
18 Register a cipher with the descriptor table
19 @param cipher The cipher you wish to register
20 @return value >= 0 if successfully added (or already present), -1 if unsuccessful
21 */
22 int register_cipher(const struct ltc_cipher_descriptor *cipher)
23 {
24 int x;
25
26 LTC_ARGCHK(cipher != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
32 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
33 return x;
34 }
35 }
36
37 /* find a blank spot */
38 for (x = 0; x < TAB_SIZE; x++) {
39 if (cipher_descriptor[x].name == NULL) {
40 XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor));
41 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
42 return x;
43 }
44 }
45
46 /* no spot */
47 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
48 return -1;
49 }
50
51 /* $Source$ */
52 /* $Revision$ */
53 /* $Date$ */
+0
-54
libtom-src/misc/crypt/crypt_register_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_register_hash.c
14 Register a HASH, Tom St Denis
15 */
16
17 /**
18 Register a hash with the descriptor table
19 @param hash The hash you wish to register
20 @return value >= 0 if successfully added (or already present), -1 if unsuccessful
21 */
22 int register_hash(const struct ltc_hash_descriptor *hash)
23 {
24 int x;
25
26 LTC_ARGCHK(hash != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_hash_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
32 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
33 return x;
34 }
35 }
36
37 /* find a blank spot */
38 for (x = 0; x < TAB_SIZE; x++) {
39 if (hash_descriptor[x].name == NULL) {
40 XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor));
41 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
42 return x;
43 }
44 }
45
46 /* no spot */
47 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
48 return -1;
49 }
50
51 /* $Source$ */
52 /* $Revision$ */
53 /* $Date$ */
+0
-54
libtom-src/misc/crypt/crypt_register_prng.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_register_prng.c
14 Register a PRNG, Tom St Denis
15 */
16
17 /**
18 Register a PRNG with the descriptor table
19 @param prng The PRNG you wish to register
20 @return value >= 0 if successfully added (or already present), -1 if unsuccessful
21 */
22 int register_prng(const struct ltc_prng_descriptor *prng)
23 {
24 int x;
25
26 LTC_ARGCHK(prng != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_prng_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
32 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
33 return x;
34 }
35 }
36
37 /* find a blank spot */
38 for (x = 0; x < TAB_SIZE; x++) {
39 if (prng_descriptor[x].name == NULL) {
40 XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor));
41 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
42 return x;
43 }
44 }
45
46 /* no spot */
47 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
48 return -1;
49 }
50
51 /* $Source$ */
52 /* $Revision$ */
53 /* $Date$ */
+0
-45
libtom-src/misc/crypt/crypt_unregister_cipher.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_unregister_cipher.c
14 Unregister a cipher, Tom St Denis
15 */
16
17 /**
18 Unregister a cipher from the descriptor table
19 @param cipher The cipher descriptor to remove
20 @return CRYPT_OK on success
21 */
22 int unregister_cipher(const struct ltc_cipher_descriptor *cipher)
23 {
24 int x;
25
26 LTC_ARGCHK(cipher != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) {
32 cipher_descriptor[x].name = NULL;
33 cipher_descriptor[x].ID = 255;
34 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
35 return CRYPT_OK;
36 }
37 }
38 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
39 return CRYPT_ERROR;
40 }
41
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
+0
-44
libtom-src/misc/crypt/crypt_unregister_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_unregister_hash.c
14 Unregister a hash, Tom St Denis
15 */
16
17 /**
18 Unregister a hash from the descriptor table
19 @param hash The hash descriptor to remove
20 @return CRYPT_OK on success
21 */
22 int unregister_hash(const struct ltc_hash_descriptor *hash)
23 {
24 int x;
25
26 LTC_ARGCHK(hash != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_hash_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
32 hash_descriptor[x].name = NULL;
33 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
34 return CRYPT_OK;
35 }
36 }
37 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
38 return CRYPT_ERROR;
39 }
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-44
libtom-src/misc/crypt/crypt_unregister_prng.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_unregister_prng.c
14 Unregister a PRNG, Tom St Denis
15 */
16
17 /**
18 Unregister a PRNG from the descriptor table
19 @param prng The PRNG descriptor to remove
20 @return CRYPT_OK on success
21 */
22 int unregister_prng(const struct ltc_prng_descriptor *prng)
23 {
24 int x;
25
26 LTC_ARGCHK(prng != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_prng_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) != 0) {
32 prng_descriptor[x].name = NULL;
33 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
34 return CRYPT_OK;
35 }
36 }
37 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
38 return CRYPT_ERROR;
39 }
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-74
libtom-src/misc/error_to_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #include "tomcrypt.h"
12
13 /**
14 @file error_to_string.c
15 Convert error codes to ASCII strings, Tom St Denis
16 */
17
18 static const char *err_2_str[] =
19 {
20 "CRYPT_OK",
21 "CRYPT_ERROR",
22 "Non-fatal 'no-operation' requested.",
23
24 "Invalid keysize for block cipher.",
25 "Invalid number of rounds for block cipher.",
26 "Algorithm failed test vectors.",
27
28 "Buffer overflow.",
29 "Invalid input packet.",
30
31 "Invalid number of bits for a PRNG.",
32 "Error reading the PRNG.",
33
34 "Invalid cipher specified.",
35 "Invalid hash specified.",
36 "Invalid PRNG specified.",
37
38 "Out of memory.",
39
40 "Invalid PK key or key type specified for function.",
41 "A private PK key is required.",
42
43 "Invalid argument provided.",
44 "File Not Found",
45
46 "Invalid PK type.",
47 "Invalid PK system.",
48 "Duplicate PK key found on keyring.",
49 "Key not found in keyring.",
50 "Invalid sized parameter.",
51
52 "Invalid size for prime.",
53
54 };
55
56 /**
57 Convert an LTC error code to ASCII
58 @param err The error code
59 @return A pointer to the ASCII NUL terminated string for the error or "Invalid error code." if the err code was not valid.
60 */
61 const char *error_to_string(int err)
62 {
63 if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
64 return "Invalid error code.";
65 } else {
66 return err_2_str[err];
67 }
68 }
69
70
71 /* $Source$ */
72 /* $Revision$ */
73 /* $Date$ */
+0
-141
libtom-src/misc/hkdf/hkdf.c less more
0 #include <assert.h>
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <tomcrypt.h>
5
6 #ifndef MIN
7 #define MIN(a,b) ((a)<(b))?(a):(b)
8 #endif
9
10 /* This is mostly just a wrapper around hmac_memory */
11 int hkdf_extract(int hash_idx, const unsigned char *salt, unsigned long saltlen,
12 const unsigned char *in, unsigned long inlen,
13 unsigned char *out, unsigned long *outlen)
14 {
15 /* libtomcrypt chokes on a zero length HMAC key, so we need to check for
16 that. HMAC specifies that keys shorter than the hash's blocksize are
17 0 padded to the block size. HKDF specifies that a NULL salt is to be
18 substituted with a salt comprised of hashLen 0 bytes. HMAC's padding
19 means that in either case the HMAC is actually using a blocksize long
20 zero filled key. Unless blocksize < hashLen (which wouldn't make any
21 sense), we can use a single 0 byte as the HMAC key and still generate
22 valid results for HKDF. */
23 if (salt == NULL || saltlen == 0) {
24 return hmac_memory(hash_idx, (const unsigned char *)"", 1, in, inlen, out, outlen);
25 } else {
26 return hmac_memory(hash_idx, salt, saltlen, in, inlen, out, outlen);
27 }
28 }
29
30 int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen,
31 const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long outlen)
33 {
34 unsigned long hashsize;
35 int err;
36 unsigned char N;
37 unsigned long Noutlen, outoff;
38
39 unsigned char *T, *dat;
40 unsigned long Tlen, datlen;
41
42 /* make sure hash descriptor is valid */
43 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
44 return err;
45 }
46
47 hashsize = hash_descriptor[hash_idx].hashsize;
48
49 /* RFC5869 parameter restrictions */
50 if (inlen < hashsize || outlen > hashsize * 255)
51 return CRYPT_INVALID_ARG;
52 if (info == NULL && infolen != 0)
53 return CRYPT_INVALID_ARG;
54 LTC_ARGCHK(out != NULL);
55
56 Tlen = hashsize + infolen + 1;
57 T = XMALLOC(Tlen); /* Replace with static buffer? */
58 if (T == NULL) {
59 return CRYPT_MEM;
60 }
61 XMEMCPY(T + hashsize, info, infolen);
62
63 /* HMAC data T(1) doesn't include a previous hash value */
64 dat = T + hashsize;
65 datlen = Tlen - hashsize;
66
67 N = 0;
68 outoff = 0; /* offset in out to write to */
69 while (1) { /* an exit condition breaks mid-loop */
70 Noutlen = MIN(hashsize, outlen - outoff);
71 T[Tlen - 1] = ++N;
72 if ((err = hmac_memory(hash_idx, in, inlen, dat, datlen,
73 out + outoff, &Noutlen)) != CRYPT_OK) {
74 zeromem(T, Tlen);
75 XFREE(T);
76 return err;
77 }
78 outoff += Noutlen;
79
80 if (outoff >= outlen) /* loop exit condition */
81 break;
82
83 /* All subsequent HMAC data T(N) DOES include the previous hash value */
84 XMEMCPY(T, out + hashsize * (N-1), hashsize);
85 if (N == 1) {
86 dat = T;
87 datlen = Tlen;
88 }
89 }
90 zeromem(T, Tlen);
91 XFREE(T);
92 return CRYPT_OK;
93 }
94
95 /* all in one step */
96 int hkdf(int hash_idx, const unsigned char *salt, unsigned long saltlen,
97 const unsigned char *info, unsigned long infolen,
98 const unsigned char *in, unsigned long inlen,
99 unsigned char *out, unsigned long outlen)
100 {
101 unsigned long hashsize;
102 int err;
103 unsigned char *extracted;
104
105 /* make sure hash descriptor is valid */
106 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
107 return err;
108 }
109
110 hashsize = hash_descriptor[hash_idx].hashsize;
111
112 extracted = XMALLOC(hashsize); /* replace with static buffer? */
113 if (extracted == NULL) {
114 return CRYPT_MEM;
115 }
116 if ((err = hkdf_extract(hash_idx, salt, saltlen, in, inlen, extracted, &hashsize)) != 0) {
117 zeromem(extracted, hashsize);
118 XFREE(extracted);
119 return err;
120 }
121 #if 0
122 {
123 int j;
124 printf("\nPRK: 0x");
125 for(j=0; j < hashsize; j++) {
126 printf("%02x ", extracted[j]);
127 }
128 for(j=0; j < hashsize; j++) {
129 printf("%02x ", extracted[j]);
130 }
131 }
132 #endif
133 err = hkdf_expand(hash_idx, info, infolen, extracted, hashsize, out, outlen);
134 zeromem(extracted, hashsize);
135 XFREE(extracted);
136 return err;
137 }
138
139
140 /* vim: set ts=2 sw=2 et ai si: */
+0
-39
libtom-src/misc/pk_get_oid.c less more
0 /* LibTomCrypt, modular cryptographic library
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9 #include "tomcrypt.h"
10
11 static const oid_st rsa_oid = {
12 { 1, 2, 840, 113549, 1, 1, 1 },
13 7,
14 };
15
16 static const oid_st dsa_oid = {
17 { 1, 2, 840, 10040, 4, 1 },
18 6,
19 };
20
21 /*
22 Returns the OID of the public key algorithm.
23 @return CRYPT_OK if valid
24 */
25 int pk_get_oid(int pk, oid_st *st)
26 {
27 switch (pk) {
28 case PKA_RSA:
29 memcpy(st, &rsa_oid, sizeof(*st));
30 break;
31 case PKA_DSA:
32 memcpy(st, &dsa_oid, sizeof(*st));
33 break;
34 default:
35 return CRYPT_INVALID_ARG;
36 }
37 return CRYPT_OK;
38 }
+0
-106
libtom-src/misc/pkcs5/pkcs_5_1.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include <tomcrypt.h>
11
12 /**
13 @file pkcs_5_1.c
14 LTC_PKCS #5, Algorithm #1, Tom St Denis
15 */
16 #ifdef LTC_PKCS_5
17 /**
18 Execute LTC_PKCS #5 v1
19 @param password The password (or key)
20 @param password_len The length of the password (octet)
21 @param salt The salt (or nonce) which is 8 octets long
22 @param iteration_count The LTC_PKCS #5 v1 iteration count
23 @param hash_idx The index of the hash desired
24 @param out [out] The destination for this algorithm
25 @param outlen [in/out] The max size and resulting size of the algorithm output
26 @return CRYPT_OK if successful
27 */
28 int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
29 const unsigned char *salt,
30 int iteration_count, int hash_idx,
31 unsigned char *out, unsigned long *outlen)
32 {
33 int err;
34 unsigned long x;
35 hash_state *md;
36 unsigned char *buf;
37
38 LTC_ARGCHK(password != NULL);
39 LTC_ARGCHK(salt != NULL);
40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL);
42
43 /* test hash IDX */
44 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* allocate memory */
49 md = XMALLOC(sizeof(hash_state));
50 buf = XMALLOC(MAXBLOCKSIZE);
51 if (md == NULL || buf == NULL) {
52 if (md != NULL) {
53 XFREE(md);
54 }
55 if (buf != NULL) {
56 XFREE(buf);
57 }
58 return CRYPT_MEM;
59 }
60
61 /* hash initial password + salt */
62 if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
63 goto LBL_ERR;
64 }
65 if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) {
66 goto LBL_ERR;
67 }
68 if ((err = hash_descriptor[hash_idx].process(md, salt, 8)) != CRYPT_OK) {
69 goto LBL_ERR;
70 }
71 if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
72 goto LBL_ERR;
73 }
74
75 while (--iteration_count) {
76 /* code goes here. */
77 x = MAXBLOCKSIZE;
78 if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) {
79 goto LBL_ERR;
80 }
81 }
82
83 /* copy upto outlen bytes */
84 for (x = 0; x < hash_descriptor[hash_idx].hashsize && x < *outlen; x++) {
85 out[x] = buf[x];
86 }
87 *outlen = x;
88 err = CRYPT_OK;
89 LBL_ERR:
90 #ifdef LTC_CLEAN_STACK
91 zeromem(buf, MAXBLOCKSIZE);
92 zeromem(md, sizeof(hash_state));
93 #endif
94
95 XFREE(buf);
96 XFREE(md);
97
98 return err;
99 }
100
101 #endif
102
103 /* $Source$ */
104 /* $Revision$ */
105 /* $Date$ */
+0
-129
libtom-src/misc/pkcs5/pkcs_5_2.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include <tomcrypt.h>
11
12 /**
13 @file pkcs_5_2.c
14 LTC_PKCS #5, Algorithm #2, Tom St Denis
15 */
16 #ifdef LTC_PKCS_5
17
18 /**
19 Execute LTC_PKCS #5 v2
20 @param password The input password (or key)
21 @param password_len The length of the password (octets)
22 @param salt The salt (or nonce)
23 @param salt_len The length of the salt (octets)
24 @param iteration_count # of iterations desired for LTC_PKCS #5 v2 [read specs for more]
25 @param hash_idx The index of the hash desired
26 @param out [out] The destination for this algorithm
27 @param outlen [in/out] The max size and resulting size of the algorithm output
28 @return CRYPT_OK if successful
29 */
30 int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
31 const unsigned char *salt, unsigned long salt_len,
32 int iteration_count, int hash_idx,
33 unsigned char *out, unsigned long *outlen)
34 {
35 int err, itts;
36 ulong32 blkno;
37 unsigned long stored, left, x, y;
38 unsigned char *buf[2];
39 hmac_state *hmac;
40
41 LTC_ARGCHK(password != NULL);
42 LTC_ARGCHK(salt != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45
46 /* test hash IDX */
47 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
48 return err;
49 }
50
51 buf[0] = XMALLOC(MAXBLOCKSIZE * 2);
52 hmac = XMALLOC(sizeof(hmac_state));
53 if (hmac == NULL || buf[0] == NULL) {
54 if (hmac != NULL) {
55 XFREE(hmac);
56 }
57 if (buf[0] != NULL) {
58 XFREE(buf[0]);
59 }
60 return CRYPT_MEM;
61 }
62 /* buf[1] points to the second block of MAXBLOCKSIZE bytes */
63 buf[1] = buf[0] + MAXBLOCKSIZE;
64
65 left = *outlen;
66 blkno = 1;
67 stored = 0;
68 while (left != 0) {
69 /* process block number blkno */
70 zeromem(buf[0], MAXBLOCKSIZE*2);
71
72 /* store current block number and increment for next pass */
73 STORE32H(blkno, buf[1]);
74 ++blkno;
75
76 /* get PRF(P, S||int(blkno)) */
77 if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80 if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {
81 goto LBL_ERR;
82 }
83 if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {
84 goto LBL_ERR;
85 }
86 x = MAXBLOCKSIZE;
87 if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {
88 goto LBL_ERR;
89 }
90
91 /* now compute repeated and XOR it in buf[1] */
92 XMEMCPY(buf[1], buf[0], x);
93 for (itts = 1; itts < iteration_count; ++itts) {
94 if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {
95 goto LBL_ERR;
96 }
97 for (y = 0; y < x; y++) {
98 buf[1][y] ^= buf[0][y];
99 }
100 }
101
102 /* now emit upto x bytes of buf[1] to output */
103 for (y = 0; y < x && left != 0; ++y) {
104 out[stored++] = buf[1][y];
105 --left;
106 }
107 }
108 *outlen = stored;
109
110 err = CRYPT_OK;
111 LBL_ERR:
112 #ifdef LTC_CLEAN_STACK
113 zeromem(buf[0], MAXBLOCKSIZE*2);
114 zeromem(hmac, sizeof(hmac_state));
115 #endif
116
117 XFREE(hmac);
118 XFREE(buf[0]);
119
120 return err;
121 }
122
123 #endif
124
125
126 /* $Source$ */
127 /* $Revision$ */
128 /* $Date$ */
+0
-34
libtom-src/misc/zeromem.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file zeromem.c
14 Zero a block of memory, Tom St Denis
15 */
16
17 /**
18 Zero a block of memory
19 @param out The destination of the area to zero
20 @param outlen The length of the area to zero (octets)
21 */
22 void zeromem(volatile void *out, size_t outlen)
23 {
24 volatile char *mem = out;
25 LTC_ARGCHKVD(out != NULL);
26 while (outlen-- > 0) {
27 *mem++ = '\0';
28 }
29 }
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
+0
-97
libtom-src/modes/cbc/cbc_decrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_decrypt.c
14 CBC implementation, encrypt block, Tom St Denis
15 */
16
17
18 #ifdef LTC_CBC_MODE
19
20 /**
21 CBC decrypt
22 @param ct Ciphertext
23 @param pt [out] Plaintext
24 @param len The number of bytes to process (must be multiple of block length)
25 @param cbc CBC state
26 @return CRYPT_OK if successful
27 */
28 int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc)
29 {
30 int x, err;
31 unsigned char tmp[16];
32 #ifdef LTC_FAST
33 LTC_FAST_TYPE tmpy;
34 #else
35 unsigned char tmpy;
36 #endif
37
38 LTC_ARGCHK(pt != NULL);
39 LTC_ARGCHK(ct != NULL);
40 LTC_ARGCHK(cbc != NULL);
41
42 if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
43 return err;
44 }
45
46 /* is blocklen valid? */
47 if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
48 return CRYPT_INVALID_ARG;
49 }
50
51 if (len % cbc->blocklen) {
52 return CRYPT_INVALID_ARG;
53 }
54 #ifdef LTC_FAST
55 if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
56 return CRYPT_INVALID_ARG;
57 }
58 #endif
59
60 if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
61 return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
62 } else {
63 while (len) {
64 /* decrypt */
65 if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
66 return err;
67 }
68
69 /* xor IV against plaintext */
70 #if defined(LTC_FAST)
71 for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
72 tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x));
73 *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
74 *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy;
75 }
76 #else
77 for (x = 0; x < cbc->blocklen; x++) {
78 tmpy = tmp[x] ^ cbc->IV[x];
79 cbc->IV[x] = ct[x];
80 pt[x] = tmpy;
81 }
82 #endif
83
84 ct += cbc->blocklen;
85 pt += cbc->blocklen;
86 len -= cbc->blocklen;
87 }
88 }
89 return CRYPT_OK;
90 }
91
92 #endif
93
94 /* $Source$ */
95 /* $Revision$ */
96 /* $Date$ */
+0
-42
libtom-src/modes/cbc/cbc_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_done.c
14 CBC implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_CBC_MODE
18
19 /** Terminate the chain
20 @param cbc The CBC chain to terminate
21 @return CRYPT_OK on success
22 */
23 int cbc_done(symmetric_CBC *cbc)
24 {
25 int err;
26 LTC_ARGCHK(cbc != NULL);
27
28 if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[cbc->cipher].done(&cbc->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
+0
-98
libtom-src/modes/cbc/cbc_encrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_encrypt.c
14 CBC implementation, encrypt block, Tom St Denis
15 */
16
17
18 #ifdef LTC_CBC_MODE
19
20 /**
21 CBC encrypt
22 @param pt Plaintext
23 @param ct [out] Ciphertext
24 @param len The number of bytes to process (must be multiple of block length)
25 @param cbc CBC state
26 @return CRYPT_OK if successful
27 */
28 int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc)
29 {
30 int x, err;
31
32 LTC_ARGCHK(pt != NULL);
33 LTC_ARGCHK(ct != NULL);
34 LTC_ARGCHK(cbc != NULL);
35
36 if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 /* is blocklen valid? */
41 if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 if (len % cbc->blocklen) {
46 return CRYPT_INVALID_ARG;
47 }
48 #ifdef LTC_FAST
49 if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
50 return CRYPT_INVALID_ARG;
51 }
52 #endif
53
54 if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
55 return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
56 } else {
57 while (len) {
58 /* xor IV against plaintext */
59 #if defined(LTC_FAST)
60 for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
61 *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x));
62 }
63 #else
64 for (x = 0; x < cbc->blocklen; x++) {
65 cbc->IV[x] ^= pt[x];
66 }
67 #endif
68
69 /* encrypt */
70 if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
71 return err;
72 }
73
74 /* store IV [ciphertext] for a future block */
75 #if defined(LTC_FAST)
76 for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
77 *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
78 }
79 #else
80 for (x = 0; x < cbc->blocklen; x++) {
81 cbc->IV[x] = ct[x];
82 }
83 #endif
84
85 ct += cbc->blocklen;
86 pt += cbc->blocklen;
87 len -= cbc->blocklen;
88 }
89 }
90 return CRYPT_OK;
91 }
92
93 #endif
94
95 /* $Source$ */
96 /* $Revision$ */
97 /* $Date$ */
+0
-46
libtom-src/modes/cbc/cbc_getiv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_getiv.c
14 CBC implementation, get IV, Tom St Denis
15 */
16
17 #ifdef LTC_CBC_MODE
18
19 /**
20 Get the current initial vector
21 @param IV [out] The destination of the initial vector
22 @param len [in/out] The max size and resulting size of the initial vector
23 @param cbc The CBC state
24 @return CRYPT_OK if successful
25 */
26 int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc)
27 {
28 LTC_ARGCHK(IV != NULL);
29 LTC_ARGCHK(len != NULL);
30 LTC_ARGCHK(cbc != NULL);
31 if ((unsigned long)cbc->blocklen > *len) {
32 *len = cbc->blocklen;
33 return CRYPT_BUFFER_OVERFLOW;
34 }
35 XMEMCPY(IV, cbc->IV, cbc->blocklen);
36 *len = cbc->blocklen;
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
+0
-44
libtom-src/modes/cbc/cbc_setiv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_setiv.c
14 CBC implementation, set IV, Tom St Denis
15 */
16
17
18 #ifdef LTC_CBC_MODE
19
20 /**
21 Set an initial vector
22 @param IV The initial vector
23 @param len The length of the vector (in octets)
24 @param cbc The CBC state
25 @return CRYPT_OK if successful
26 */
27 int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc)
28 {
29 LTC_ARGCHK(IV != NULL);
30 LTC_ARGCHK(cbc != NULL);
31 if (len != (unsigned long)cbc->blocklen) {
32 return CRYPT_INVALID_ARG;
33 }
34 XMEMCPY(cbc->IV, IV, len);
35 return CRYPT_OK;
36 }
37
38 #endif
39
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
+0
-62
libtom-src/modes/cbc/cbc_start.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_start.c
14 CBC implementation, start chain, Tom St Denis
15 */
16
17 #ifdef LTC_CBC_MODE
18
19 /**
20 Initialize a CBC context
21 @param cipher The index of the cipher desired
22 @param IV The initial vector
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param num_rounds Number of rounds in the cipher desired (0 for default)
26 @param cbc The CBC state to initialize
27 @return CRYPT_OK if successful
28 */
29 int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
30 int keylen, int num_rounds, symmetric_CBC *cbc)
31 {
32 int x, err;
33
34 LTC_ARGCHK(IV != NULL);
35 LTC_ARGCHK(key != NULL);
36 LTC_ARGCHK(cbc != NULL);
37
38 /* bad param? */
39 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* setup cipher */
44 if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* copy IV */
49 cbc->blocklen = cipher_descriptor[cipher].block_length;
50 cbc->cipher = cipher;
51 for (x = 0; x < cbc->blocklen; x++) {
52 cbc->IV[x] = IV[x];
53 }
54 return CRYPT_OK;
55 }
56
57 #endif
58
59 /* $Source$ */
60 /* $Revision$ */
61 /* $Date$ */
+0
-67
libtom-src/modes/cfb/cfb_decrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_decrypt.c
14 CFB implementation, decrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /**
20 CFB decrypt
21 @param ct Ciphertext
22 @param pt [out] Plaintext
23 @param len Length of ciphertext (octets)
24 @param cfb CFB state
25 @return CRYPT_OK if successful
26 */
27 int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb)
28 {
29 int err;
30
31 LTC_ARGCHK(pt != NULL);
32 LTC_ARGCHK(ct != NULL);
33 LTC_ARGCHK(cfb != NULL);
34
35 if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
36 return err;
37 }
38
39 /* is blocklen/padlen valid? */
40 if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) ||
41 cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 while (len-- > 0) {
46 if (cfb->padlen == cfb->blocklen) {
47 if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
48 return err;
49 }
50 cfb->padlen = 0;
51 }
52 cfb->pad[cfb->padlen] = *ct;
53 *pt = *ct ^ cfb->IV[cfb->padlen];
54 ++pt;
55 ++ct;
56 ++(cfb->padlen);
57 }
58 return CRYPT_OK;
59 }
60
61 #endif
62
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
+0
-42
libtom-src/modes/cfb/cfb_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_done.c
14 CFB implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /** Terminate the chain
20 @param cfb The CFB chain to terminate
21 @return CRYPT_OK on success
22 */
23 int cfb_done(symmetric_CFB *cfb)
24 {
25 int err;
26 LTC_ARGCHK(cfb != NULL);
27
28 if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[cfb->cipher].done(&cfb->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
+0
-65
libtom-src/modes/cfb/cfb_encrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_encrypt.c
14 CFB implementation, encrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /**
20 CFB encrypt
21 @param pt Plaintext
22 @param ct [out] Ciphertext
23 @param len Length of plaintext (octets)
24 @param cfb CFB state
25 @return CRYPT_OK if successful
26 */
27 int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb)
28 {
29 int err;
30
31 LTC_ARGCHK(pt != NULL);
32 LTC_ARGCHK(ct != NULL);
33 LTC_ARGCHK(cfb != NULL);
34
35 if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
36 return err;
37 }
38
39 /* is blocklen/padlen valid? */
40 if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) ||
41 cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 while (len-- > 0) {
46 if (cfb->padlen == cfb->blocklen) {
47 if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
48 return err;
49 }
50 cfb->padlen = 0;
51 }
52 cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
53 ++pt;
54 ++ct;
55 ++(cfb->padlen);
56 }
57 return CRYPT_OK;
58 }
59
60 #endif
61
62 /* $Source$ */
63 /* $Revision$ */
64 /* $Date$ */
+0
-46
libtom-src/modes/cfb/cfb_getiv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_getiv.c
14 CFB implementation, get IV, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /**
20 Get the current initial vector
21 @param IV [out] The destination of the initial vector
22 @param len [in/out] The max size and resulting size of the initial vector
23 @param cfb The CFB state
24 @return CRYPT_OK if successful
25 */
26 int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb)
27 {
28 LTC_ARGCHK(IV != NULL);
29 LTC_ARGCHK(len != NULL);
30 LTC_ARGCHK(cfb != NULL);
31 if ((unsigned long)cfb->blocklen > *len) {
32 *len = cfb->blocklen;
33 return CRYPT_BUFFER_OVERFLOW;
34 }
35 XMEMCPY(IV, cfb->IV, cfb->blocklen);
36 *len = cfb->blocklen;
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
+0
-52
libtom-src/modes/cfb/cfb_setiv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_setiv.c
14 CFB implementation, set IV, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /**
20 Set an initial vector
21 @param IV The initial vector
22 @param len The length of the vector (in octets)
23 @param cfb The CFB state
24 @return CRYPT_OK if successful
25 */
26 int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
27 {
28 int err;
29
30 LTC_ARGCHK(IV != NULL);
31 LTC_ARGCHK(cfb != NULL);
32
33 if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36
37 if (len != (unsigned long)cfb->blocklen) {
38 return CRYPT_INVALID_ARG;
39 }
40
41 /* force next block */
42 cfb->padlen = 0;
43 return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
44 }
45
46 #endif
47
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
+0
-65
libtom-src/modes/cfb/cfb_start.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_start.c
14 CFB implementation, start chain, Tom St Denis
15 */
16
17
18 #ifdef LTC_CFB_MODE
19
20 /**
21 Initialize a CFB context
22 @param cipher The index of the cipher desired
23 @param IV The initial vector
24 @param key The secret key
25 @param keylen The length of the secret key (octets)
26 @param num_rounds Number of rounds in the cipher desired (0 for default)
27 @param cfb The CFB state to initialize
28 @return CRYPT_OK if successful
29 */
30 int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
31 int keylen, int num_rounds, symmetric_CFB *cfb)
32 {
33 int x, err;
34
35 LTC_ARGCHK(IV != NULL);
36 LTC_ARGCHK(key != NULL);
37 LTC_ARGCHK(cfb != NULL);
38
39 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
40 return err;
41 }
42
43
44 /* copy data */
45 cfb->cipher = cipher;
46 cfb->blocklen = cipher_descriptor[cipher].block_length;
47 for (x = 0; x < cfb->blocklen; x++)
48 cfb->IV[x] = IV[x];
49
50 /* init the cipher */
51 if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) {
52 return err;
53 }
54
55 /* encrypt the IV */
56 cfb->padlen = 0;
57 return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
58 }
59
60 #endif
61
62 /* $Source$ */
63 /* $Revision$ */
64 /* $Date$ */
+0
-42
libtom-src/modes/ctr/ctr_decrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_decrypt.c
14 CTR implementation, decrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_CTR_MODE
18
19 /**
20 CTR decrypt
21 @param ct Ciphertext
22 @param pt [out] Plaintext
23 @param len Length of ciphertext (octets)
24 @param ctr CTR state
25 @return CRYPT_OK if successful
26 */
27 int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr)
28 {
29 LTC_ARGCHK(pt != NULL);
30 LTC_ARGCHK(ct != NULL);
31 LTC_ARGCHK(ctr != NULL);
32
33 return ctr_encrypt(ct, pt, len, ctr);
34 }
35
36 #endif
37
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
+0
-42
libtom-src/modes/ctr/ctr_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_done.c
14 CTR implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_CTR_MODE
18
19 /** Terminate the chain
20 @param ctr The CTR chain to terminate
21 @return CRYPT_OK on success
22 */
23 int ctr_done(symmetric_CTR *ctr)
24 {
25 int err;
26 LTC_ARGCHK(ctr != NULL);
27
28 if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[ctr->cipher].done(&ctr->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
+0
-112
libtom-src/modes/ctr/ctr_encrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_encrypt.c
14 CTR implementation, encrypt data, Tom St Denis
15 */
16
17
18 #ifdef LTC_CTR_MODE
19
20 /**
21 CTR encrypt
22 @param pt Plaintext
23 @param ct [out] Ciphertext
24 @param len Length of plaintext (octets)
25 @param ctr CTR state
26 @return CRYPT_OK if successful
27 */
28 int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
29 {
30 int x, err;
31
32 LTC_ARGCHK(pt != NULL);
33 LTC_ARGCHK(ct != NULL);
34 LTC_ARGCHK(ctr != NULL);
35
36 if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 /* is blocklen/padlen valid? */
41 if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) ||
42 ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) {
43 return CRYPT_INVALID_ARG;
44 }
45
46 #ifdef LTC_FAST
47 if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
48 return CRYPT_INVALID_ARG;
49 }
50 #endif
51
52 /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
53 if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
54 if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
55 return err;
56 }
57 len %= ctr->blocklen;
58 }
59
60 while (len) {
61 /* is the pad empty? */
62 if (ctr->padlen == ctr->blocklen) {
63 /* increment counter */
64 if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
65 /* little-endian */
66 for (x = 0; x < ctr->ctrlen; x++) {
67 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
68 if (ctr->ctr[x] != (unsigned char)0) {
69 break;
70 }
71 }
72 } else {
73 /* big-endian */
74 for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
75 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
76 if (ctr->ctr[x] != (unsigned char)0) {
77 break;
78 }
79 }
80 }
81
82 /* encrypt it */
83 if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
84 return err;
85 }
86 ctr->padlen = 0;
87 }
88 #ifdef LTC_FAST
89 if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) {
90 for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
91 *((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^
92 *((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x));
93 }
94 pt += ctr->blocklen;
95 ct += ctr->blocklen;
96 len -= ctr->blocklen;
97 ctr->padlen = ctr->blocklen;
98 continue;
99 }
100 #endif
101 *ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
102 --len;
103 }
104 return CRYPT_OK;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
+0
-46
libtom-src/modes/ctr/ctr_getiv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_getiv.c
14 CTR implementation, get IV, Tom St Denis
15 */
16
17 #ifdef LTC_CTR_MODE
18
19 /**
20 Get the current initial vector
21 @param IV [out] The destination of the initial vector
22 @param len [in/out] The max size and resulting size of the initial vector
23 @param ctr The CTR state
24 @return CRYPT_OK if successful
25 */
26 int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr)
27 {
28 LTC_ARGCHK(IV != NULL);
29 LTC_ARGCHK(len != NULL);
30 LTC_ARGCHK(ctr != NULL);
31 if ((unsigned long)ctr->blocklen > *len) {
32 *len = ctr->blocklen;
33 return CRYPT_BUFFER_OVERFLOW;
34 }
35 XMEMCPY(IV, ctr->ctr, ctr->blocklen);
36 *len = ctr->blocklen;
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
+0
-56
libtom-src/modes/ctr/ctr_setiv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_setiv.c
14 CTR implementation, set IV, Tom St Denis
15 */
16
17 #ifdef LTC_CTR_MODE
18
19 /**
20 Set an initial vector
21 @param IV The initial vector
22 @param len The length of the vector (in octets)
23 @param ctr The CTR state
24 @return CRYPT_OK if successful
25 */
26 int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
27 {
28 int err;
29
30 LTC_ARGCHK(IV != NULL);
31 LTC_ARGCHK(ctr != NULL);
32
33 /* bad param? */
34 if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
35 return err;
36 }
37
38 if (len != (unsigned long)ctr->blocklen) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 /* set IV */
43 XMEMCPY(ctr->ctr, IV, len);
44
45 /* force next block */
46 ctr->padlen = 0;
47 return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
48 }
49
50 #endif
51
52
53 /* $Source$ */
54 /* $Revision$ */
55 /* $Date$ */
+0
-101
libtom-src/modes/ctr/ctr_start.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_start.c
14 CTR implementation, start chain, Tom St Denis
15 */
16
17
18 #ifdef LTC_CTR_MODE
19
20 /**
21 Initialize a CTR context
22 @param cipher The index of the cipher desired
23 @param IV The initial vector
24 @param key The secret key
25 @param keylen The length of the secret key (octets)
26 @param num_rounds Number of rounds in the cipher desired (0 for default)
27 @param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN)
28 @param ctr The CTR state to initialize
29 @return CRYPT_OK if successful
30 */
31 int ctr_start( int cipher,
32 const unsigned char *IV,
33 const unsigned char *key, int keylen,
34 int num_rounds, int ctr_mode,
35 symmetric_CTR *ctr)
36 {
37 int x, err;
38
39 LTC_ARGCHK(IV != NULL);
40 LTC_ARGCHK(key != NULL);
41 LTC_ARGCHK(ctr != NULL);
42
43 /* bad param? */
44 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* ctrlen == counter width */
49 ctr->ctrlen = (ctr_mode & 255) ? (ctr_mode & 255) : cipher_descriptor[cipher].block_length;
50 if (ctr->ctrlen > cipher_descriptor[cipher].block_length) {
51 return CRYPT_INVALID_ARG;
52 }
53
54 if ((ctr_mode & 0x1000) == CTR_COUNTER_BIG_ENDIAN) {
55 ctr->ctrlen = cipher_descriptor[cipher].block_length - ctr->ctrlen;
56 }
57
58 /* setup cipher */
59 if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) {
60 return err;
61 }
62
63 /* copy ctr */
64 ctr->blocklen = cipher_descriptor[cipher].block_length;
65 ctr->cipher = cipher;
66 ctr->padlen = 0;
67 ctr->mode = ctr_mode & 0x1000;
68 for (x = 0; x < ctr->blocklen; x++) {
69 ctr->ctr[x] = IV[x];
70 }
71
72 if (ctr_mode & LTC_CTR_RFC3686) {
73 /* increment the IV as per RFC 3686 */
74 if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
75 /* little-endian */
76 for (x = 0; x < ctr->ctrlen; x++) {
77 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
78 if (ctr->ctr[x] != (unsigned char)0) {
79 break;
80 }
81 }
82 } else {
83 /* big-endian */
84 for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
85 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
86 if (ctr->ctr[x] != (unsigned char)0) {
87 break;
88 }
89 }
90 }
91 }
92
93 return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
94 }
95
96 #endif
97
98 /* $Source$ */
99 /* $Revision$ */
100 /* $Date$ */
+0
-61
libtom-src/modes/ecb/ecb_decrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ecb_decrypt.c
14 ECB implementation, decrypt a block, Tom St Denis
15 */
16
17 #ifdef LTC_ECB_MODE
18
19 /**
20 ECB decrypt
21 @param ct Ciphertext
22 @param pt [out] Plaintext
23 @param len The number of octets to process (must be multiple of the cipher block size)
24 @param ecb ECB state
25 @return CRYPT_OK if successful
26 */
27 int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb)
28 {
29 int err;
30 LTC_ARGCHK(pt != NULL);
31 LTC_ARGCHK(ct != NULL);
32 LTC_ARGCHK(ecb != NULL);
33 if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36 if (len % cipher_descriptor[ecb->cipher].block_length) {
37 return CRYPT_INVALID_ARG;
38 }
39
40 /* check for accel */
41 if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) {
42 return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
43 } else {
44 while (len) {
45 if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) {
46 return err;
47 }
48 pt += cipher_descriptor[ecb->cipher].block_length;
49 ct += cipher_descriptor[ecb->cipher].block_length;
50 len -= cipher_descriptor[ecb->cipher].block_length;
51 }
52 }
53 return CRYPT_OK;
54 }
55
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
+0
-42
libtom-src/modes/ecb/ecb_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ecb_done.c
14 ECB implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_ECB_MODE
18
19 /** Terminate the chain
20 @param ecb The ECB chain to terminate
21 @return CRYPT_OK on success
22 */
23 int ecb_done(symmetric_ECB *ecb)
24 {
25 int err;
26 LTC_ARGCHK(ecb != NULL);
27
28 if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[ecb->cipher].done(&ecb->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
+0
-61
libtom-src/modes/ecb/ecb_encrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ecb_encrypt.c
14 ECB implementation, encrypt a block, Tom St Denis
15 */
16
17 #ifdef LTC_ECB_MODE
18
19 /**
20 ECB encrypt
21 @param pt Plaintext
22 @param ct [out] Ciphertext
23 @param len The number of octets to process (must be multiple of the cipher block size)
24 @param ecb ECB state
25 @return CRYPT_OK if successful
26 */
27 int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb)
28 {
29 int err;
30 LTC_ARGCHK(pt != NULL);
31 LTC_ARGCHK(ct != NULL);
32 LTC_ARGCHK(ecb != NULL);
33 if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36 if (len % cipher_descriptor[ecb->cipher].block_length) {
37 return CRYPT_INVALID_ARG;
38 }
39
40 /* check for accel */
41 if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) {
42 return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
43 } else {
44 while (len) {
45 if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) {
46 return err;
47 }
48 pt += cipher_descriptor[ecb->cipher].block_length;
49 ct += cipher_descriptor[ecb->cipher].block_length;
50 len -= cipher_descriptor[ecb->cipher].block_length;
51 }
52 }
53 return CRYPT_OK;
54 }
55
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
+0
-48
libtom-src/modes/ecb/ecb_start.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ecb_start.c
14 ECB implementation, start chain, Tom St Denis
15 */
16
17
18 #ifdef LTC_ECB_MODE
19
20 /**
21 Initialize a ECB context
22 @param cipher The index of the cipher desired
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param num_rounds Number of rounds in the cipher desired (0 for default)
26 @param ecb The ECB state to initialize
27 @return CRYPT_OK if successful
28 */
29 int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb)
30 {
31 int err;
32 LTC_ARGCHK(key != NULL);
33 LTC_ARGCHK(ecb != NULL);
34
35 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
36 return err;
37 }
38 ecb->cipher = cipher;
39 ecb->blocklen = cipher_descriptor[cipher].block_length;
40 return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key);
41 }
42
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
+0
-43
libtom-src/modes/ofb/ofb_decrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_decrypt.c
14 OFB implementation, decrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /**
20 OFB decrypt
21 @param ct Ciphertext
22 @param pt [out] Plaintext
23 @param len Length of ciphertext (octets)
24 @param ofb OFB state
25 @return CRYPT_OK if successful
26 */
27 int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb)
28 {
29 LTC_ARGCHK(pt != NULL);
30 LTC_ARGCHK(ct != NULL);
31 LTC_ARGCHK(ofb != NULL);
32 return ofb_encrypt(ct, pt, len, ofb);
33 }
34
35
36 #endif
37
38
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
+0
-42
libtom-src/modes/ofb/ofb_done.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_done.c
14 OFB implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /** Terminate the chain
20 @param ofb The OFB chain to terminate
21 @return CRYPT_OK on success
22 */
23 int ofb_done(symmetric_OFB *ofb)
24 {
25 int err;
26 LTC_ARGCHK(ofb != NULL);
27
28 if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[ofb->cipher].done(&ofb->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
+0
-60
libtom-src/modes/ofb/ofb_encrypt.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_encrypt.c
14 OFB implementation, encrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /**
20 OFB encrypt
21 @param pt Plaintext
22 @param ct [out] Ciphertext
23 @param len Length of plaintext (octets)
24 @param ofb OFB state
25 @return CRYPT_OK if successful
26 */
27 int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb)
28 {
29 int err;
30 LTC_ARGCHK(pt != NULL);
31 LTC_ARGCHK(ct != NULL);
32 LTC_ARGCHK(ofb != NULL);
33 if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36
37 /* is blocklen/padlen valid? */
38 if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) ||
39 ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 while (len-- > 0) {
44 if (ofb->padlen == ofb->blocklen) {
45 if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) {
46 return err;
47 }
48 ofb->padlen = 0;
49 }
50 *ct++ = *pt++ ^ ofb->IV[(ofb->padlen)++];
51 }
52 return CRYPT_OK;
53 }
54
55 #endif
56
57 /* $Source$ */
58 /* $Revision$ */
59 /* $Date$ */
+0
-46
libtom-src/modes/ofb/ofb_getiv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_getiv.c
14 OFB implementation, get IV, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /**
20 Get the current initial vector
21 @param IV [out] The destination of the initial vector
22 @param len [in/out] The max size and resulting size of the initial vector
23 @param ofb The OFB state
24 @return CRYPT_OK if successful
25 */
26 int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb)
27 {
28 LTC_ARGCHK(IV != NULL);
29 LTC_ARGCHK(len != NULL);
30 LTC_ARGCHK(ofb != NULL);
31 if ((unsigned long)ofb->blocklen > *len) {
32 *len = ofb->blocklen;
33 return CRYPT_BUFFER_OVERFLOW;
34 }
35 XMEMCPY(IV, ofb->IV, ofb->blocklen);
36 *len = ofb->blocklen;
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
+0
-52
libtom-src/modes/ofb/ofb_setiv.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_setiv.c
14 OFB implementation, set IV, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /**
20 Set an initial vector
21 @param IV The initial vector
22 @param len The length of the vector (in octets)
23 @param ofb The OFB state
24 @return CRYPT_OK if successful
25 */
26 int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
27 {
28 int err;
29
30 LTC_ARGCHK(IV != NULL);
31 LTC_ARGCHK(ofb != NULL);
32
33 if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36
37 if (len != (unsigned long)ofb->blocklen) {
38 return CRYPT_INVALID_ARG;
39 }
40
41 /* force next block */
42 ofb->padlen = 0;
43 return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
44 }
45
46 #endif
47
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
+0
-60
libtom-src/modes/ofb/ofb_start.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_start.c
14 OFB implementation, start chain, Tom St Denis
15 */
16
17
18 #ifdef LTC_OFB_MODE
19
20 /**
21 Initialize a OFB context
22 @param cipher The index of the cipher desired
23 @param IV The initial vector
24 @param key The secret key
25 @param keylen The length of the secret key (octets)
26 @param num_rounds Number of rounds in the cipher desired (0 for default)
27 @param ofb The OFB state to initialize
28 @return CRYPT_OK if successful
29 */
30 int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
31 int keylen, int num_rounds, symmetric_OFB *ofb)
32 {
33 int x, err;
34
35 LTC_ARGCHK(IV != NULL);
36 LTC_ARGCHK(key != NULL);
37 LTC_ARGCHK(ofb != NULL);
38
39 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* copy details */
44 ofb->cipher = cipher;
45 ofb->blocklen = cipher_descriptor[cipher].block_length;
46 for (x = 0; x < ofb->blocklen; x++) {
47 ofb->IV[x] = IV[x];
48 }
49
50 /* init the cipher */
51 ofb->padlen = ofb->blocklen;
52 return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key);
53 }
54
55 #endif
56
57 /* $Source$ */
58 /* $Revision$ */
59 /* $Date$ */
+0
-102
libtom-src/pk/asn1/der/bit/der_decode_bit_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_bit_string.c
14 ASN.1 DER, encode a BIT STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a BIT STRING
22 @param in The DER encoded BIT STRING
23 @param inlen The size of the DER BIT STRING
24 @param out [out] The array of bits stored (one per char)
25 @param outlen [in/out] The number of bits stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long dlen, blen, x, y;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* packet must be at least 4 bytes */
38 if (inlen < 4) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 /* check for 0x03 */
43 if ((in[0]&0x1F) != 0x03) {
44 return CRYPT_INVALID_PACKET;
45 }
46
47 /* offset in the data */
48 x = 1;
49
50 /* get the length of the data */
51 if (in[x] & 0x80) {
52 /* long format get number of length bytes */
53 y = in[x++] & 0x7F;
54
55 /* invalid if 0 or > 2 */
56 if (y == 0 || y > 2) {
57 return CRYPT_INVALID_PACKET;
58 }
59
60 /* read the data len */
61 dlen = 0;
62 while (y--) {
63 dlen = (dlen << 8) | (unsigned long)in[x++];
64 }
65 } else {
66 /* short format */
67 dlen = in[x++] & 0x7F;
68 }
69
70 /* is the data len too long or too short? */
71 if ((dlen == 0) || (dlen + x > inlen)) {
72 return CRYPT_INVALID_PACKET;
73 }
74
75 /* get padding count */
76 blen = ((dlen - 1) << 3) - (in[x++] & 7);
77
78 /* too many bits? */
79 if (blen > *outlen) {
80 *outlen = blen;
81 return CRYPT_BUFFER_OVERFLOW;
82 }
83
84 /* decode/store the bits */
85 for (y = 0; y < blen; y++) {
86 out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0;
87 if ((y & 7) == 7) {
88 ++x;
89 }
90 }
91
92 /* we done */
93 *outlen = blen;
94 return CRYPT_OK;
95 }
96
97 #endif
98
99 /* $Source$ */
100 /* $Revision$ */
101 /* $Date$ */
+0
-106
libtom-src/pk/asn1/der/bit/der_decode_raw_bit_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_bit_string.c
14 ASN.1 DER, encode a BIT STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 #define setbit(v, n) (v=((unsigned char)(v) | (1U << (unsigned char)(n))))
21
22 /**
23 Store a BIT STRING
24 @param in The DER encoded BIT STRING
25 @param inlen The size of the DER BIT STRING
26 @param out [out] The array of bits stored (8 per char)
27 @param outlen [in/out] The number of bits stored
28 @return CRYPT_OK if successful
29 */
30 int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
31 unsigned char *out, unsigned long *outlen)
32 {
33 unsigned long dlen, blen, x, y;
34
35 LTC_ARGCHK(in != NULL);
36 LTC_ARGCHK(out != NULL);
37 LTC_ARGCHK(outlen != NULL);
38
39 /* packet must be at least 4 bytes */
40 if (inlen < 4) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 /* check for 0x03 */
45 if ((in[0]&0x1F) != 0x03) {
46 return CRYPT_INVALID_PACKET;
47 }
48
49 /* offset in the data */
50 x = 1;
51
52 /* get the length of the data */
53 if (in[x] & 0x80) {
54 /* long format get number of length bytes */
55 y = in[x++] & 0x7F;
56
57 /* invalid if 0 or > 2 */
58 if (y == 0 || y > 2) {
59 return CRYPT_INVALID_PACKET;
60 }
61
62 /* read the data len */
63 dlen = 0;
64 while (y--) {
65 dlen = (dlen << 8) | (unsigned long)in[x++];
66 }
67 } else {
68 /* short format */
69 dlen = in[x++] & 0x7F;
70 }
71
72 /* is the data len too long or too short? */
73 if ((dlen == 0) || (dlen + x > inlen)) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* get padding count */
78 blen = ((dlen - 1) << 3) - (in[x++] & 7);
79
80 /* too many bits? */
81 if (blen > *outlen) {
82 *outlen = blen;
83 return CRYPT_BUFFER_OVERFLOW;
84 }
85
86 /* decode/store the bits */
87 for (y = 0; y < blen; y++) {
88 if (in[x] & (1 << (7 - (y & 7)))) {
89 setbit(out[y/8], 7-(y%8));
90 }
91 if ((y & 7) == 7) {
92 ++x;
93 }
94 }
95
96 /* we done */
97 *outlen = blen;
98 return CRYPT_OK;
99 }
100
101 #endif
102
103 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */
104 /* $Revision: 1.5 $ */
105 /* $Date: 2006/12/28 01:27:24 $ */
+0
-89
libtom-src/pk/asn1/der/bit/der_encode_bit_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_bit_string.c
14 ASN.1 DER, encode a BIT STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a BIT STRING
22 @param in The array of bits to store (one per char)
23 @param inlen The number of bits tostore
24 @param out [out] The destination for the DER encoded BIT STRING
25 @param outlen [in/out] The max size and resulting size of the DER BIT STRING
26 @return CRYPT_OK if successful
27 */
28 int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long len, x, y;
32 unsigned char buf;
33 int err;
34
35 LTC_ARGCHK(in != NULL);
36 LTC_ARGCHK(out != NULL);
37 LTC_ARGCHK(outlen != NULL);
38
39 /* avoid overflows */
40 if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) {
41 return err;
42 }
43
44 if (len > *outlen) {
45 *outlen = len;
46 return CRYPT_BUFFER_OVERFLOW;
47 }
48
49 /* store header (include bit padding count in length) */
50 x = 0;
51 y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
52
53 out[x++] = 0x03;
54 if (y < 128) {
55 out[x++] = (unsigned char)y;
56 } else if (y < 256) {
57 out[x++] = 0x81;
58 out[x++] = (unsigned char)y;
59 } else if (y < 65536) {
60 out[x++] = 0x82;
61 out[x++] = (unsigned char)((y>>8)&255);
62 out[x++] = (unsigned char)(y&255);
63 }
64
65 /* store number of zero padding bits */
66 out[x++] = (unsigned char)((8 - inlen) & 7);
67
68 /* store the bits in big endian format */
69 for (y = buf = 0; y < inlen; y++) {
70 buf |= (in[y] ? 1 : 0) << (7 - (y & 7));
71 if ((y & 7) == 7) {
72 out[x++] = buf;
73 buf = 0;
74 }
75 }
76 /* store last byte */
77 if (inlen & 7) {
78 out[x++] = buf;
79 }
80 *outlen = x;
81 return CRYPT_OK;
82 }
83
84 #endif
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
+0
-92
libtom-src/pk/asn1/der/bit/der_encode_raw_bit_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_bit_string.c
14 ASN.1 DER, encode a BIT STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 #define getbit(n, k) (((n) & ( 1 << (k) )) >> (k))
21
22 /**
23 Store a BIT STRING
24 @param in The array of bits to store (8 per char)
25 @param inlen The number of bits tostore
26 @param out [out] The destination for the DER encoded BIT STRING
27 @param outlen [in/out] The max size and resulting size of the DER BIT STRING
28 @return CRYPT_OK if successful
29 */
30 int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
31 unsigned char *out, unsigned long *outlen)
32 {
33 unsigned long len, x, y;
34 unsigned char buf;
35 int err;
36
37 LTC_ARGCHK(in != NULL);
38 LTC_ARGCHK(out != NULL);
39 LTC_ARGCHK(outlen != NULL);
40
41 /* avoid overflows */
42 if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) {
43 return err;
44 }
45
46 if (len > *outlen) {
47 *outlen = len;
48 return CRYPT_BUFFER_OVERFLOW;
49 }
50
51 /* store header (include bit padding count in length) */
52 x = 0;
53 y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
54
55 out[x++] = 0x03;
56 if (y < 128) {
57 out[x++] = (unsigned char)y;
58 } else if (y < 256) {
59 out[x++] = 0x81;
60 out[x++] = (unsigned char)y;
61 } else if (y < 65536) {
62 out[x++] = 0x82;
63 out[x++] = (unsigned char)((y>>8)&255);
64 out[x++] = (unsigned char)(y&255);
65 }
66
67 /* store number of zero padding bits */
68 out[x++] = (unsigned char)((8 - inlen) & 7);
69
70 /* store the bits in big endian format */
71 for (y = buf = 0; y < inlen; y++) {
72 buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7));
73 if ((y & 7) == 7) {
74 out[x++] = buf;
75 buf = 0;
76 }
77 }
78 /* store last byte */
79 if (inlen & 7) {
80 out[x++] = buf;
81 }
82
83 *outlen = x;
84 return CRYPT_OK;
85 }
86
87 #endif
88
89 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */
90 /* $Revision: 1.5 $ */
91 /* $Date: 2006/12/28 01:27:24 $ */
+0
-54
libtom-src/pk/asn1/der/bit/der_length_bit_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_bit_string.c
14 ASN.1 DER, get length of BIT STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Gets length of DER encoding of BIT STRING
20 @param nbits The number of bits in the string to encode
21 @param outlen [out] The length of the DER encoding for the given string
22 @return CRYPT_OK if successful
23 */
24 int der_length_bit_string(unsigned long nbits, unsigned long *outlen)
25 {
26 unsigned long nbytes;
27 LTC_ARGCHK(outlen != NULL);
28
29 /* get the number of the bytes */
30 nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
31
32 if (nbytes < 128) {
33 /* 03 LL PP DD DD DD ... */
34 *outlen = 2 + nbytes;
35 } else if (nbytes < 256) {
36 /* 03 81 LL PP DD DD DD ... */
37 *outlen = 3 + nbytes;
38 } else if (nbytes < 65536) {
39 /* 03 82 LL LL PP DD DD DD ... */
40 *outlen = 4 + nbytes;
41 } else {
42 return CRYPT_INVALID_ARG;
43 }
44
45 return CRYPT_OK;
46 }
47
48 #endif
49
50
51 /* $Source$ */
52 /* $Revision$ */
53 /* $Date$ */
+0
-47
libtom-src/pk/asn1/der/boolean/der_decode_boolean.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_boolean.c
14 ASN.1 DER, decode a BOOLEAN, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Read a BOOLEAN
22 @param in The destination for the DER encoded BOOLEAN
23 @param inlen The size of the DER BOOLEAN
24 @param out [out] The boolean to decode
25 @return CRYPT_OK if successful
26 */
27 int der_decode_boolean(const unsigned char *in, unsigned long inlen,
28 int *out)
29 {
30 LTC_ARGCHK(in != NULL);
31 LTC_ARGCHK(out != NULL);
32
33 if (inlen < 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) {
34 return CRYPT_INVALID_ARG;
35 }
36
37 *out = (in[2]==0xFF) ? 1 : 0;
38
39 return CRYPT_OK;
40 }
41
42 #endif
43
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
+0
-51
libtom-src/pk/asn1/der/boolean/der_encode_boolean.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_boolean.c
14 ASN.1 DER, encode a BOOLEAN, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a BOOLEAN
22 @param in The boolean to encode
23 @param out [out] The destination for the DER encoded BOOLEAN
24 @param outlen [in/out] The max size and resulting size of the DER BOOLEAN
25 @return CRYPT_OK if successful
26 */
27 int der_encode_boolean(int in,
28 unsigned char *out, unsigned long *outlen)
29 {
30 LTC_ARGCHK(outlen != NULL);
31 LTC_ARGCHK(out != NULL);
32
33 if (*outlen < 3) {
34 *outlen = 3;
35 return CRYPT_BUFFER_OVERFLOW;
36 }
37
38 *outlen = 3;
39 out[0] = 0x01;
40 out[1] = 0x01;
41 out[2] = in ? 0xFF : 0x00;
42
43 return CRYPT_OK;
44 }
45
46 #endif
47
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
+0
-35
libtom-src/pk/asn1/der/boolean/der_length_boolean.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_boolean.c
14 ASN.1 DER, get length of a BOOLEAN, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Gets length of DER encoding of a BOOLEAN
20 @param outlen [out] The length of the DER encoding
21 @return CRYPT_OK if successful
22 */
23 int der_length_boolean(unsigned long *outlen)
24 {
25 LTC_ARGCHK(outlen != NULL);
26 *outlen = 3;
27 return CRYPT_OK;
28 }
29
30 #endif
31
32 /* $Source$ */
33 /* $Revision$ */
34 /* $Date$ */
+0
-182
libtom-src/pk/asn1/der/choice/der_decode_choice.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_choice.c
14 ASN.1 DER, decode a CHOICE, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Decode a CHOICE
21 @param in The DER encoded input
22 @param inlen [in/out] The size of the input and resulting size of read type
23 @param list The list of items to decode
24 @param outlen The number of items in the list
25 @return CRYPT_OK on success
26 */
27 int der_decode_choice(const unsigned char *in, unsigned long *inlen,
28 ltc_asn1_list *list, unsigned long outlen)
29 {
30 unsigned long size, x, z;
31 void *data;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(inlen != NULL);
35 LTC_ARGCHK(list != NULL);
36
37 /* get blk size */
38 if (*inlen < 2) {
39 return CRYPT_INVALID_PACKET;
40 }
41
42 /* set all of the "used" flags to zero */
43 for (x = 0; x < outlen; x++) {
44 list[x].used = 0;
45 }
46
47 /* now scan until we have a winner */
48 for (x = 0; x < outlen; x++) {
49 size = list[x].size;
50 data = list[x].data;
51
52 switch (list[x].type) {
53 case LTC_ASN1_INTEGER:
54 if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
55 if (der_length_integer(data, &z) == CRYPT_OK) {
56 list[x].used = 1;
57 *inlen = z;
58 return CRYPT_OK;
59 }
60 }
61 break;
62
63 case LTC_ASN1_SHORT_INTEGER:
64 if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) {
65 if (der_length_short_integer(size, &z) == CRYPT_OK) {
66 list[x].used = 1;
67 *inlen = z;
68 return CRYPT_OK;
69 }
70 }
71 break;
72
73 case LTC_ASN1_BIT_STRING:
74 if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
75 if (der_length_bit_string(size, &z) == CRYPT_OK) {
76 list[x].used = 1;
77 list[x].size = size;
78 *inlen = z;
79 return CRYPT_OK;
80 }
81 }
82 break;
83
84 case LTC_ASN1_OCTET_STRING:
85 if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
86 if (der_length_octet_string(size, &z) == CRYPT_OK) {
87 list[x].used = 1;
88 list[x].size = size;
89 *inlen = z;
90 return CRYPT_OK;
91 }
92 }
93 break;
94
95 case LTC_ASN1_NULL:
96 if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
97 *inlen = 2;
98 list[x].used = 1;
99 return CRYPT_OK;
100 }
101 break;
102
103 case LTC_ASN1_OBJECT_IDENTIFIER:
104 if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) {
105 if (der_length_object_identifier(data, size, &z) == CRYPT_OK) {
106 list[x].used = 1;
107 list[x].size = size;
108 *inlen = z;
109 return CRYPT_OK;
110 }
111 }
112 break;
113
114 case LTC_ASN1_IA5_STRING:
115 if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
116 if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
117 list[x].used = 1;
118 list[x].size = size;
119 *inlen = z;
120 return CRYPT_OK;
121 }
122 }
123 break;
124
125
126 case LTC_ASN1_PRINTABLE_STRING:
127 if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) {
128 if (der_length_printable_string(data, size, &z) == CRYPT_OK) {
129 list[x].used = 1;
130 list[x].size = size;
131 *inlen = z;
132 return CRYPT_OK;
133 }
134 }
135 break;
136
137 case LTC_ASN1_UTF8_STRING:
138 if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) {
139 if (der_length_utf8_string(data, size, &z) == CRYPT_OK) {
140 list[x].used = 1;
141 list[x].size = size;
142 *inlen = z;
143 return CRYPT_OK;
144 }
145 }
146 break;
147
148 case LTC_ASN1_UTCTIME:
149 z = *inlen;
150 if (der_decode_utctime(in, &z, data) == CRYPT_OK) {
151 list[x].used = 1;
152 *inlen = z;
153 return CRYPT_OK;
154 }
155 break;
156
157 case LTC_ASN1_SET:
158 case LTC_ASN1_SETOF:
159 case LTC_ASN1_SEQUENCE:
160 if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
161 if (der_length_sequence(data, size, &z) == CRYPT_OK) {
162 list[x].used = 1;
163 *inlen = z;
164 return CRYPT_OK;
165 }
166 }
167 break;
168
169 default:
170 return CRYPT_INVALID_ARG;
171 }
172 }
173
174 return CRYPT_INVALID_PACKET;
175 }
176
177 #endif
178
179 /* $Source$ */
180 /* $Revision$ */
181 /* $Date$ */
+0
-96
libtom-src/pk/asn1/der/ia5/der_decode_ia5_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_ia5_string.c
14 ASN.1 DER, encode a IA5 STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a IA5 STRING
22 @param in The DER encoded IA5 STRING
23 @param inlen The size of the DER IA5 STRING
24 @param out [out] The array of octets stored (one per char)
25 @param outlen [in/out] The number of octets stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32 int t;
33
34 LTC_ARGCHK(in != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* must have header at least */
39 if (inlen < 2) {
40 return CRYPT_INVALID_PACKET;
41 }
42
43 /* check for 0x16 */
44 if ((in[0] & 0x1F) != 0x16) {
45 return CRYPT_INVALID_PACKET;
46 }
47 x = 1;
48
49 /* decode the length */
50 if (in[x] & 0x80) {
51 /* valid # of bytes in length are 1,2,3 */
52 y = in[x] & 0x7F;
53 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* read the length in */
58 len = 0;
59 ++x;
60 while (y--) {
61 len = (len << 8) | in[x++];
62 }
63 } else {
64 len = in[x++] & 0x7F;
65 }
66
67 /* is it too long? */
68 if (len > *outlen) {
69 *outlen = len;
70 return CRYPT_BUFFER_OVERFLOW;
71 }
72
73 if (len + x > inlen) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* read the data */
78 for (y = 0; y < len; y++) {
79 t = der_ia5_value_decode(in[x++]);
80 if (t == -1) {
81 return CRYPT_INVALID_ARG;
82 }
83 out[y] = t;
84 }
85
86 *outlen = y;
87
88 return CRYPT_OK;
89 }
90
91 #endif
92
93 /* $Source$ */
94 /* $Revision$ */
95 /* $Date$ */
+0
-85
libtom-src/pk/asn1/der/ia5/der_encode_ia5_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_ia5_string.c
14 ASN.1 DER, encode a IA5 STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Store an IA5 STRING
21 @param in The array of IA5 to store (one per char)
22 @param inlen The number of IA5 to store
23 @param out [out] The destination for the DER encoded IA5 STRING
24 @param outlen [in/out] The max size and resulting size of the DER IA5 STRING
25 @return CRYPT_OK if successful
26 */
27 int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
28 unsigned char *out, unsigned long *outlen)
29 {
30 unsigned long x, y, len;
31 int err;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* get the size */
38 if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* too big? */
43 if (len > *outlen) {
44 *outlen = len;
45 return CRYPT_BUFFER_OVERFLOW;
46 }
47
48 /* encode the header+len */
49 x = 0;
50 out[x++] = 0x16;
51 if (inlen < 128) {
52 out[x++] = (unsigned char)inlen;
53 } else if (inlen < 256) {
54 out[x++] = 0x81;
55 out[x++] = (unsigned char)inlen;
56 } else if (inlen < 65536UL) {
57 out[x++] = 0x82;
58 out[x++] = (unsigned char)((inlen>>8)&255);
59 out[x++] = (unsigned char)(inlen&255);
60 } else if (inlen < 16777216UL) {
61 out[x++] = 0x83;
62 out[x++] = (unsigned char)((inlen>>16)&255);
63 out[x++] = (unsigned char)((inlen>>8)&255);
64 out[x++] = (unsigned char)(inlen&255);
65 } else {
66 return CRYPT_INVALID_ARG;
67 }
68
69 /* store octets */
70 for (y = 0; y < inlen; y++) {
71 out[x++] = der_ia5_char_encode(in[y]);
72 }
73
74 /* retun length */
75 *outlen = x;
76
77 return CRYPT_OK;
78 }
79
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
+0
-194
libtom-src/pk/asn1/der/ia5/der_length_ia5_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_ia5_string.c
14 ASN.1 DER, get length of IA5 STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static const struct {
20 int code, value;
21 } ia5_table[] = {
22 { '\0', 0 },
23 { '\a', 7 },
24 { '\b', 8 },
25 { '\t', 9 },
26 { '\n', 10 },
27 { '\f', 12 },
28 { '\r', 13 },
29 { ' ', 32 },
30 { '!', 33 },
31 { '"', 34 },
32 { '#', 35 },
33 { '$', 36 },
34 { '%', 37 },
35 { '&', 38 },
36 { '\'', 39 },
37 { '(', 40 },
38 { ')', 41 },
39 { '*', 42 },
40 { '+', 43 },
41 { ',', 44 },
42 { '-', 45 },
43 { '.', 46 },
44 { '/', 47 },
45 { '0', 48 },
46 { '1', 49 },
47 { '2', 50 },
48 { '3', 51 },
49 { '4', 52 },
50 { '5', 53 },
51 { '6', 54 },
52 { '7', 55 },
53 { '8', 56 },
54 { '9', 57 },
55 { ':', 58 },
56 { ';', 59 },
57 { '<', 60 },
58 { '=', 61 },
59 { '>', 62 },
60 { '?', 63 },
61 { '@', 64 },
62 { 'A', 65 },
63 { 'B', 66 },
64 { 'C', 67 },
65 { 'D', 68 },
66 { 'E', 69 },
67 { 'F', 70 },
68 { 'G', 71 },
69 { 'H', 72 },
70 { 'I', 73 },
71 { 'J', 74 },
72 { 'K', 75 },
73 { 'L', 76 },
74 { 'M', 77 },
75 { 'N', 78 },
76 { 'O', 79 },
77 { 'P', 80 },
78 { 'Q', 81 },
79 { 'R', 82 },
80 { 'S', 83 },
81 { 'T', 84 },
82 { 'U', 85 },
83 { 'V', 86 },
84 { 'W', 87 },
85 { 'X', 88 },
86 { 'Y', 89 },
87 { 'Z', 90 },
88 { '[', 91 },
89 { '\\', 92 },
90 { ']', 93 },
91 { '^', 94 },
92 { '_', 95 },
93 { '`', 96 },
94 { 'a', 97 },
95 { 'b', 98 },
96 { 'c', 99 },
97 { 'd', 100 },
98 { 'e', 101 },
99 { 'f', 102 },
100 { 'g', 103 },
101 { 'h', 104 },
102 { 'i', 105 },
103 { 'j', 106 },
104 { 'k', 107 },
105 { 'l', 108 },
106 { 'm', 109 },
107 { 'n', 110 },
108 { 'o', 111 },
109 { 'p', 112 },
110 { 'q', 113 },
111 { 'r', 114 },
112 { 's', 115 },
113 { 't', 116 },
114 { 'u', 117 },
115 { 'v', 118 },
116 { 'w', 119 },
117 { 'x', 120 },
118 { 'y', 121 },
119 { 'z', 122 },
120 { '{', 123 },
121 { '|', 124 },
122 { '}', 125 },
123 { '~', 126 }
124 };
125
126 int der_ia5_char_encode(int c)
127 {
128 int x;
129 for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
130 if (ia5_table[x].code == c) {
131 return ia5_table[x].value;
132 }
133 }
134 return -1;
135 }
136
137 int der_ia5_value_decode(int v)
138 {
139 int x;
140 for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
141 if (ia5_table[x].value == v) {
142 return ia5_table[x].code;
143 }
144 }
145 return -1;
146 }
147
148 /**
149 Gets length of DER encoding of IA5 STRING
150 @param octets The values you want to encode
151 @param noctets The number of octets in the string to encode
152 @param outlen [out] The length of the DER encoding for the given string
153 @return CRYPT_OK if successful
154 */
155 int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
156 {
157 unsigned long x;
158
159 LTC_ARGCHK(outlen != NULL);
160 LTC_ARGCHK(octets != NULL);
161
162 /* scan string for validity */
163 for (x = 0; x < noctets; x++) {
164 if (der_ia5_char_encode(octets[x]) == -1) {
165 return CRYPT_INVALID_ARG;
166 }
167 }
168
169 if (noctets < 128) {
170 /* 16 LL DD DD DD ... */
171 *outlen = 2 + noctets;
172 } else if (noctets < 256) {
173 /* 16 81 LL DD DD DD ... */
174 *outlen = 3 + noctets;
175 } else if (noctets < 65536UL) {
176 /* 16 82 LL LL DD DD DD ... */
177 *outlen = 4 + noctets;
178 } else if (noctets < 16777216UL) {
179 /* 16 83 LL LL LL DD DD DD ... */
180 *outlen = 5 + noctets;
181 } else {
182 return CRYPT_INVALID_ARG;
183 }
184
185 return CRYPT_OK;
186 }
187
188 #endif
189
190
191 /* $Source$ */
192 /* $Revision$ */
193 /* $Date$ */
+0
-110
libtom-src/pk/asn1/der/integer/der_decode_integer.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_integer.c
14 ASN.1 DER, decode an integer, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Read a mp_int integer
22 @param in The DER encoded data
23 @param inlen Size of DER encoded data
24 @param num The first mp_int to decode
25 @return CRYPT_OK if successful
26 */
27 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num)
28 {
29 unsigned long x, y, z;
30 int err;
31
32 LTC_ARGCHK(num != NULL);
33 LTC_ARGCHK(in != NULL);
34
35 /* min DER INTEGER is 0x02 01 00 == 0 */
36 if (inlen < (1 + 1 + 1)) {
37 return CRYPT_INVALID_PACKET;
38 }
39
40 /* ok expect 0x02 when we AND with 0001 1111 [1F] */
41 x = 0;
42 if ((in[x++] & 0x1F) != 0x02) {
43 return CRYPT_INVALID_PACKET;
44 }
45
46 /* now decode the len stuff */
47 z = in[x++];
48
49 if ((z & 0x80) == 0x00) {
50 /* short form */
51
52 /* will it overflow? */
53 if (x + z > inlen) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* no so read it */
58 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) {
59 return err;
60 }
61 } else {
62 /* long form */
63 z &= 0x7F;
64
65 /* will number of length bytes overflow? (or > 4) */
66 if (((x + z) > inlen) || (z > 4) || (z == 0)) {
67 return CRYPT_INVALID_PACKET;
68 }
69
70 /* now read it in */
71 y = 0;
72 while (z--) {
73 y = ((unsigned long)(in[x++])) | (y << 8);
74 }
75
76 /* now will reading y bytes overrun? */
77 if ((x + y) > inlen) {
78 return CRYPT_INVALID_PACKET;
79 }
80
81 /* no so read it */
82 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) {
83 return err;
84 }
85 }
86
87 /* see if it's negative */
88 if (in[x] & 0x80) {
89 void *tmp;
90 if (mp_init(&tmp) != CRYPT_OK) {
91 return CRYPT_MEM;
92 }
93
94 if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) {
95 mp_clear(tmp);
96 return CRYPT_MEM;
97 }
98 mp_clear(tmp);
99 }
100
101 return CRYPT_OK;
102
103 }
104
105 #endif
106
107 /* $Source$ */
108 /* $Revision$ */
109 /* $Date$ */
+0
-130
libtom-src/pk/asn1/der/integer/der_encode_integer.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_integer.c
14 ASN.1 DER, encode an integer, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /* Exports a positive bignum as DER format (upto 2^32 bytes in size) */
21 /**
22 Store a mp_int integer
23 @param num The first mp_int to encode
24 @param out [out] The destination for the DER encoded integers
25 @param outlen [in/out] The max size and resulting size of the DER encoded integers
26 @return CRYPT_OK if successful
27 */
28 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen)
29 {
30 unsigned long tmplen, y;
31 int err, leading_zero;
32
33 LTC_ARGCHK(num != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* find out how big this will be */
38 if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) {
39 return err;
40 }
41
42 if (*outlen < tmplen) {
43 *outlen = tmplen;
44 return CRYPT_BUFFER_OVERFLOW;
45 }
46
47 if (mp_cmp_d(num, 0) != LTC_MP_LT) {
48 /* we only need a leading zero if the msb of the first byte is one */
49 if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
50 leading_zero = 1;
51 } else {
52 leading_zero = 0;
53 }
54
55 /* get length of num in bytes (plus 1 since we force the msbyte to zero) */
56 y = mp_unsigned_bin_size(num) + leading_zero;
57 } else {
58 leading_zero = 0;
59 y = mp_count_bits(num);
60 y = y + (8 - (y & 7));
61 y = y >> 3;
62 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y;
63 }
64
65 /* now store initial data */
66 *out++ = 0x02;
67 if (y < 128) {
68 /* short form */
69 *out++ = (unsigned char)y;
70 } else if (y < 256) {
71 *out++ = 0x81;
72 *out++ = (unsigned char)y;
73 } else if (y < 65536UL) {
74 *out++ = 0x82;
75 *out++ = (unsigned char)((y>>8)&255);
76 *out++ = (unsigned char)y;
77 } else if (y < 16777216UL) {
78 *out++ = 0x83;
79 *out++ = (unsigned char)((y>>16)&255);
80 *out++ = (unsigned char)((y>>8)&255);
81 *out++ = (unsigned char)y;
82 } else {
83 return CRYPT_INVALID_ARG;
84 }
85
86 /* now store msbyte of zero if num is non-zero */
87 if (leading_zero) {
88 *out++ = 0x00;
89 }
90
91 /* if it's not zero store it as big endian */
92 if (mp_cmp_d(num, 0) == LTC_MP_GT) {
93 /* now store the mpint */
94 if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) {
95 return err;
96 }
97 } else if (mp_iszero(num) != LTC_MP_YES) {
98 void *tmp;
99
100 /* negative */
101 if (mp_init(&tmp) != CRYPT_OK) {
102 return CRYPT_MEM;
103 }
104
105 /* 2^roundup and subtract */
106 y = mp_count_bits(num);
107 y = y + (8 - (y & 7));
108 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8;
109 if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) {
110 mp_clear(tmp);
111 return CRYPT_MEM;
112 }
113 if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) {
114 mp_clear(tmp);
115 return err;
116 }
117 mp_clear(tmp);
118 }
119
120 /* we good */
121 *outlen = tmplen;
122 return CRYPT_OK;
123 }
124
125 #endif
126
127 /* $Source$ */
128 /* $Revision$ */
129 /* $Date$ */
+0
-82
libtom-src/pk/asn1/der/integer/der_length_integer.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_integer.c
14 ASN.1 DER, get length of encoding, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19 /**
20 Gets length of DER encoding of num
21 @param num The int to get the size of
22 @param outlen [out] The length of the DER encoding for the given integer
23 @return CRYPT_OK if successful
24 */
25 int der_length_integer(void *num, unsigned long *outlen)
26 {
27 unsigned long z, len;
28 int leading_zero;
29
30 LTC_ARGCHK(num != NULL);
31 LTC_ARGCHK(outlen != NULL);
32
33 if (mp_cmp_d(num, 0) != LTC_MP_LT) {
34 /* positive */
35
36 /* we only need a leading zero if the msb of the first byte is one */
37 if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
38 leading_zero = 1;
39 } else {
40 leading_zero = 0;
41 }
42
43 /* size for bignum */
44 z = len = leading_zero + mp_unsigned_bin_size(num);
45 } else {
46 /* it's negative */
47 /* find power of 2 that is a multiple of eight and greater than count bits */
48 leading_zero = 0;
49 z = mp_count_bits(num);
50 z = z + (8 - (z & 7));
51 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z;
52 len = z = z >> 3;
53 }
54
55 /* now we need a length */
56 if (z < 128) {
57 /* short form */
58 ++len;
59 } else {
60 /* long form (relies on z != 0), assumes length bytes < 128 */
61 ++len;
62
63 while (z) {
64 ++len;
65 z >>= 8;
66 }
67 }
68
69 /* we need a 0x02 to indicate it's INTEGER */
70 ++len;
71
72 /* return length */
73 *outlen = len;
74 return CRYPT_OK;
75 }
76
77 #endif
78
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
+0
-99
libtom-src/pk/asn1/der/object_identifier/der_decode_object_identifier.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_object_identifier.c
14 ASN.1 DER, Decode Object Identifier, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Decode OID data and store the array of integers in words
20 @param in The OID DER encoded data
21 @param inlen The length of the OID data
22 @param words [out] The destination of the OID words
23 @param outlen [in/out] The number of OID words
24 @return CRYPT_OK if successful
25 */
26 int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
27 unsigned long *words, unsigned long *outlen)
28 {
29 unsigned long x, y, t, len;
30
31 LTC_ARGCHK(in != NULL);
32 LTC_ARGCHK(words != NULL);
33 LTC_ARGCHK(outlen != NULL);
34
35 /* header is at least 3 bytes */
36 if (inlen < 3) {
37 return CRYPT_INVALID_PACKET;
38 }
39
40 /* must be room for at least two words */
41 if (*outlen < 2) {
42 return CRYPT_BUFFER_OVERFLOW;
43 }
44
45 /* decode the packet header */
46 x = 0;
47 if ((in[x++] & 0x1F) != 0x06) {
48 return CRYPT_INVALID_PACKET;
49 }
50
51 /* get the length */
52 if (in[x] < 128) {
53 len = in[x++];
54 } else {
55 if (in[x] < 0x81 || in[x] > 0x82) {
56 return CRYPT_INVALID_PACKET;
57 }
58 y = in[x++] & 0x7F;
59 len = 0;
60 while (y--) {
61 len = (len << 8) | (unsigned long)in[x++];
62 }
63 }
64
65 if (len < 1 || (len + x) > inlen) {
66 return CRYPT_INVALID_PACKET;
67 }
68
69 /* decode words */
70 y = 0;
71 t = 0;
72 while (len--) {
73 t = (t << 7) | (in[x] & 0x7F);
74 if (!(in[x++] & 0x80)) {
75 /* store t */
76 if (y >= *outlen) {
77 return CRYPT_BUFFER_OVERFLOW;
78 }
79 if (y == 0) {
80 words[0] = t / 40;
81 words[1] = t % 40;
82 y = 2;
83 } else {
84 words[y++] = t;
85 }
86 t = 0;
87 }
88 }
89
90 *outlen = y;
91 return CRYPT_OK;
92 }
93
94 #endif
95
96 /* $Source$ */
97 /* $Revision$ */
98 /* $Date$ */
+0
-111
libtom-src/pk/asn1/der/object_identifier/der_encode_object_identifier.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_object_identifier.c
14 ASN.1 DER, Encode Object Identifier, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Encode an OID
20 @param words The words to encode (upto 32-bits each)
21 @param nwords The number of words in the OID
22 @param out [out] Destination of OID data
23 @param outlen [in/out] The max and resulting size of the OID
24 @return CRYPT_OK if successful
25 */
26 int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
27 unsigned char *out, unsigned long *outlen)
28 {
29 unsigned long i, x, y, z, t, mask, wordbuf;
30 int err;
31
32 LTC_ARGCHK(words != NULL);
33 LTC_ARGCHK(out != NULL);
34 LTC_ARGCHK(outlen != NULL);
35
36 /* check length */
37 if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) {
38 return err;
39 }
40 if (x > *outlen) {
41 *outlen = x;
42 return CRYPT_BUFFER_OVERFLOW;
43 }
44
45 /* compute length to store OID data */
46 z = 0;
47 wordbuf = words[0] * 40 + words[1];
48 for (y = 1; y < nwords; y++) {
49 t = der_object_identifier_bits(wordbuf);
50 z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
51 if (y < nwords - 1) {
52 wordbuf = words[y + 1];
53 }
54 }
55
56 /* store header + length */
57 x = 0;
58 out[x++] = 0x06;
59 if (z < 128) {
60 out[x++] = (unsigned char)z;
61 } else if (z < 256) {
62 out[x++] = 0x81;
63 out[x++] = (unsigned char)z;
64 } else if (z < 65536UL) {
65 out[x++] = 0x82;
66 out[x++] = (unsigned char)((z>>8)&255);
67 out[x++] = (unsigned char)(z&255);
68 } else {
69 return CRYPT_INVALID_ARG;
70 }
71
72 /* store first byte */
73 wordbuf = words[0] * 40 + words[1];
74 for (i = 1; i < nwords; i++) {
75 /* store 7 bit words in little endian */
76 t = wordbuf & 0xFFFFFFFF;
77 if (t) {
78 y = x;
79 mask = 0;
80 while (t) {
81 out[x++] = (unsigned char)((t & 0x7F) | mask);
82 t >>= 7;
83 mask |= 0x80; /* upper bit is set on all but the last byte */
84 }
85 /* now swap bytes y...x-1 */
86 z = x - 1;
87 while (y < z) {
88 t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t;
89 ++y;
90 --z;
91 }
92 } else {
93 /* zero word */
94 out[x++] = 0x00;
95 }
96
97 if (i < nwords - 1) {
98 wordbuf = words[i + 1];
99 }
100 }
101
102 *outlen = x;
103 return CRYPT_OK;
104 }
105
106 #endif
107
108 /* $Source$ */
109 /* $Revision$ */
110 /* $Date$ */
+0
-89
libtom-src/pk/asn1/der/object_identifier/der_length_object_identifier.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_object_identifier.c
14 ASN.1 DER, get length of Object Identifier, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 unsigned long der_object_identifier_bits(unsigned long x)
20 {
21 unsigned long c;
22 x &= 0xFFFFFFFF;
23 c = 0;
24 while (x) {
25 ++c;
26 x >>= 1;
27 }
28 return c;
29 }
30
31
32 /**
33 Gets length of DER encoding of Object Identifier
34 @param nwords The number of OID words
35 @param words The actual OID words to get the size of
36 @param outlen [out] The length of the DER encoding for the given string
37 @return CRYPT_OK if successful
38 */
39 int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen)
40 {
41 unsigned long y, z, t, wordbuf;
42
43 LTC_ARGCHK(words != NULL);
44 LTC_ARGCHK(outlen != NULL);
45
46
47 /* must be >= 2 words */
48 if (nwords < 2) {
49 return CRYPT_INVALID_ARG;
50 }
51
52 /* word1 = 0,1,2,3 and word2 0..39 */
53 if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) {
54 return CRYPT_INVALID_ARG;
55 }
56
57 /* leading word is the first two */
58 z = 0;
59 wordbuf = words[0] * 40 + words[1];
60 for (y = 1; y < nwords; y++) {
61 t = der_object_identifier_bits(wordbuf);
62 z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
63 if (y < nwords - 1) {
64 /* grab next word */
65 wordbuf = words[y+1];
66 }
67 }
68
69 /* now depending on the length our length encoding changes */
70 if (z < 128) {
71 z += 2;
72 } else if (z < 256) {
73 z += 3;
74 } else if (z < 65536UL) {
75 z += 4;
76 } else {
77 return CRYPT_INVALID_ARG;
78 }
79
80 *outlen = z;
81 return CRYPT_OK;
82 }
83
84 #endif
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
+0
-91
libtom-src/pk/asn1/der/octet/der_decode_octet_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_octet_string.c
14 ASN.1 DER, encode a OCTET STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a OCTET STRING
22 @param in The DER encoded OCTET STRING
23 @param inlen The size of the DER OCTET STRING
24 @param out [out] The array of octets stored (one per char)
25 @param outlen [in/out] The number of octets stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* must have header at least */
38 if (inlen < 2) {
39 return CRYPT_INVALID_PACKET;
40 }
41
42 /* check for 0x04 */
43 if ((in[0] & 0x1F) != 0x04) {
44 return CRYPT_INVALID_PACKET;
45 }
46 x = 1;
47
48 /* decode the length */
49 if (in[x] & 0x80) {
50 /* valid # of bytes in length are 1,2,3 */
51 y = in[x] & 0x7F;
52 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
53 return CRYPT_INVALID_PACKET;
54 }
55
56 /* read the length in */
57 len = 0;
58 ++x;
59 while (y--) {
60 len = (len << 8) | in[x++];
61 }
62 } else {
63 len = in[x++] & 0x7F;
64 }
65
66 /* is it too long? */
67 if (len > *outlen) {
68 *outlen = len;
69 return CRYPT_BUFFER_OVERFLOW;
70 }
71
72 if (len + x > inlen) {
73 return CRYPT_INVALID_PACKET;
74 }
75
76 /* read the data */
77 for (y = 0; y < len; y++) {
78 out[y] = in[x++];
79 }
80
81 *outlen = y;
82
83 return CRYPT_OK;
84 }
85
86 #endif
87
88 /* $Source$ */
89 /* $Revision$ */
90 /* $Date$ */
+0
-86
libtom-src/pk/asn1/der/octet/der_encode_octet_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_octet_string.c
14 ASN.1 DER, encode a OCTET STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store an OCTET STRING
22 @param in The array of OCTETS to store (one per char)
23 @param inlen The number of OCTETS to store
24 @param out [out] The destination for the DER encoded OCTET STRING
25 @param outlen [in/out] The max size and resulting size of the DER OCTET STRING
26 @return CRYPT_OK if successful
27 */
28 int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32 int err;
33
34 LTC_ARGCHK(in != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* get the size */
39 if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* too big? */
44 if (len > *outlen) {
45 *outlen = len;
46 return CRYPT_BUFFER_OVERFLOW;
47 }
48
49 /* encode the header+len */
50 x = 0;
51 out[x++] = 0x04;
52 if (inlen < 128) {
53 out[x++] = (unsigned char)inlen;
54 } else if (inlen < 256) {
55 out[x++] = 0x81;
56 out[x++] = (unsigned char)inlen;
57 } else if (inlen < 65536UL) {
58 out[x++] = 0x82;
59 out[x++] = (unsigned char)((inlen>>8)&255);
60 out[x++] = (unsigned char)(inlen&255);
61 } else if (inlen < 16777216UL) {
62 out[x++] = 0x83;
63 out[x++] = (unsigned char)((inlen>>16)&255);
64 out[x++] = (unsigned char)((inlen>>8)&255);
65 out[x++] = (unsigned char)(inlen&255);
66 } else {
67 return CRYPT_INVALID_ARG;
68 }
69
70 /* store octets */
71 for (y = 0; y < inlen; y++) {
72 out[x++] = in[y];
73 }
74
75 /* retun length */
76 *outlen = x;
77
78 return CRYPT_OK;
79 }
80
81 #endif
82
83 /* $Source$ */
84 /* $Revision$ */
85 /* $Date$ */
+0
-53
libtom-src/pk/asn1/der/octet/der_length_octet_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_octet_string.c
14 ASN.1 DER, get length of OCTET STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Gets length of DER encoding of OCTET STRING
20 @param noctets The number of octets in the string to encode
21 @param outlen [out] The length of the DER encoding for the given string
22 @return CRYPT_OK if successful
23 */
24 int der_length_octet_string(unsigned long noctets, unsigned long *outlen)
25 {
26 LTC_ARGCHK(outlen != NULL);
27
28 if (noctets < 128) {
29 /* 04 LL DD DD DD ... */
30 *outlen = 2 + noctets;
31 } else if (noctets < 256) {
32 /* 04 81 LL DD DD DD ... */
33 *outlen = 3 + noctets;
34 } else if (noctets < 65536UL) {
35 /* 04 82 LL LL DD DD DD ... */
36 *outlen = 4 + noctets;
37 } else if (noctets < 16777216UL) {
38 /* 04 83 LL LL LL DD DD DD ... */
39 *outlen = 5 + noctets;
40 } else {
41 return CRYPT_INVALID_ARG;
42 }
43
44 return CRYPT_OK;
45 }
46
47 #endif
48
49
50 /* $Source$ */
51 /* $Revision$ */
52 /* $Date$ */
+0
-96
libtom-src/pk/asn1/der/printable_string/der_decode_printable_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_printable_string.c
14 ASN.1 DER, encode a printable STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a printable STRING
22 @param in The DER encoded printable STRING
23 @param inlen The size of the DER printable STRING
24 @param out [out] The array of octets stored (one per char)
25 @param outlen [in/out] The number of octets stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32 int t;
33
34 LTC_ARGCHK(in != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* must have header at least */
39 if (inlen < 2) {
40 return CRYPT_INVALID_PACKET;
41 }
42
43 /* check for 0x13 */
44 if ((in[0] & 0x1F) != 0x13) {
45 return CRYPT_INVALID_PACKET;
46 }
47 x = 1;
48
49 /* decode the length */
50 if (in[x] & 0x80) {
51 /* valid # of bytes in length are 1,2,3 */
52 y = in[x] & 0x7F;
53 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* read the length in */
58 len = 0;
59 ++x;
60 while (y--) {
61 len = (len << 8) | in[x++];
62 }
63 } else {
64 len = in[x++] & 0x7F;
65 }
66
67 /* is it too long? */
68 if (len > *outlen) {
69 *outlen = len;
70 return CRYPT_BUFFER_OVERFLOW;
71 }
72
73 if (len + x > inlen) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* read the data */
78 for (y = 0; y < len; y++) {
79 t = der_printable_value_decode(in[x++]);
80 if (t == -1) {
81 return CRYPT_INVALID_ARG;
82 }
83 out[y] = t;
84 }
85
86 *outlen = y;
87
88 return CRYPT_OK;
89 }
90
91 #endif
92
93 /* $Source$ */
94 /* $Revision$ */
95 /* $Date$ */
+0
-85
libtom-src/pk/asn1/der/printable_string/der_encode_printable_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_printable_string.c
14 ASN.1 DER, encode a printable STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Store an printable STRING
21 @param in The array of printable to store (one per char)
22 @param inlen The number of printable to store
23 @param out [out] The destination for the DER encoded printable STRING
24 @param outlen [in/out] The max size and resulting size of the DER printable STRING
25 @return CRYPT_OK if successful
26 */
27 int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
28 unsigned char *out, unsigned long *outlen)
29 {
30 unsigned long x, y, len;
31 int err;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* get the size */
38 if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* too big? */
43 if (len > *outlen) {
44 *outlen = len;
45 return CRYPT_BUFFER_OVERFLOW;
46 }
47
48 /* encode the header+len */
49 x = 0;
50 out[x++] = 0x13;
51 if (inlen < 128) {
52 out[x++] = (unsigned char)inlen;
53 } else if (inlen < 256) {
54 out[x++] = 0x81;
55 out[x++] = (unsigned char)inlen;
56 } else if (inlen < 65536UL) {
57 out[x++] = 0x82;
58 out[x++] = (unsigned char)((inlen>>8)&255);
59 out[x++] = (unsigned char)(inlen&255);
60 } else if (inlen < 16777216UL) {
61 out[x++] = 0x83;
62 out[x++] = (unsigned char)((inlen>>16)&255);
63 out[x++] = (unsigned char)((inlen>>8)&255);
64 out[x++] = (unsigned char)(inlen&255);
65 } else {
66 return CRYPT_INVALID_ARG;
67 }
68
69 /* store octets */
70 for (y = 0; y < inlen; y++) {
71 out[x++] = der_printable_char_encode(in[y]);
72 }
73
74 /* retun length */
75 *outlen = x;
76
77 return CRYPT_OK;
78 }
79
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
+0
-166
libtom-src/pk/asn1/der/printable_string/der_length_printable_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_printable_string.c
14 ASN.1 DER, get length of Printable STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static const struct {
20 int code, value;
21 } printable_table[] = {
22 { ' ', 32 },
23 { '\'', 39 },
24 { '(', 40 },
25 { ')', 41 },
26 { '+', 43 },
27 { ',', 44 },
28 { '-', 45 },
29 { '.', 46 },
30 { '/', 47 },
31 { '0', 48 },
32 { '1', 49 },
33 { '2', 50 },
34 { '3', 51 },
35 { '4', 52 },
36 { '5', 53 },
37 { '6', 54 },
38 { '7', 55 },
39 { '8', 56 },
40 { '9', 57 },
41 { ':', 58 },
42 { '=', 61 },
43 { '?', 63 },
44 { 'A', 65 },
45 { 'B', 66 },
46 { 'C', 67 },
47 { 'D', 68 },
48 { 'E', 69 },
49 { 'F', 70 },
50 { 'G', 71 },
51 { 'H', 72 },
52 { 'I', 73 },
53 { 'J', 74 },
54 { 'K', 75 },
55 { 'L', 76 },
56 { 'M', 77 },
57 { 'N', 78 },
58 { 'O', 79 },
59 { 'P', 80 },
60 { 'Q', 81 },
61 { 'R', 82 },
62 { 'S', 83 },
63 { 'T', 84 },
64 { 'U', 85 },
65 { 'V', 86 },
66 { 'W', 87 },
67 { 'X', 88 },
68 { 'Y', 89 },
69 { 'Z', 90 },
70 { 'a', 97 },
71 { 'b', 98 },
72 { 'c', 99 },
73 { 'd', 100 },
74 { 'e', 101 },
75 { 'f', 102 },
76 { 'g', 103 },
77 { 'h', 104 },
78 { 'i', 105 },
79 { 'j', 106 },
80 { 'k', 107 },
81 { 'l', 108 },
82 { 'm', 109 },
83 { 'n', 110 },
84 { 'o', 111 },
85 { 'p', 112 },
86 { 'q', 113 },
87 { 'r', 114 },
88 { 's', 115 },
89 { 't', 116 },
90 { 'u', 117 },
91 { 'v', 118 },
92 { 'w', 119 },
93 { 'x', 120 },
94 { 'y', 121 },
95 { 'z', 122 },
96 };
97
98 int der_printable_char_encode(int c)
99 {
100 int x;
101 for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
102 if (printable_table[x].code == c) {
103 return printable_table[x].value;
104 }
105 }
106 return -1;
107 }
108
109 int der_printable_value_decode(int v)
110 {
111 int x;
112 for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
113 if (printable_table[x].value == v) {
114 return printable_table[x].code;
115 }
116 }
117 return -1;
118 }
119
120 /**
121 Gets length of DER encoding of Printable STRING
122 @param octets The values you want to encode
123 @param noctets The number of octets in the string to encode
124 @param outlen [out] The length of the DER encoding for the given string
125 @return CRYPT_OK if successful
126 */
127 int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
128 {
129 unsigned long x;
130
131 LTC_ARGCHK(outlen != NULL);
132 LTC_ARGCHK(octets != NULL);
133
134 /* scan string for validity */
135 for (x = 0; x < noctets; x++) {
136 if (der_printable_char_encode(octets[x]) == -1) {
137 return CRYPT_INVALID_ARG;
138 }
139 }
140
141 if (noctets < 128) {
142 /* 16 LL DD DD DD ... */
143 *outlen = 2 + noctets;
144 } else if (noctets < 256) {
145 /* 16 81 LL DD DD DD ... */
146 *outlen = 3 + noctets;
147 } else if (noctets < 65536UL) {
148 /* 16 82 LL LL DD DD DD ... */
149 *outlen = 4 + noctets;
150 } else if (noctets < 16777216UL) {
151 /* 16 83 LL LL LL DD DD DD ... */
152 *outlen = 5 + noctets;
153 } else {
154 return CRYPT_INVALID_ARG;
155 }
156
157 return CRYPT_OK;
158 }
159
160 #endif
161
162
163 /* $Source$ */
164 /* $Revision$ */
165 /* $Date$ */
+0
-299
libtom-src/pk/asn1/der/sequence/der_decode_sequence_ex.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13
14 /**
15 @file der_decode_sequence_ex.c
16 ASN.1 DER, decode a SEQUENCE, Tom St Denis
17 */
18
19 #ifdef LTC_DER
20
21 /**
22 Decode a SEQUENCE
23 @param in The DER encoded input
24 @param inlen The size of the input
25 @param list The list of items to decode
26 @param outlen The number of items in the list
27 @param ordered Search an unordeded or ordered list
28 @return CRYPT_OK on success
29 */
30 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
31 ltc_asn1_list *list, unsigned long outlen, int ordered)
32 {
33 int err, type, i;
34 unsigned long size, x, y, z, blksize;
35 void *data;
36
37 LTC_ARGCHK(in != NULL);
38 LTC_ARGCHK(list != NULL);
39
40 /* get blk size */
41 if (inlen < 2) {
42 return CRYPT_INVALID_PACKET;
43 }
44
45 /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
46 x = 0;
47 if (in[x] != 0x30 && in[x] != 0x31) {
48 return CRYPT_INVALID_PACKET;
49 }
50 ++x;
51
52 if (in[x] < 128) {
53 blksize = in[x++];
54 } else if (in[x] & 0x80) {
55 if (in[x] < 0x81 || in[x] > 0x83) {
56 return CRYPT_INVALID_PACKET;
57 }
58 y = in[x++] & 0x7F;
59
60 /* would reading the len bytes overrun? */
61 if (x + y > inlen) {
62 return CRYPT_INVALID_PACKET;
63 }
64
65 /* read len */
66 blksize = 0;
67 while (y--) {
68 blksize = (blksize << 8) | (unsigned long)in[x++];
69 }
70 }
71
72 /* would this blksize overflow? */
73 if (x + blksize > inlen) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* mark all as unused */
78 for (i = 0; i < (int)outlen; i++) {
79 list[i].used = 0;
80 }
81
82 /* ok read data */
83 inlen = blksize;
84 for (i = 0; i < (int)outlen; i++) {
85 z = 0;
86 type = list[i].type;
87 size = list[i].size;
88 data = list[i].data;
89 if (!ordered && list[i].used == 1) { continue; }
90
91 if (type == LTC_ASN1_EOL) {
92 break;
93 }
94
95 switch (type) {
96 case LTC_ASN1_BOOLEAN:
97 z = inlen;
98 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
99 goto LBL_ERR;
100 }
101 if ((err = der_length_boolean(&z)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104 break;
105
106 case LTC_ASN1_INTEGER:
107 z = inlen;
108 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
109 if (!ordered) { continue; }
110 goto LBL_ERR;
111 }
112 if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
113 goto LBL_ERR;
114 }
115 break;
116
117 case LTC_ASN1_SHORT_INTEGER:
118 z = inlen;
119 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
120 if (!ordered) { continue; }
121 goto LBL_ERR;
122 }
123 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
124 goto LBL_ERR;
125 }
126
127 break;
128
129 case LTC_ASN1_BIT_STRING:
130 z = inlen;
131 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
132 if (!ordered) { continue; }
133 goto LBL_ERR;
134 }
135 list[i].size = size;
136 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
137 goto LBL_ERR;
138 }
139 break;
140
141 case LTC_ASN1_RAW_BIT_STRING:
142 z = inlen;
143 if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
144 if (!ordered) { continue; }
145 goto LBL_ERR;
146 }
147 list[i].size = size;
148 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
149 goto LBL_ERR;
150 }
151 break;
152
153 case LTC_ASN1_OCTET_STRING:
154 z = inlen;
155 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
156 if (!ordered) { continue; }
157 goto LBL_ERR;
158 }
159 list[i].size = size;
160 if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
161 goto LBL_ERR;
162 }
163 break;
164
165 case LTC_ASN1_NULL:
166 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
167 if (!ordered) { continue; }
168 err = CRYPT_INVALID_PACKET;
169 goto LBL_ERR;
170 }
171 z = 2;
172 break;
173
174 case LTC_ASN1_OBJECT_IDENTIFIER:
175 z = inlen;
176 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
177 if (!ordered) { continue; }
178 goto LBL_ERR;
179 }
180 list[i].size = size;
181 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
182 goto LBL_ERR;
183 }
184 break;
185
186 case LTC_ASN1_IA5_STRING:
187 z = inlen;
188 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
189 if (!ordered) { continue; }
190 goto LBL_ERR;
191 }
192 list[i].size = size;
193 if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
194 goto LBL_ERR;
195 }
196 break;
197
198
199 case LTC_ASN1_PRINTABLE_STRING:
200 z = inlen;
201 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
202 if (!ordered) { continue; }
203 goto LBL_ERR;
204 }
205 list[i].size = size;
206 if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
207 goto LBL_ERR;
208 }
209 break;
210
211 case LTC_ASN1_UTF8_STRING:
212 z = inlen;
213 if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
214 if (!ordered) { continue; }
215 goto LBL_ERR;
216 }
217 list[i].size = size;
218 if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
219 goto LBL_ERR;
220 }
221 break;
222
223 case LTC_ASN1_UTCTIME:
224 z = inlen;
225 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
226 if (!ordered) { continue; }
227 goto LBL_ERR;
228 }
229 break;
230
231 case LTC_ASN1_SET:
232 z = inlen;
233 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
234 if (!ordered) { continue; }
235 goto LBL_ERR;
236 }
237 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
238 goto LBL_ERR;
239 }
240 break;
241
242 case LTC_ASN1_SETOF:
243 case LTC_ASN1_SEQUENCE:
244 /* detect if we have the right type */
245 if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) {
246 err = CRYPT_INVALID_PACKET;
247 goto LBL_ERR;
248 }
249
250 z = inlen;
251 if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
252 if (!ordered) { continue; }
253 goto LBL_ERR;
254 }
255 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
256 goto LBL_ERR;
257 }
258 break;
259
260
261 case LTC_ASN1_CHOICE:
262 z = inlen;
263 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
264 if (!ordered) { continue; }
265 goto LBL_ERR;
266 }
267 break;
268
269 default:
270 err = CRYPT_INVALID_ARG;
271 goto LBL_ERR;
272 }
273 x += z;
274 inlen -= z;
275 list[i].used = 1;
276 if (!ordered) {
277 /* restart the decoder */
278 i = -1;
279 }
280 }
281
282 for (i = 0; i < (int)outlen; i++) {
283 if (list[i].used == 0) {
284 err = CRYPT_INVALID_PACKET;
285 goto LBL_ERR;
286 }
287 }
288 err = CRYPT_OK;
289
290 LBL_ERR:
291 return err;
292 }
293
294 #endif
295
296 /* $Source$ */
297 /* $Revision$ */
298 /* $Date$ */
+0
-416
libtom-src/pk/asn1/der/sequence/der_decode_sequence_flexi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_sequence_flexi.c
14 ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static unsigned long fetch_length(const unsigned char *in, unsigned long inlen)
20 {
21 unsigned long x, y, z;
22
23 y = 0;
24
25 /* skip type and read len */
26 if (inlen < 2) {
27 return 0xFFFFFFFF;
28 }
29 ++in; ++y;
30
31 /* read len */
32 x = *in++; ++y;
33
34 /* <128 means literal */
35 if (x < 128) {
36 return x+y;
37 }
38 x &= 0x7F; /* the lower 7 bits are the length of the length */
39 inlen -= 2;
40
41 /* len means len of len! */
42 if (x == 0 || x > 4 || x > inlen) {
43 return 0xFFFFFFFF;
44 }
45
46 y += x;
47 z = 0;
48 while (x--) {
49 z = (z<<8) | ((unsigned long)*in);
50 ++in;
51 }
52 return z+y;
53 }
54
55 /**
56 ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
57 @param in The input buffer
58 @param inlen [in/out] The length of the input buffer and on output the amount of decoded data
59 @param out [out] A pointer to the linked list
60 @return CRYPT_OK on success.
61 */
62 int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
63 {
64 ltc_asn1_list *l;
65 unsigned long err, type, len, totlen, x, y;
66 void *realloc_tmp;
67 int isConstructed;
68
69 LTC_ARGCHK(in != NULL);
70 LTC_ARGCHK(inlen != NULL);
71 LTC_ARGCHK(out != NULL);
72
73 l = NULL;
74 totlen = 0;
75
76 /* scan the input and and get lengths and what not */
77 while (*inlen) {
78 /* read the type byte */
79 type = *in;
80
81 /* fetch length */
82 len = fetch_length(in, *inlen);
83 if (len > *inlen) {
84 err = CRYPT_INVALID_PACKET;
85 goto error;
86 }
87
88 /* alloc new link */
89 if (l == NULL) {
90 l = XCALLOC(1, sizeof(*l));
91 if (l == NULL) {
92 err = CRYPT_MEM;
93 goto error;
94 }
95 } else {
96 l->next = XCALLOC(1, sizeof(*l));
97 if (l->next == NULL) {
98 err = CRYPT_MEM;
99 goto error;
100 }
101 l->next->prev = l;
102 l = l->next;
103 }
104
105 if ((isConstructed = ((type & 0xE0) == 0xA0 ? 1 : 0))) {
106 /* constructed, use the 'used' field to store the original tag number */
107 l->used = (type & 0x1F);
108 /* treat constructed elements like SETs */
109 type = 0x31;
110 }
111
112 /* now switch on type */
113 switch (type) {
114 case 0x01: /* BOOLEAN */
115 l->type = LTC_ASN1_BOOLEAN;
116 l->size = 1;
117 l->data = XCALLOC(1, sizeof(int));
118
119 if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) {
120 goto error;
121 }
122
123 if ((err = der_length_boolean(&len)) != CRYPT_OK) {
124 goto error;
125 }
126 break;
127
128 case 0x02: /* INTEGER */
129 /* init field */
130 l->type = LTC_ASN1_INTEGER;
131 l->size = 1;
132 if ((err = mp_init(&l->data)) != CRYPT_OK) {
133 goto error;
134 }
135
136 /* decode field */
137 if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) {
138 goto error;
139 }
140
141 /* calc length of object */
142 if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) {
143 goto error;
144 }
145 break;
146
147 case 0x03: /* BIT */
148 /* init field */
149 l->type = LTC_ASN1_BIT_STRING;
150 l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */
151
152 if ((l->data = XCALLOC(1, l->size)) == NULL) {
153 err = CRYPT_MEM;
154 goto error;
155 }
156
157 if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
158 goto error;
159 }
160
161 if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) {
162 goto error;
163 }
164 break;
165
166 case 0x04: /* OCTET */
167
168 /* init field */
169 l->type = LTC_ASN1_OCTET_STRING;
170 l->size = len;
171
172 if ((l->data = XCALLOC(1, l->size)) == NULL) {
173 err = CRYPT_MEM;
174 goto error;
175 }
176
177 if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
178 goto error;
179 }
180
181 if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) {
182 goto error;
183 }
184 break;
185
186 case 0x05: /* NULL */
187
188 /* valid NULL is 0x05 0x00 */
189 if (in[0] != 0x05 || in[1] != 0x00) {
190 err = CRYPT_INVALID_PACKET;
191 goto error;
192 }
193
194 /* simple to store ;-) */
195 l->type = LTC_ASN1_NULL;
196 l->data = NULL;
197 l->size = 0;
198 len = 2;
199
200 break;
201
202 case 0x06: /* OID */
203
204 /* init field */
205 l->type = LTC_ASN1_OBJECT_IDENTIFIER;
206 l->size = len;
207
208 if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) {
209 err = CRYPT_MEM;
210 goto error;
211 }
212
213 if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
214 goto error;
215 }
216
217 if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) {
218 goto error;
219 }
220
221 /* resize it to save a bunch of mem */
222 if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) {
223 /* out of heap but this is not an error */
224 break;
225 }
226 l->data = realloc_tmp;
227 break;
228
229 case 0x0C: /* UTF8 */
230
231 /* init field */
232 l->type = LTC_ASN1_UTF8_STRING;
233 l->size = len;
234
235 if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) {
236 err = CRYPT_MEM;
237 goto error;
238 }
239
240 if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
241 goto error;
242 }
243
244 if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) {
245 goto error;
246 }
247 break;
248
249 case 0x13: /* PRINTABLE */
250
251 /* init field */
252 l->type = LTC_ASN1_PRINTABLE_STRING;
253 l->size = len;
254
255 if ((l->data = XCALLOC(1, l->size)) == NULL) {
256 err = CRYPT_MEM;
257 goto error;
258 }
259
260 if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
261 goto error;
262 }
263
264 if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) {
265 goto error;
266 }
267 break;
268
269 case 0x14: /* TELETEXT */
270
271 /* init field */
272 l->type = LTC_ASN1_TELETEX_STRING;
273 l->size = len;
274
275 if ((l->data = XCALLOC(1, l->size)) == NULL) {
276 err = CRYPT_MEM;
277 goto error;
278 }
279
280 if ((err = der_decode_teletex_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
281 goto error;
282 }
283
284 if ((err = der_length_teletex_string(l->data, l->size, &len)) != CRYPT_OK) {
285 goto error;
286 }
287 break;
288
289 case 0x16: /* IA5 */
290
291 /* init field */
292 l->type = LTC_ASN1_IA5_STRING;
293 l->size = len;
294
295 if ((l->data = XCALLOC(1, l->size)) == NULL) {
296 err = CRYPT_MEM;
297 goto error;
298 }
299
300 if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
301 goto error;
302 }
303
304 if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) {
305 goto error;
306 }
307 break;
308
309 case 0x17: /* UTC TIME */
310
311 /* init field */
312 l->type = LTC_ASN1_UTCTIME;
313 l->size = 1;
314
315 if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) {
316 err = CRYPT_MEM;
317 goto error;
318 }
319
320 len = *inlen;
321 if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) {
322 goto error;
323 }
324
325 if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) {
326 goto error;
327 }
328 break;
329
330 case 0x30: /* SEQUENCE */
331 case 0x31: /* SET */
332
333 /* init field */
334 l->type = (isConstructed ? LTC_ASN1_CONSTRUCTED : ((type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET));
335
336 /* we have to decode the SEQUENCE header and get it's length */
337
338 /* move past type */
339 ++in; --(*inlen);
340
341 /* read length byte */
342 x = *in++; --(*inlen);
343
344 /* smallest SEQUENCE/SET header */
345 y = 2;
346
347 /* now if it's > 127 the next bytes are the length of the length */
348 if (x > 128) {
349 x &= 0x7F;
350 in += x;
351 *inlen -= x;
352
353 /* update sequence header len */
354 y += x;
355 }
356
357 /* Sequence elements go as child */
358 len = len - y;
359 if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) {
360 goto error;
361 }
362
363 /* len update */
364 totlen += y;
365
366 /* link them up y0 */
367 l->child->parent = l;
368
369 break;
370 default:
371 /* invalid byte ... this is a soft error */
372 /* remove link */
373 if (l->prev) {
374 l = l->prev;
375 XFREE(l->next);
376 l->next = NULL;
377 }
378 goto outside;
379 }
380
381 /* advance pointers */
382 totlen += len;
383 in += len;
384 *inlen -= len;
385 }
386
387 outside:
388
389 /* rewind l please */
390 while (l->prev != NULL || l->parent != NULL) {
391 if (l->parent != NULL) {
392 l = l->parent;
393 } else {
394 l = l->prev;
395 }
396 }
397
398 /* return */
399 *out = l;
400 *inlen = totlen;
401 return CRYPT_OK;
402
403 error:
404 /* free list */
405 der_sequence_free(l);
406
407 return err;
408 }
409
410 #endif
411
412
413 /* $Source$ */
414 /* $Revision$ */
415 /* $Date$ */
+0
-139
libtom-src/pk/asn1/der/sequence/der_decode_sequence_multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13
14 /**
15 @file der_decode_sequence_multi.c
16 ASN.1 DER, decode a SEQUENCE, Tom St Denis
17 */
18
19 #ifdef LTC_DER
20
21 /**
22 Decode a SEQUENCE type using a VA list
23 @param in Input buffer
24 @param inlen Length of input in octets
25 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
26 @return CRYPT_OK on success
27 */
28 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
29 {
30 int err, type;
31 unsigned long size, x;
32 void *data;
33 va_list args;
34 ltc_asn1_list *list;
35
36 LTC_ARGCHK(in != NULL);
37
38 /* get size of output that will be required */
39 va_start(args, inlen);
40 x = 0;
41 for (;;) {
42 type = va_arg(args, int);
43 size = va_arg(args, unsigned long);
44 data = va_arg(args, void*);
45
46 if (type == LTC_ASN1_EOL) {
47 break;
48 }
49
50 switch (type) {
51 case LTC_ASN1_BOOLEAN:
52 case LTC_ASN1_INTEGER:
53 case LTC_ASN1_SHORT_INTEGER:
54 case LTC_ASN1_BIT_STRING:
55 case LTC_ASN1_OCTET_STRING:
56 case LTC_ASN1_NULL:
57 case LTC_ASN1_OBJECT_IDENTIFIER:
58 case LTC_ASN1_IA5_STRING:
59 case LTC_ASN1_PRINTABLE_STRING:
60 case LTC_ASN1_UTF8_STRING:
61 case LTC_ASN1_UTCTIME:
62 case LTC_ASN1_SET:
63 case LTC_ASN1_SETOF:
64 case LTC_ASN1_SEQUENCE:
65 case LTC_ASN1_CHOICE:
66 ++x;
67 break;
68
69 default:
70 va_end(args);
71 return CRYPT_INVALID_ARG;
72 }
73 }
74 va_end(args);
75
76 /* allocate structure for x elements */
77 if (x == 0) {
78 return CRYPT_NOP;
79 }
80
81 list = XCALLOC(sizeof(*list), x);
82 if (list == NULL) {
83 return CRYPT_MEM;
84 }
85
86 /* fill in the structure */
87 va_start(args, inlen);
88 x = 0;
89 for (;;) {
90 type = va_arg(args, int);
91 size = va_arg(args, unsigned long);
92 data = va_arg(args, void*);
93
94 if (type == LTC_ASN1_EOL) {
95 break;
96 }
97
98 switch (type) {
99 case LTC_ASN1_BOOLEAN:
100 case LTC_ASN1_INTEGER:
101 case LTC_ASN1_SHORT_INTEGER:
102 case LTC_ASN1_BIT_STRING:
103 case LTC_ASN1_OCTET_STRING:
104 case LTC_ASN1_NULL:
105 case LTC_ASN1_OBJECT_IDENTIFIER:
106 case LTC_ASN1_IA5_STRING:
107 case LTC_ASN1_PRINTABLE_STRING:
108 case LTC_ASN1_UTF8_STRING:
109 case LTC_ASN1_UTCTIME:
110 case LTC_ASN1_SEQUENCE:
111 case LTC_ASN1_SET:
112 case LTC_ASN1_SETOF:
113 case LTC_ASN1_CHOICE:
114 list[x].type = type;
115 list[x].size = size;
116 list[x++].data = data;
117 break;
118
119 default:
120 va_end(args);
121 err = CRYPT_INVALID_ARG;
122 goto LBL_ERR;
123 }
124 }
125 va_end(args);
126
127 err = der_decode_sequence(in, inlen, list, x);
128 LBL_ERR:
129 XFREE(list);
130 return err;
131 }
132
133 #endif
134
135
136 /* $Source$ */
137 /* $Revision$ */
138 /* $Date$ */
+0
-96
libtom-src/pk/asn1/der/sequence/der_decode_subject_public_key_info.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9 #include "tomcrypt.h"
10 /**
11 @file der_encode_sequence_multi.c
12 ASN.1 DER, encode a Subject Public Key structure --nmav
13 */
14
15 #ifdef LTC_DER
16
17 /* AlgorithmIdentifier := SEQUENCE {
18 * algorithm OBJECT IDENTIFIER,
19 * parameters ANY DEFINED BY algorithm
20 * }
21 *
22 * SubjectPublicKeyInfo := SEQUENCE {
23 * algorithm AlgorithmIdentifier,
24 * subjectPublicKey BIT STRING
25 * }
26 */
27 /**
28 Encode a SEQUENCE type using a VA list
29 @param out [out] Destination for data
30 @param outlen [in/out] Length of buffer and resulting length of output
31 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
32 @return CRYPT_OK on success
33 */
34 int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
35 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
36 unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len)
37 {
38 int err;
39 unsigned long len;
40 oid_st oid;
41 unsigned char *tmpbuf;
42 unsigned long tmpoid[16];
43 ltc_asn1_list alg_id[2];
44 ltc_asn1_list subject_pubkey[2];
45
46 LTC_ARGCHK(in != NULL);
47 LTC_ARGCHK(inlen != 0);
48
49 err = pk_get_oid(algorithm, &oid);
50 if (err != CRYPT_OK) {
51 return err;
52 }
53
54 /* see if the OpenSSL DER format RSA public key will work */
55 tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8);
56 if (tmpbuf == NULL) {
57 err = CRYPT_MEM;
58 goto LBL_ERR;
59 }
60
61 /* this includes the internal hash ID and optional params (NULL in this case) */
62 LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
63 LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len);
64
65 /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it
66 then proceed to convert bit to octet
67 */
68 LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2);
69 LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8);
70
71 err=der_decode_sequence(in, inlen, subject_pubkey, 2UL);
72 if (err != CRYPT_OK) {
73 goto LBL_ERR;
74 }
75
76 len = subject_pubkey[1].size/8;
77 if (*public_key_len > len) {
78 memcpy(public_key, subject_pubkey[1].data, len);
79 *public_key_len = len;
80 } else {
81 *public_key_len = len;
82 err = CRYPT_BUFFER_OVERFLOW;
83 goto LBL_ERR;
84 }
85
86 err = CRYPT_OK;
87
88 LBL_ERR:
89
90 XFREE(tmpbuf);
91
92 return err;
93 }
94
95 #endif
+0
-345
libtom-src/pk/asn1/der/sequence/der_encode_sequence_ex.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13
14 /**
15 @file der_encode_sequence_ex.c
16 ASN.1 DER, encode a SEQUENCE, Tom St Denis
17 */
18
19 #ifdef LTC_DER
20
21 /**
22 Encode a SEQUENCE
23 @param list The list of items to encode
24 @param inlen The number of items in the list
25 @param out [out] The destination
26 @param outlen [in/out] The size of the output
27 @param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF
28 @return CRYPT_OK on success
29 */
30 int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
31 unsigned char *out, unsigned long *outlen, int type_of)
32 {
33 int err, type;
34 unsigned long size, x, y, z, i;
35 void *data;
36
37 LTC_ARGCHK(list != NULL);
38 LTC_ARGCHK(out != NULL);
39 LTC_ARGCHK(outlen != NULL);
40
41 /* get size of output that will be required */
42 y = 0;
43 for (i = 0; i < inlen; i++) {
44 type = list[i].type;
45 size = list[i].size;
46 data = list[i].data;
47
48 if (type == LTC_ASN1_EOL) {
49 break;
50 }
51
52 switch (type) {
53 case LTC_ASN1_BOOLEAN:
54 if ((err = der_length_boolean(&x)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57 y += x;
58 break;
59
60 case LTC_ASN1_INTEGER:
61 if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
62 goto LBL_ERR;
63 }
64 y += x;
65 break;
66
67 case LTC_ASN1_SHORT_INTEGER:
68 if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) {
69 goto LBL_ERR;
70 }
71 y += x;
72 break;
73
74 case LTC_ASN1_BIT_STRING:
75 case LTC_ASN1_RAW_BIT_STRING:
76 if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79 y += x;
80 break;
81
82 case LTC_ASN1_OCTET_STRING:
83 if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
84 goto LBL_ERR;
85 }
86 y += x;
87 break;
88
89 case LTC_ASN1_NULL:
90 y += 2;
91 break;
92
93 case LTC_ASN1_OBJECT_IDENTIFIER:
94 if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
95 goto LBL_ERR;
96 }
97 y += x;
98 break;
99
100 case LTC_ASN1_IA5_STRING:
101 if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104 y += x;
105 break;
106
107 case LTC_ASN1_PRINTABLE_STRING:
108 if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
109 goto LBL_ERR;
110 }
111 y += x;
112 break;
113
114 case LTC_ASN1_UTF8_STRING:
115 if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
116 goto LBL_ERR;
117 }
118 y += x;
119 break;
120
121 case LTC_ASN1_UTCTIME:
122 if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
123 goto LBL_ERR;
124 }
125 y += x;
126 break;
127
128 case LTC_ASN1_SET:
129 case LTC_ASN1_SETOF:
130 case LTC_ASN1_SEQUENCE:
131 if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
132 goto LBL_ERR;
133 }
134 y += x;
135 break;
136
137 default:
138 err = CRYPT_INVALID_ARG;
139 goto LBL_ERR;
140 }
141 }
142
143 /* calc header size */
144 z = y;
145 if (y < 128) {
146 y += 2;
147 } else if (y < 256) {
148 /* 0x30 0x81 LL */
149 y += 3;
150 } else if (y < 65536UL) {
151 /* 0x30 0x82 LL LL */
152 y += 4;
153 } else if (y < 16777216UL) {
154 /* 0x30 0x83 LL LL LL */
155 y += 5;
156 } else {
157 err = CRYPT_INVALID_ARG;
158 goto LBL_ERR;
159 }
160
161 /* too big ? */
162 if (*outlen < y) {
163 *outlen = y;
164 err = CRYPT_BUFFER_OVERFLOW;
165 goto LBL_ERR;
166 }
167
168 /* store header */
169 x = 0;
170 out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
171
172 if (z < 128) {
173 out[x++] = (unsigned char)z;
174 } else if (z < 256) {
175 out[x++] = 0x81;
176 out[x++] = (unsigned char)z;
177 } else if (z < 65536UL) {
178 out[x++] = 0x82;
179 out[x++] = (unsigned char)((z>>8UL)&255);
180 out[x++] = (unsigned char)(z&255);
181 } else if (z < 16777216UL) {
182 out[x++] = 0x83;
183 out[x++] = (unsigned char)((z>>16UL)&255);
184 out[x++] = (unsigned char)((z>>8UL)&255);
185 out[x++] = (unsigned char)(z&255);
186 }
187
188 /* store data */
189 *outlen -= x;
190 for (i = 0; i < inlen; i++) {
191 type = list[i].type;
192 size = list[i].size;
193 data = list[i].data;
194
195 if (type == LTC_ASN1_EOL) {
196 break;
197 }
198
199 switch (type) {
200 case LTC_ASN1_BOOLEAN:
201 z = *outlen;
202 if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
203 goto LBL_ERR;
204 }
205 x += z;
206 *outlen -= z;
207 break;
208
209 case LTC_ASN1_INTEGER:
210 z = *outlen;
211 if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
212 goto LBL_ERR;
213 }
214 x += z;
215 *outlen -= z;
216 break;
217
218 case LTC_ASN1_SHORT_INTEGER:
219 z = *outlen;
220 if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
221 goto LBL_ERR;
222 }
223 x += z;
224 *outlen -= z;
225 break;
226
227 case LTC_ASN1_BIT_STRING:
228 z = *outlen;
229 if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
230 goto LBL_ERR;
231 }
232 x += z;
233 *outlen -= z;
234 break;
235
236 case LTC_ASN1_RAW_BIT_STRING:
237 z = *outlen;
238 if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
239 goto LBL_ERR;
240 }
241 x += z;
242 *outlen -= z;
243 break;
244
245 case LTC_ASN1_OCTET_STRING:
246 z = *outlen;
247 if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
248 goto LBL_ERR;
249 }
250 x += z;
251 *outlen -= z;
252 break;
253
254 case LTC_ASN1_NULL:
255 out[x++] = 0x05;
256 out[x++] = 0x00;
257 *outlen -= 2;
258 break;
259
260 case LTC_ASN1_OBJECT_IDENTIFIER:
261 z = *outlen;
262 if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
263 goto LBL_ERR;
264 }
265 x += z;
266 *outlen -= z;
267 break;
268
269 case LTC_ASN1_IA5_STRING:
270 z = *outlen;
271 if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
272 goto LBL_ERR;
273 }
274 x += z;
275 *outlen -= z;
276 break;
277
278 case LTC_ASN1_PRINTABLE_STRING:
279 z = *outlen;
280 if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
281 goto LBL_ERR;
282 }
283 x += z;
284 *outlen -= z;
285 break;
286
287 case LTC_ASN1_UTF8_STRING:
288 z = *outlen;
289 if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
290 goto LBL_ERR;
291 }
292 x += z;
293 *outlen -= z;
294 break;
295
296 case LTC_ASN1_UTCTIME:
297 z = *outlen;
298 if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
299 goto LBL_ERR;
300 }
301 x += z;
302 *outlen -= z;
303 break;
304
305 case LTC_ASN1_SET:
306 z = *outlen;
307 if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
308 goto LBL_ERR;
309 }
310 x += z;
311 *outlen -= z;
312 break;
313
314 case LTC_ASN1_SETOF:
315 z = *outlen;
316 if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
317 goto LBL_ERR;
318 }
319 x += z;
320 *outlen -= z;
321 break;
322
323 case LTC_ASN1_SEQUENCE:
324 z = *outlen;
325 if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
326 goto LBL_ERR;
327 }
328 x += z;
329 *outlen -= z;
330 break;
331
332 default:
333 err = CRYPT_INVALID_ARG;
334 goto LBL_ERR;
335 }
336 }
337 *outlen = x;
338 err = CRYPT_OK;
339
340 LBL_ERR:
341 return err;
342 }
343
344 #endif
+0
-140
libtom-src/pk/asn1/der/sequence/der_encode_sequence_multi.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13
14 /**
15 @file der_encode_sequence_multi.c
16 ASN.1 DER, encode a SEQUENCE, Tom St Denis
17 */
18
19 #ifdef LTC_DER
20
21 /**
22 Encode a SEQUENCE type using a VA list
23 @param out [out] Destination for data
24 @param outlen [in/out] Length of buffer and resulting length of output
25 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
26 @return CRYPT_OK on success
27 */
28 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
29 {
30 int err, type;
31 unsigned long size, x;
32 void *data;
33 va_list args;
34 ltc_asn1_list *list;
35
36 LTC_ARGCHK(out != NULL);
37 LTC_ARGCHK(outlen != NULL);
38
39 /* get size of output that will be required */
40 va_start(args, outlen);
41 x = 0;
42 for (;;) {
43 type = va_arg(args, int);
44 size = va_arg(args, unsigned long);
45 data = va_arg(args, void*);
46
47 if (type == LTC_ASN1_EOL) {
48 break;
49 }
50
51 switch (type) {
52 case LTC_ASN1_BOOLEAN:
53 case LTC_ASN1_INTEGER:
54 case LTC_ASN1_SHORT_INTEGER:
55 case LTC_ASN1_BIT_STRING:
56 case LTC_ASN1_OCTET_STRING:
57 case LTC_ASN1_NULL:
58 case LTC_ASN1_OBJECT_IDENTIFIER:
59 case LTC_ASN1_IA5_STRING:
60 case LTC_ASN1_PRINTABLE_STRING:
61 case LTC_ASN1_UTF8_STRING:
62 case LTC_ASN1_UTCTIME:
63 case LTC_ASN1_SEQUENCE:
64 case LTC_ASN1_SET:
65 case LTC_ASN1_SETOF:
66 case LTC_ASN1_RAW_BIT_STRING:
67 ++x;
68 break;
69
70 default:
71 va_end(args);
72 return CRYPT_INVALID_ARG;
73 }
74 }
75 va_end(args);
76
77 /* allocate structure for x elements */
78 if (x == 0) {
79 return CRYPT_NOP;
80 }
81
82 list = XCALLOC(sizeof(*list), x);
83 if (list == NULL) {
84 return CRYPT_MEM;
85 }
86
87 /* fill in the structure */
88 va_start(args, outlen);
89 x = 0;
90 for (;;) {
91 type = va_arg(args, int);
92 size = va_arg(args, unsigned long);
93 data = va_arg(args, void*);
94
95 if (type == LTC_ASN1_EOL) {
96 break;
97 }
98
99 switch (type) {
100 case LTC_ASN1_BOOLEAN:
101 case LTC_ASN1_INTEGER:
102 case LTC_ASN1_SHORT_INTEGER:
103 case LTC_ASN1_BIT_STRING:
104 case LTC_ASN1_OCTET_STRING:
105 case LTC_ASN1_NULL:
106 case LTC_ASN1_OBJECT_IDENTIFIER:
107 case LTC_ASN1_IA5_STRING:
108 case LTC_ASN1_PRINTABLE_STRING:
109 case LTC_ASN1_UTF8_STRING:
110 case LTC_ASN1_UTCTIME:
111 case LTC_ASN1_SEQUENCE:
112 case LTC_ASN1_SET:
113 case LTC_ASN1_SETOF:
114 case LTC_ASN1_RAW_BIT_STRING:
115 list[x].type = type;
116 list[x].size = size;
117 list[x++].data = data;
118 break;
119
120 default:
121 va_end(args);
122 err = CRYPT_INVALID_ARG;
123 goto LBL_ERR;
124 }
125 }
126 va_end(args);
127
128 err = der_encode_sequence(list, x, out, outlen);
129 LBL_ERR:
130 XFREE(list);
131 return err;
132 }
133
134 #endif
135
136
137 /* $Source$ */
138 /* $Revision$ */
139 /* $Date$ */
+0
-69
libtom-src/pk/asn1/der/sequence/der_encode_subject_public_key_info.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9 #include "tomcrypt.h"
10
11 /**
12 @file der_encode_sequence_multi.c
13 ASN.1 DER, encode a Subject Public Key structure --nmav
14 */
15
16 #ifdef LTC_DER
17
18 /* AlgorithmIdentifier := SEQUENCE {
19 * algorithm OBJECT IDENTIFIER,
20 * parameters ANY DEFINED BY algorithm
21 * }
22 *
23 * SubjectPublicKeyInfo := SEQUENCE {
24 * algorithm AlgorithmIdentifier,
25 * subjectPublicKey BIT STRING
26 * }
27 */
28 /**
29 Encode a SEQUENCE type using a VA list
30 @param out [out] Destination for data
31 @param outlen [in/out] Length of buffer and resulting length of output
32 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
33 @return CRYPT_OK on success
34 */
35 int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
36 unsigned int algorithm, void* public_key, unsigned long public_key_len,
37 unsigned long parameters_type, void* parameters, unsigned long parameters_len)
38 {
39 int err;
40 ltc_asn1_list alg_id[2];
41 oid_st oid;
42
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45
46 err = pk_get_oid(algorithm, &oid);
47 if (err != CRYPT_OK) {
48 return err;
49 }
50
51 alg_id[0].data = oid.OID;
52 alg_id[0].size = oid.OIDlen;
53 alg_id[0].type = LTC_ASN1_OBJECT_IDENTIFIER;
54
55 alg_id[1].data = parameters;
56 alg_id[1].size = parameters_len;
57 alg_id[1].type = parameters_type;
58
59 return der_encode_sequence_multi(out, outlen,
60 LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
61 LTC_ASN1_RAW_BIT_STRING, (unsigned long)(public_key_len*8), public_key,
62 LTC_ASN1_EOL, 0UL, NULL);
63
64 }
65
66 #endif
67
68
+0
-168
libtom-src/pk/asn1/der/sequence/der_length_sequence.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_sequence.c
14 ASN.1 DER, length a SEQUENCE, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Get the length of a DER sequence
21 @param list The sequences of items in the SEQUENCE
22 @param inlen The number of items
23 @param outlen [out] The length required in octets to store it
24 @return CRYPT_OK on success
25 */
26 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
27 unsigned long *outlen)
28 {
29 int err, type;
30 unsigned long size, x, y, i;
31 void *data;
32
33 LTC_ARGCHK(list != NULL);
34 LTC_ARGCHK(outlen != NULL);
35
36 /* get size of output that will be required */
37 y = 0;
38 for (i = 0; i < inlen; i++) {
39 type = list[i].type;
40 size = list[i].size;
41 data = list[i].data;
42
43 if (type == LTC_ASN1_EOL) {
44 break;
45 }
46
47 switch (type) {
48 case LTC_ASN1_BOOLEAN:
49 if ((err = der_length_boolean(&x)) != CRYPT_OK) {
50 goto LBL_ERR;
51 }
52 y += x;
53 break;
54
55 case LTC_ASN1_INTEGER:
56 if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
57 goto LBL_ERR;
58 }
59 y += x;
60 break;
61
62 case LTC_ASN1_SHORT_INTEGER:
63 if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 y += x;
67 break;
68
69 case LTC_ASN1_BIT_STRING:
70 if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
71 goto LBL_ERR;
72 }
73 y += x;
74 break;
75
76 case LTC_ASN1_OCTET_STRING:
77 if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80 y += x;
81 break;
82
83 case LTC_ASN1_NULL:
84 y += 2;
85 break;
86
87 case LTC_ASN1_OBJECT_IDENTIFIER:
88 if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
89 goto LBL_ERR;
90 }
91 y += x;
92 break;
93
94 case LTC_ASN1_IA5_STRING:
95 if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
96 goto LBL_ERR;
97 }
98 y += x;
99 break;
100
101 case LTC_ASN1_PRINTABLE_STRING:
102 if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
103 goto LBL_ERR;
104 }
105 y += x;
106 break;
107
108 case LTC_ASN1_UTCTIME:
109 if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
110 goto LBL_ERR;
111 }
112 y += x;
113 break;
114
115 case LTC_ASN1_UTF8_STRING:
116 if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
117 goto LBL_ERR;
118 }
119 y += x;
120 break;
121
122 case LTC_ASN1_SET:
123 case LTC_ASN1_SETOF:
124 case LTC_ASN1_SEQUENCE:
125 if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
126 goto LBL_ERR;
127 }
128 y += x;
129 break;
130
131
132 default:
133 err = CRYPT_INVALID_ARG;
134 goto LBL_ERR;
135 }
136 }
137
138 /* calc header size */
139 if (y < 128) {
140 y += 2;
141 } else if (y < 256) {
142 /* 0x30 0x81 LL */
143 y += 3;
144 } else if (y < 65536UL) {
145 /* 0x30 0x82 LL LL */
146 y += 4;
147 } else if (y < 16777216UL) {
148 /* 0x30 0x83 LL LL LL */
149 y += 5;
150 } else {
151 err = CRYPT_INVALID_ARG;
152 goto LBL_ERR;
153 }
154
155 /* store size */
156 *outlen = y;
157 err = CRYPT_OK;
158
159 LBL_ERR:
160 return err;
161 }
162
163 #endif
164
165 /* $Source$ */
166 /* $Revision$ */
167 /* $Date$ */
+0
-67
libtom-src/pk/asn1/der/sequence/der_sequence_free.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_sequence_free.c
14 ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Free memory allocated by der_decode_sequence_flexi()
21 @param in The list to free
22 */
23 void der_sequence_free(ltc_asn1_list *in)
24 {
25 ltc_asn1_list *l;
26
27 if (!in) return;
28
29 /* walk to the start of the chain */
30 while (in->prev != NULL || in->parent != NULL) {
31 if (in->parent != NULL) {
32 in = in->parent;
33 } else {
34 in = in->prev;
35 }
36 }
37
38 /* now walk the list and free stuff */
39 while (in != NULL) {
40 /* is there a child? */
41 if (in->child) {
42 /* disconnect */
43 in->child->parent = NULL;
44 der_sequence_free(in->child);
45 }
46
47 switch (in->type) {
48 case LTC_ASN1_SET:
49 case LTC_ASN1_SETOF:
50 case LTC_ASN1_SEQUENCE: break;
51 case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break;
52 default : if (in->data != NULL) { XFREE(in->data); }
53 }
54
55 /* move to next and free current */
56 l = in->next;
57 XFREE(in);
58 in = l;
59 }
60 }
61
62 #endif
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
+0
-103
libtom-src/pk/asn1/der/set/der_encode_set.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_set.c
14 ASN.1 DER, Encode a SET, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /* LTC define to ASN.1 TAG */
20 static int ltc_to_asn1(int v)
21 {
22 switch (v) {
23 case LTC_ASN1_BOOLEAN: return 0x01;
24 case LTC_ASN1_INTEGER:
25 case LTC_ASN1_SHORT_INTEGER: return 0x02;
26 case LTC_ASN1_BIT_STRING: return 0x03;
27 case LTC_ASN1_OCTET_STRING: return 0x04;
28 case LTC_ASN1_NULL: return 0x05;
29 case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06;
30 case LTC_ASN1_UTF8_STRING: return 0x0C;
31 case LTC_ASN1_PRINTABLE_STRING: return 0x13;
32 case LTC_ASN1_IA5_STRING: return 0x16;
33 case LTC_ASN1_UTCTIME: return 0x17;
34 case LTC_ASN1_SEQUENCE: return 0x30;
35 case LTC_ASN1_SET:
36 case LTC_ASN1_SETOF: return 0x31;
37 default: return -1;
38 }
39 }
40
41
42 static int qsort_helper(const void *a, const void *b)
43 {
44 ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
45 int r;
46
47 r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type);
48
49 /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */
50 if (r == 0) {
51 /* their order in the original list now determines the position */
52 return A->used - B->used;
53 } else {
54 return r;
55 }
56 }
57
58 /*
59 Encode a SET type
60 @param list The list of items to encode
61 @param inlen The number of items in the list
62 @param out [out] The destination
63 @param outlen [in/out] The size of the output
64 @return CRYPT_OK on success
65 */
66 int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
67 unsigned char *out, unsigned long *outlen)
68 {
69 ltc_asn1_list *copy;
70 unsigned long x;
71 int err;
72
73 /* make copy of list */
74 copy = XCALLOC(inlen, sizeof(*copy));
75 if (copy == NULL) {
76 return CRYPT_MEM;
77 }
78
79 /* fill in used member with index so we can fully sort it */
80 for (x = 0; x < inlen; x++) {
81 copy[x] = list[x];
82 copy[x].used = x;
83 }
84
85 /* sort it by the "type" field */
86 XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);
87
88 /* call der_encode_sequence_ex() */
89 err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);
90
91 /* free list */
92 XFREE(copy);
93
94 return err;
95 }
96
97
98 #endif
99
100 /* $Source$ */
101 /* $Revision$ */
102 /* $Date$ */
+0
-162
libtom-src/pk/asn1/der/set/der_encode_setof.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_setof.c
14 ASN.1 DER, Encode SET OF, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 struct edge {
20 unsigned char *start;
21 unsigned long size;
22 };
23
24 static int qsort_helper(const void *a, const void *b)
25 {
26 struct edge *A = (struct edge *)a, *B = (struct edge *)b;
27 int r;
28 unsigned long x;
29
30 /* compare min length */
31 r = XMEMCMP(A->start, B->start, MIN(A->size, B->size));
32
33 if (r == 0 && A->size != B->size) {
34 if (A->size > B->size) {
35 for (x = B->size; x < A->size; x++) {
36 if (A->start[x]) {
37 return 1;
38 }
39 }
40 } else {
41 for (x = A->size; x < B->size; x++) {
42 if (B->start[x]) {
43 return -1;
44 }
45 }
46 }
47 }
48
49 return r;
50 }
51
52 /**
53 Encode a SETOF stucture
54 @param list The list of items to encode
55 @param inlen The number of items in the list
56 @param out [out] The destination
57 @param outlen [in/out] The size of the output
58 @return CRYPT_OK on success
59 */
60 int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
61 unsigned char *out, unsigned long *outlen)
62 {
63 unsigned long x, y, z, hdrlen;
64 int err;
65 struct edge *edges;
66 unsigned char *ptr, *buf;
67
68 /* check that they're all the same type */
69 for (x = 1; x < inlen; x++) {
70 if (list[x].type != list[x-1].type) {
71 return CRYPT_INVALID_ARG;
72 }
73 }
74
75 /* alloc buffer to store copy of output */
76 buf = XCALLOC(1, *outlen);
77 if (buf == NULL) {
78 return CRYPT_MEM;
79 }
80
81 /* encode list */
82 if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) {
83 XFREE(buf);
84 return err;
85 }
86
87 /* allocate edges */
88 edges = XCALLOC(inlen, sizeof(*edges));
89 if (edges == NULL) {
90 XFREE(buf);
91 return CRYPT_MEM;
92 }
93
94 /* skip header */
95 ptr = buf + 1;
96
97 /* now skip length data */
98 x = *ptr++;
99 if (x >= 0x80) {
100 ptr += (x & 0x7F);
101 }
102
103 /* get the size of the static header */
104 hdrlen = (unsigned long)(ptr - buf);
105
106
107 /* scan for edges */
108 x = 0;
109 while (ptr < (buf + *outlen)) {
110 /* store start */
111 edges[x].start = ptr;
112
113 /* skip type */
114 z = 1;
115
116 /* parse length */
117 y = ptr[z++];
118 if (y < 128) {
119 edges[x].size = y;
120 } else {
121 y &= 0x7F;
122 edges[x].size = 0;
123 while (y--) {
124 edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]);
125 }
126 }
127
128 /* skip content */
129 edges[x].size += z;
130 ptr += edges[x].size;
131 ++x;
132 }
133
134 /* sort based on contents (using edges) */
135 XQSORT(edges, inlen, sizeof(*edges), &qsort_helper);
136
137 /* copy static header */
138 XMEMCPY(out, buf, hdrlen);
139
140 /* copy+sort using edges+indecies to output from buffer */
141 for (y = hdrlen, x = 0; x < inlen; x++) {
142 XMEMCPY(out+y, edges[x].start, edges[x].size);
143 y += edges[x].size;
144 }
145
146 #ifdef LTC_CLEAN_STACK
147 zeromem(buf, *outlen);
148 #endif
149
150 /* free buffers */
151 XFREE(edges);
152 XFREE(buf);
153
154 return CRYPT_OK;
155 }
156
157 #endif
158
159 /* $Source$ */
160 /* $Revision$ */
161 /* $Date$ */
+0
-68
libtom-src/pk/asn1/der/short_integer/der_decode_short_integer.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_short_integer.c
14 ASN.1 DER, decode an integer, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Read a short integer
22 @param in The DER encoded data
23 @param inlen Size of data
24 @param num [out] The integer to decode
25 @return CRYPT_OK if successful
26 */
27 int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num)
28 {
29 unsigned long len, x, y;
30
31 LTC_ARGCHK(num != NULL);
32 LTC_ARGCHK(in != NULL);
33
34 /* check length */
35 if (inlen < 2) {
36 return CRYPT_INVALID_PACKET;
37 }
38
39 /* check header */
40 x = 0;
41 if ((in[x++] & 0x1F) != 0x02) {
42 return CRYPT_INVALID_PACKET;
43 }
44
45 /* get the packet len */
46 len = in[x++];
47
48 if (x + len > inlen) {
49 return CRYPT_INVALID_PACKET;
50 }
51
52 /* read number */
53 y = 0;
54 while (len--) {
55 y = (y<<8) | (unsigned long)in[x++];
56 }
57 *num = y;
58
59 return CRYPT_OK;
60
61 }
62
63 #endif
64
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
+0
-97
libtom-src/pk/asn1/der/short_integer/der_encode_short_integer.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_short_integer.c
14 ASN.1 DER, encode an integer, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a short integer in the range (0,2^32-1)
22 @param num The integer to encode
23 @param out [out] The destination for the DER encoded integers
24 @param outlen [in/out] The max size and resulting size of the DER encoded integers
25 @return CRYPT_OK if successful
26 */
27 int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen)
28 {
29 unsigned long len, x, y, z;
30 int err;
31
32 LTC_ARGCHK(out != NULL);
33 LTC_ARGCHK(outlen != NULL);
34
35 /* force to 32 bits */
36 num &= 0xFFFFFFFFUL;
37
38 /* find out how big this will be */
39 if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) {
40 return err;
41 }
42
43 if (*outlen < len) {
44 *outlen = len;
45 return CRYPT_BUFFER_OVERFLOW;
46 }
47
48 /* get len of output */
49 z = 0;
50 y = num;
51 while (y) {
52 ++z;
53 y >>= 8;
54 }
55
56 /* handle zero */
57 if (z == 0) {
58 z = 1;
59 }
60
61 /* see if msb is set */
62 z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
63
64 /* adjust the number so the msB is non-zero */
65 for (x = 0; (z <= 4) && (x < (4 - z)); x++) {
66 num <<= 8;
67 }
68
69 /* store header */
70 x = 0;
71 out[x++] = 0x02;
72 out[x++] = (unsigned char)z;
73
74 /* if 31st bit is set output a leading zero and decrement count */
75 if (z == 5) {
76 out[x++] = 0;
77 --z;
78 }
79
80 /* store values */
81 for (y = 0; y < z; y++) {
82 out[x++] = (unsigned char)((num >> 24) & 0xFF);
83 num <<= 8;
84 }
85
86 /* we good */
87 *outlen = x;
88
89 return CRYPT_OK;
90 }
91
92 #endif
93
94 /* $Source$ */
95 /* $Revision$ */
96 /* $Date$ */
+0
-70
libtom-src/pk/asn1/der/short_integer/der_length_short_integer.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_short_integer.c
14 ASN.1 DER, get length of encoding, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19 /**
20 Gets length of DER encoding of num
21 @param num The integer to get the size of
22 @param outlen [out] The length of the DER encoding for the given integer
23 @return CRYPT_OK if successful
24 */
25 int der_length_short_integer(unsigned long num, unsigned long *outlen)
26 {
27 unsigned long z, y, len;
28
29 LTC_ARGCHK(outlen != NULL);
30
31 /* force to 32 bits */
32 num &= 0xFFFFFFFFUL;
33
34 /* get the number of bytes */
35 z = 0;
36 y = num;
37 while (y) {
38 ++z;
39 y >>= 8;
40 }
41
42 /* handle zero */
43 if (z == 0) {
44 z = 1;
45 }
46
47 /* we need a 0x02 to indicate it's INTEGER */
48 len = 1;
49
50 /* length byte */
51 ++len;
52
53 /* bytes in value */
54 len += z;
55
56 /* see if msb is set */
57 len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
58
59 /* return length */
60 *outlen = len;
61
62 return CRYPT_OK;
63 }
64
65 #endif
66
67 /* $Source$ */
68 /* $Revision$ */
69 /* $Date$ */
+0
-95
libtom-src/pk/asn1/der/teletex_string/der_decode_teletex_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_teletex_string.c
14 ASN.1 DER, encode a teletex STRING
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Store a teletex STRING
21 @param in The DER encoded teletex STRING
22 @param inlen The size of the DER teletex STRING
23 @param out [out] The array of octets stored (one per char)
24 @param outlen [in/out] The number of octets stored
25 @return CRYPT_OK if successful
26 */
27 int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
28 unsigned char *out, unsigned long *outlen)
29 {
30 unsigned long x, y, len;
31 int t;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* must have header at least */
38 if (inlen < 2) {
39 return CRYPT_INVALID_PACKET;
40 }
41
42 /* check for 0x13 */
43 if ((in[0] & 0x1F) != 0x14) {
44 return CRYPT_INVALID_PACKET;
45 }
46 x = 1;
47
48 /* decode the length */
49 if (in[x] & 0x80) {
50 /* valid # of bytes in length are 1,2,3 */
51 y = in[x] & 0x7F;
52 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
53 return CRYPT_INVALID_PACKET;
54 }
55
56 /* read the length in */
57 len = 0;
58 ++x;
59 while (y--) {
60 len = (len << 8) | in[x++];
61 }
62 } else {
63 len = in[x++] & 0x7F;
64 }
65
66 /* is it too long? */
67 if (len > *outlen) {
68 *outlen = len;
69 return CRYPT_BUFFER_OVERFLOW;
70 }
71
72 if (len + x > inlen) {
73 return CRYPT_INVALID_PACKET;
74 }
75
76 /* read the data */
77 for (y = 0; y < len; y++) {
78 t = der_teletex_value_decode(in[x++]);
79 if (t == -1) {
80 return CRYPT_INVALID_ARG;
81 }
82 out[y] = t;
83 }
84
85 *outlen = y;
86
87 return CRYPT_OK;
88 }
89
90 #endif
91
92 /* $Source$ */
93 /* $Revision$ */
94 /* $Date$ */
+0
-210
libtom-src/pk/asn1/der/teletex_string/der_length_teletex_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_teletex_string.c
14 ASN.1 DER, get length of teletex STRING
15 */
16
17 #ifdef LTC_DER
18
19 static const struct {
20 int code, value;
21 } teletex_table[] = {
22 { '\0', 0 },
23 { '\a', 7 },
24 { '\b', 8 },
25 { '\t', 9 },
26 { '\n', 10 },
27 { '\v', 11 },
28 { '\f', 12 },
29 { '\r', 13 },
30 { ' ', 32 },
31 { '!', 33 },
32 { '"', 34 },
33 { '%', 37 },
34 { '&', 38 },
35 { '\'', 39 },
36 { '(', 40 },
37 { ')', 41 },
38 { '+', 43 },
39 { ',', 44 },
40 { '-', 45 },
41 { '.', 46 },
42 { '/', 47 },
43 { '0', 48 },
44 { '1', 49 },
45 { '2', 50 },
46 { '3', 51 },
47 { '4', 52 },
48 { '5', 53 },
49 { '6', 54 },
50 { '7', 55 },
51 { '8', 56 },
52 { '9', 57 },
53 { ':', 58 },
54 { ';', 59 },
55 { '<', 60 },
56 { '=', 61 },
57 { '>', 62 },
58 { '?', 63 },
59 { '@', 64 },
60 { 'A', 65 },
61 { 'B', 66 },
62 { 'C', 67 },
63 { 'D', 68 },
64 { 'E', 69 },
65 { 'F', 70 },
66 { 'G', 71 },
67 { 'H', 72 },
68 { 'I', 73 },
69 { 'J', 74 },
70 { 'K', 75 },
71 { 'L', 76 },
72 { 'M', 77 },
73 { 'N', 78 },
74 { 'O', 79 },
75 { 'P', 80 },
76 { 'Q', 81 },
77 { 'R', 82 },
78 { 'S', 83 },
79 { 'T', 84 },
80 { 'U', 85 },
81 { 'V', 86 },
82 { 'W', 87 },
83 { 'X', 88 },
84 { 'Y', 89 },
85 { 'Z', 90 },
86 { '[', 91 },
87 { ']', 93 },
88 { '_', 95 },
89 { 'a', 97 },
90 { 'b', 98 },
91 { 'c', 99 },
92 { 'd', 100 },
93 { 'e', 101 },
94 { 'f', 102 },
95 { 'g', 103 },
96 { 'h', 104 },
97 { 'i', 105 },
98 { 'j', 106 },
99 { 'k', 107 },
100 { 'l', 108 },
101 { 'm', 109 },
102 { 'n', 110 },
103 { 'o', 111 },
104 { 'p', 112 },
105 { 'q', 113 },
106 { 'r', 114 },
107 { 's', 115 },
108 { 't', 116 },
109 { 'u', 117 },
110 { 'v', 118 },
111 { 'w', 119 },
112 { 'x', 120 },
113 { 'y', 121 },
114 { 'z', 122 },
115 { '|', 124 },
116 { ' ', 160 },
117 { 0xa1, 161 },
118 { 0xa2, 162 },
119 { 0xa3, 163 },
120 { '$', 164 },
121 { 0xa5, 165 },
122 { '#', 166 },
123 { 0xa7, 167 },
124 { 0xa4, 168 },
125 { 0xab, 171 },
126 { 0xb0, 176 },
127 { 0xb1, 177 },
128 { 0xb2, 178 },
129 { 0xb3, 179 },
130 { 0xd7, 180 },
131 { 0xb5, 181 },
132 { 0xb6, 182 },
133 { 0xb7, 183 },
134 { 0xf7, 184 },
135 { 0xbb, 187 },
136 { 0xbc, 188 },
137 { 0xbd, 189 },
138 { 0xbe, 190 },
139 { 0xbf, 191 },
140 };
141
142 int der_teletex_char_encode(int c)
143 {
144 int x;
145 for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) {
146 if (teletex_table[x].code == c) {
147 return teletex_table[x].value;
148 }
149 }
150 return -1;
151 }
152
153 int der_teletex_value_decode(int v)
154 {
155 int x;
156 for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) {
157 if (teletex_table[x].value == v) {
158 return teletex_table[x].code;
159 }
160 }
161 return -1;
162 }
163
164 /**
165 Gets length of DER encoding of teletex STRING
166 @param octets The values you want to encode
167 @param noctets The number of octets in the string to encode
168 @param outlen [out] The length of the DER encoding for the given string
169 @return CRYPT_OK if successful
170 */
171 int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
172 {
173 unsigned long x;
174
175 LTC_ARGCHK(outlen != NULL);
176 LTC_ARGCHK(octets != NULL);
177
178 /* scan string for validity */
179 for (x = 0; x < noctets; x++) {
180 if (der_teletex_char_encode(octets[x]) == -1) {
181 return CRYPT_INVALID_ARG;
182 }
183 }
184
185 if (noctets < 128) {
186 /* 16 LL DD DD DD ... */
187 *outlen = 2 + noctets;
188 } else if (noctets < 256) {
189 /* 16 81 LL DD DD DD ... */
190 *outlen = 3 + noctets;
191 } else if (noctets < 65536UL) {
192 /* 16 82 LL LL DD DD DD ... */
193 *outlen = 4 + noctets;
194 } else if (noctets < 16777216UL) {
195 /* 16 83 LL LL LL DD DD DD ... */
196 *outlen = 5 + noctets;
197 } else {
198 return CRYPT_INVALID_ARG;
199 }
200
201 return CRYPT_OK;
202 }
203
204 #endif
205
206
207 /* $Source$ */
208 /* $Revision$ */
209 /* $Date$ */
+0
-127
libtom-src/pk/asn1/der/utctime/der_decode_utctime.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_utctime.c
14 ASN.1 DER, decode a UTCTIME, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static int char_to_int(unsigned char x)
20 {
21 switch (x) {
22 case '0': return 0;
23 case '1': return 1;
24 case '2': return 2;
25 case '3': return 3;
26 case '4': return 4;
27 case '5': return 5;
28 case '6': return 6;
29 case '7': return 7;
30 case '8': return 8;
31 case '9': return 9;
32 }
33 return 100;
34 }
35
36 #define DECODE_V(y, max) \
37 y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \
38 if (y >= max) return CRYPT_INVALID_PACKET; \
39 x += 2;
40
41 /**
42 Decodes a UTC time structure in DER format (reads all 6 valid encoding formats)
43 @param in Input buffer
44 @param inlen Length of input buffer in octets
45 @param out [out] Destination of UTC time structure
46 @return CRYPT_OK if successful
47 */
48 int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
49 ltc_utctime *out)
50 {
51 unsigned char buf[32];
52 unsigned long x;
53 int y;
54
55 LTC_ARGCHK(in != NULL);
56 LTC_ARGCHK(inlen != NULL);
57 LTC_ARGCHK(out != NULL);
58
59 /* check header */
60 if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) {
61 return CRYPT_INVALID_PACKET;
62 }
63
64 /* decode the string */
65 for (x = 0; x < in[1]; x++) {
66 y = der_ia5_value_decode(in[x+2]);
67 if (y == -1) {
68 return CRYPT_INVALID_PACKET;
69 }
70 buf[x] = y;
71 }
72 *inlen = 2 + x;
73
74
75 /* possible encodings are
76 YYMMDDhhmmZ
77 YYMMDDhhmm+hh'mm'
78 YYMMDDhhmm-hh'mm'
79 YYMMDDhhmmssZ
80 YYMMDDhhmmss+hh'mm'
81 YYMMDDhhmmss-hh'mm'
82
83 So let's do a trivial decode upto [including] mm
84 */
85
86 x = 0;
87 DECODE_V(out->YY, 100);
88 DECODE_V(out->MM, 13);
89 DECODE_V(out->DD, 32);
90 DECODE_V(out->hh, 24);
91 DECODE_V(out->mm, 60);
92
93 /* clear timezone and seconds info */
94 out->off_dir = out->off_hh = out->off_mm = out->ss = 0;
95
96 /* now is it Z, +, - or 0-9 */
97 if (buf[x] == 'Z') {
98 return CRYPT_OK;
99 } else if (buf[x] == '+' || buf[x] == '-') {
100 out->off_dir = (buf[x++] == '+') ? 0 : 1;
101 DECODE_V(out->off_hh, 24);
102 DECODE_V(out->off_mm, 60);
103 return CRYPT_OK;
104 }
105
106 /* decode seconds */
107 DECODE_V(out->ss, 60);
108
109 /* now is it Z, +, - */
110 if (buf[x] == 'Z') {
111 return CRYPT_OK;
112 } else if (buf[x] == '+' || buf[x] == '-') {
113 out->off_dir = (buf[x++] == '+') ? 0 : 1;
114 DECODE_V(out->off_hh, 24);
115 DECODE_V(out->off_mm, 60);
116 return CRYPT_OK;
117 } else {
118 return CRYPT_INVALID_PACKET;
119 }
120 }
121
122 #endif
123
124 /* $Source$ */
125 /* $Revision$ */
126 /* $Date$ */
+0
-83
libtom-src/pk/asn1/der/utctime/der_encode_utctime.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_utctime.c
14 ASN.1 DER, encode a UTCTIME, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static const char *baseten = "0123456789";
20
21 #define STORE_V(y) \
22 out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
23 out[x++] = der_ia5_char_encode(baseten[y % 10]);
24
25 /**
26 Encodes a UTC time structure in DER format
27 @param utctime The UTC time structure to encode
28 @param out The destination of the DER encoding of the UTC time structure
29 @param outlen [in/out] The length of the DER encoding
30 @return CRYPT_OK if successful
31 */
32 int der_encode_utctime(ltc_utctime *utctime,
33 unsigned char *out, unsigned long *outlen)
34 {
35 unsigned long x, tmplen;
36 int err;
37
38 LTC_ARGCHK(utctime != NULL);
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41
42 if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) {
43 return err;
44 }
45 if (tmplen > *outlen) {
46 *outlen = tmplen;
47 return CRYPT_BUFFER_OVERFLOW;
48 }
49
50 /* store header */
51 out[0] = 0x17;
52
53 /* store values */
54 x = 2;
55 STORE_V(utctime->YY);
56 STORE_V(utctime->MM);
57 STORE_V(utctime->DD);
58 STORE_V(utctime->hh);
59 STORE_V(utctime->mm);
60 STORE_V(utctime->ss);
61
62 if (utctime->off_mm || utctime->off_hh) {
63 out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+');
64 STORE_V(utctime->off_hh);
65 STORE_V(utctime->off_mm);
66 } else {
67 out[x++] = der_ia5_char_encode('Z');
68 }
69
70 /* store length */
71 out[1] = (unsigned char)(x - 2);
72
73 /* all good let's return */
74 *outlen = x;
75 return CRYPT_OK;
76 }
77
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
+0
-46
libtom-src/pk/asn1/der/utctime/der_length_utctime.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_utctime.c
14 ASN.1 DER, get length of UTCTIME, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Gets length of DER encoding of UTCTIME
21 @param utctime The UTC time structure to get the size of
22 @param outlen [out] The length of the DER encoding
23 @return CRYPT_OK if successful
24 */
25 int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen)
26 {
27 LTC_ARGCHK(outlen != NULL);
28 LTC_ARGCHK(utctime != NULL);
29
30 if (utctime->off_hh == 0 && utctime->off_mm == 0) {
31 /* we encode as YYMMDDhhmmssZ */
32 *outlen = 2 + 13;
33 } else {
34 /* we encode as YYMMDDhhmmss{+|-}hh'mm' */
35 *outlen = 2 + 17;
36 }
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
+0
-111
libtom-src/pk/asn1/der/utf8/der_decode_utf8_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_utf8_string.c
14 ASN.1 DER, encode a UTF8 STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a UTF8 STRING
22 @param in The DER encoded UTF8 STRING
23 @param inlen The size of the DER UTF8 STRING
24 @param out [out] The array of utf8s stored (one per char)
25 @param outlen [in/out] The number of utf8s stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
29 wchar_t *out, unsigned long *outlen)
30 {
31 wchar_t tmp;
32 unsigned long x, y, z, len;
33
34 LTC_ARGCHK(in != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* must have header at least */
39 if (inlen < 2) {
40 return CRYPT_INVALID_PACKET;
41 }
42
43 /* check for 0x0C */
44 if ((in[0] & 0x1F) != 0x0C) {
45 return CRYPT_INVALID_PACKET;
46 }
47 x = 1;
48
49 /* decode the length */
50 if (in[x] & 0x80) {
51 /* valid # of bytes in length are 1,2,3 */
52 y = in[x] & 0x7F;
53 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* read the length in */
58 len = 0;
59 ++x;
60 while (y--) {
61 len = (len << 8) | in[x++];
62 }
63 } else {
64 len = in[x++] & 0x7F;
65 }
66
67 if (len + x > inlen) {
68 return CRYPT_INVALID_PACKET;
69 }
70
71 /* proceed to decode */
72 for (y = 0; x < inlen; ) {
73 /* get first byte */
74 tmp = in[x++];
75
76 /* count number of bytes */
77 for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF);
78
79 if (z > 4 || (x + (z - 1) > inlen)) {
80 return CRYPT_INVALID_PACKET;
81 }
82
83 /* decode, grab upper bits */
84 tmp >>= z;
85
86 /* grab remaining bytes */
87 if (z > 1) { --z; }
88 while (z-- != 0) {
89 if ((in[x] & 0xC0) != 0x80) {
90 return CRYPT_INVALID_PACKET;
91 }
92 tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F);
93 }
94
95 if (y > *outlen) {
96 *outlen = y;
97 return CRYPT_BUFFER_OVERFLOW;
98 }
99 out[y++] = tmp;
100 }
101 *outlen = y;
102
103 return CRYPT_OK;
104 }
105
106 #endif
107
108 /* $Source$ */
109 /* $Revision$ */
110 /* $Date$ */
+0
-105
libtom-src/pk/asn1/der/utf8/der_encode_utf8_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_utf8_string.c
14 ASN.1 DER, encode a UTF8 STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store an UTF8 STRING
22 @param in The array of UTF8 to store (one per wchar_t)
23 @param inlen The number of UTF8 to store
24 @param out [out] The destination for the DER encoded UTF8 STRING
25 @param outlen [in/out] The max size and resulting size of the DER UTF8 STRING
26 @return CRYPT_OK if successful
27 */
28 int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* get the size */
38 for (x = len = 0; x < inlen; x++) {
39 if (in[x] < 0 || in[x] > 0x1FFFF) {
40 return CRYPT_INVALID_ARG;
41 }
42 len += der_utf8_charsize(in[x]);
43 }
44
45 if (len < 128) {
46 y = 2 + len;
47 } else if (len < 256) {
48 y = 3 + len;
49 } else if (len < 65536UL) {
50 y = 4 + len;
51 } else if (len < 16777216UL) {
52 y = 5 + len;
53 } else {
54 return CRYPT_INVALID_ARG;
55 }
56
57 /* too big? */
58 if (y > *outlen) {
59 *outlen = len;
60 return CRYPT_BUFFER_OVERFLOW;
61 }
62
63 /* encode the header+len */
64 x = 0;
65 out[x++] = 0x0C;
66 if (len < 128) {
67 out[x++] = (unsigned char)len;
68 } else if (len < 256) {
69 out[x++] = 0x81;
70 out[x++] = (unsigned char)len;
71 } else if (len < 65536UL) {
72 out[x++] = 0x82;
73 out[x++] = (unsigned char)((len>>8)&255);
74 out[x++] = (unsigned char)(len&255);
75 } else if (len < 16777216UL) {
76 out[x++] = 0x83;
77 out[x++] = (unsigned char)((len>>16)&255);
78 out[x++] = (unsigned char)((len>>8)&255);
79 out[x++] = (unsigned char)(len&255);
80 } else {
81 return CRYPT_INVALID_ARG;
82 }
83
84 /* store UTF8 */
85 for (y = 0; y < inlen; y++) {
86 switch (der_utf8_charsize(in[y])) {
87 case 1: out[x++] = (unsigned char)in[y]; break;
88 case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break;
89 case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
90 case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
91 }
92 }
93
94 /* retun length */
95 *outlen = x;
96
97 return CRYPT_OK;
98 }
99
100 #endif
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
+0
-83
libtom-src/pk/asn1/der/utf8/der_length_utf8_string.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_utf8_string.c
14 ASN.1 DER, get length of UTF8 STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /** Return the size in bytes of a UTF-8 character
20 @param c The UTF-8 character to measure
21 @return The size in bytes
22 */
23 unsigned long der_utf8_charsize(const wchar_t c)
24 {
25 if (c <= 0x7F) {
26 return 1;
27 } else if (c <= 0x7FF) {
28 return 2;
29 } else if (c <= 0xFFFF) {
30 return 3;
31 } else {
32 return 4;
33 }
34 }
35
36 /**
37 Gets length of DER encoding of UTF8 STRING
38 @param in The characters to measure the length of
39 @param noctets The number of octets in the string to encode
40 @param outlen [out] The length of the DER encoding for the given string
41 @return CRYPT_OK if successful
42 */
43 int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen)
44 {
45 unsigned long x, len;
46
47 LTC_ARGCHK(in != NULL);
48 LTC_ARGCHK(outlen != NULL);
49
50 len = 0;
51 for (x = 0; x < noctets; x++) {
52 if (in[x] < 0 || in[x] > 0x10FFFF) {
53 return CRYPT_INVALID_ARG;
54 }
55 len += der_utf8_charsize(in[x]);
56 }
57
58 if (len < 128) {
59 /* 0C LL DD DD DD ... */
60 *outlen = 2 + len;
61 } else if (len < 256) {
62 /* 0C 81 LL DD DD DD ... */
63 *outlen = 3 + len;
64 } else if (len < 65536UL) {
65 /* 0C 82 LL LL DD DD DD ... */
66 *outlen = 4 + len;
67 } else if (len < 16777216UL) {
68 /* 0C 83 LL LL LL DD DD DD ... */
69 *outlen = 5 + len;
70 } else {
71 return CRYPT_INVALID_ARG;
72 }
73
74 return CRYPT_OK;
75 }
76
77 #endif
78
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
+0
-606
libtom-src/pk/dh/dh.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dh.c
14 DH crypto, Tom St Denis
15 */
16
17 #ifdef MDH
18
19 /* size of a packet header in bytes */
20 #define PACKET_SIZE 4
21
22 /* Section tags */
23 #define PACKET_SECT_DH 1
24
25 /* Subsection Tags for the first three sections */
26 #define PACKET_SUB_KEY 0
27 #define PACKET_SUB_ENCRYPTED 1
28 #define PACKET_SUB_SIGNED 2
29 #define PACKET_SUB_ENC_KEY 3
30
31 #define OUTPUT_BIGNUM(num, out, y, z) \
32 { \
33 if ((y + 4) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \
34 z = (unsigned long)mp_unsigned_bin_size(num); \
35 STORE32L(z, out+y); \
36 y += 4; \
37 if ((y + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \
38 if ((err = mp_to_unsigned_bin(num, out+y)) != CRYPT_OK) { return err; } \
39 y += z; \
40 }
41
42 #define INPUT_BIGNUM(num, in, x, y, inlen) \
43 { \
44 /* load value */ \
45 if ((y + 4) > inlen) { \
46 err = CRYPT_INVALID_PACKET; \
47 goto error; \
48 } \
49 LOAD32L(x, in+y); \
50 y += 4; \
51 \
52 /* sanity check... */ \
53 if ((x+y) > inlen) { \
54 err = CRYPT_INVALID_PACKET; \
55 goto error; \
56 } \
57 \
58 /* load it */ \
59 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != CRYPT_OK) {\
60 goto error; \
61 } \
62 y += x; \
63 }
64
65 static void packet_store_header(unsigned char *dst, int section, int subsection)
66 {
67 LTC_ARGCHK(dst != NULL);
68
69 /* store version number */
70 dst[0] = (unsigned char)(CRYPT&255);
71 dst[1] = (unsigned char)((CRYPT>>8)&255);
72
73 /* store section and subsection */
74 dst[2] = (unsigned char)(section & 255);
75 dst[3] = (unsigned char)(subsection & 255);
76
77 }
78
79 static int packet_valid_header(unsigned char *src, int section, int subsection)
80 {
81 unsigned long ver;
82
83 LTC_ARGCHK(src != NULL);
84
85 /* check version */
86 ver = ((unsigned long)src[0]) | ((unsigned long)src[1] << 8U);
87 if (CRYPT < ver) {
88 return CRYPT_INVALID_PACKET;
89 }
90
91 /* check section and subsection */
92 if (section != (int)src[2] || subsection != (int)src[3]) {
93 return CRYPT_INVALID_PACKET;
94 }
95
96 return CRYPT_OK;
97 }
98
99
100 /* max export size we'll encounter (smaller than this but lets round up a bit) */
101 #define DH_BUF_SIZE 1200
102
103 /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
104 static const struct {
105 int size;
106 char *name, *base, *prime;
107 } sets[] = {
108 #ifdef DH768
109 {
110 96,
111 "DH-768",
112 "4",
113 "F///////////////////////////////////////////////////////////"
114 "////////////////////////////////////////////////////////////"
115 "//////m3wvV"
116 },
117 #endif
118 #ifdef DH1024
119 {
120 128,
121 "DH-1024",
122 "4",
123 "F///////////////////////////////////////////////////////////"
124 "////////////////////////////////////////////////////////////"
125 "////////////////////////////////////////////////m3C47"
126 },
127 #endif
128 #ifdef DH1280
129 {
130 160,
131 "DH-1280",
132 "4",
133 "F///////////////////////////////////////////////////////////"
134 "////////////////////////////////////////////////////////////"
135 "////////////////////////////////////////////////////////////"
136 "//////////////////////////////m4kSN"
137 },
138 #endif
139 #ifdef DH1536
140 {
141 192,
142 "DH-1536",
143 "4",
144 "F///////////////////////////////////////////////////////////"
145 "////////////////////////////////////////////////////////////"
146 "////////////////////////////////////////////////////////////"
147 "////////////////////////////////////////////////////////////"
148 "////////////m5uqd"
149 },
150 #endif
151 #ifdef DH1792
152 {
153 224,
154 "DH-1792",
155 "4",
156 "F///////////////////////////////////////////////////////////"
157 "////////////////////////////////////////////////////////////"
158 "////////////////////////////////////////////////////////////"
159 "////////////////////////////////////////////////////////////"
160 "//////////////////////////////////////////////////////mT/sd"
161 },
162 #endif
163 #ifdef DH2048
164 {
165 256,
166 "DH-2048",
167 "4",
168 "3///////////////////////////////////////////////////////////"
169 "////////////////////////////////////////////////////////////"
170 "////////////////////////////////////////////////////////////"
171 "////////////////////////////////////////////////////////////"
172 "////////////////////////////////////////////////////////////"
173 "/////////////////////////////////////////m8MPh"
174 },
175 #endif
176 #ifdef DH2560
177 {
178 320,
179 "DH-2560",
180 "4",
181 "3///////////////////////////////////////////////////////////"
182 "////////////////////////////////////////////////////////////"
183 "////////////////////////////////////////////////////////////"
184 "////////////////////////////////////////////////////////////"
185 "////////////////////////////////////////////////////////////"
186 "////////////////////////////////////////////////////////////"
187 "////////////////////////////////////////////////////////////"
188 "/////mKFpF"
189 },
190 #endif
191 #ifdef DH3072
192 {
193 384,
194 "DH-3072",
195 "4",
196 "3///////////////////////////////////////////////////////////"
197 "////////////////////////////////////////////////////////////"
198 "////////////////////////////////////////////////////////////"
199 "////////////////////////////////////////////////////////////"
200 "////////////////////////////////////////////////////////////"
201 "////////////////////////////////////////////////////////////"
202 "////////////////////////////////////////////////////////////"
203 "////////////////////////////////////////////////////////////"
204 "/////////////////////////////m32nN"
205 },
206 #endif
207 #ifdef DH4096
208 {
209 512,
210 "DH-4096",
211 "4",
212 "////////////////////////////////////////////////////////////"
213 "////////////////////////////////////////////////////////////"
214 "////////////////////////////////////////////////////////////"
215 "////////////////////////////////////////////////////////////"
216 "////////////////////////////////////////////////////////////"
217 "////////////////////////////////////////////////////////////"
218 "////////////////////////////////////////////////////////////"
219 "////////////////////////////////////////////////////////////"
220 "////////////////////////////////////////////////////////////"
221 "////////////////////////////////////////////////////////////"
222 "////////////////////////////////////////////////////////////"
223 "/////////////////////m8pOF"
224 },
225 #endif
226 {
227 0,
228 NULL,
229 NULL,
230 NULL
231 }
232 };
233
234 static int is_valid_idx(int n)
235 {
236 int x;
237
238 for (x = 0; sets[x].size; x++);
239 if ((n < 0) || (n >= x)) {
240 return 0;
241 }
242 return 1;
243 }
244
245 /**
246 Test the DH sub-system (can take a while)
247 @return CRYPT_OK if successful
248 */
249 int dh_compat_test(void)
250 {
251 void *p, *g, *tmp;
252 int x, err, primality;
253
254 if ((err = mp_init_multi(&p, &g, &tmp, NULL)) != CRYPT_OK) { goto error; }
255
256 for (x = 0; sets[x].size != 0; x++) {
257 #if 0
258 printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
259 #endif
260 if ((err = mp_read_radix(g,(char *)sets[x].base, 64)) != CRYPT_OK) { goto error; }
261 if ((err = mp_read_radix(p,(char *)sets[x].prime, 64)) != CRYPT_OK) { goto error; }
262
263 /* ensure p is prime */
264 if ((err = mp_prime_is_prime(p, 8, &primality)) != CRYPT_OK) { goto done; }
265 if (primality != LTC_MP_YES ) {
266 err = CRYPT_FAIL_TESTVECTOR;
267 goto done;
268 }
269
270 if ((err = mp_sub_d(p, 1, tmp)) != CRYPT_OK) { goto error; }
271 if ((err = mp_div_2(tmp, tmp)) != CRYPT_OK) { goto error; }
272
273 /* ensure (p-1)/2 is prime */
274 if ((err = mp_prime_is_prime(tmp, 8, &primality)) != CRYPT_OK) { goto done; }
275 if (primality == 0) {
276 err = CRYPT_FAIL_TESTVECTOR;
277 goto done;
278 }
279
280 /* now see if g^((p-1)/2) mod p is in fact 1 */
281 if ((err = mp_exptmod(g, tmp, p, tmp)) != CRYPT_OK) { goto error; }
282 if (mp_cmp_d(tmp, 1)) {
283 err = CRYPT_FAIL_TESTVECTOR;
284 goto done;
285 }
286 }
287 err = CRYPT_OK;
288 error:
289 done:
290 mp_clear_multi(tmp, g, p, NULL);
291 return err;
292 }
293
294 /**
295 Get the min and max DH key sizes (octets)
296 @param low [out] The smallest key size supported
297 @param high [out] The largest key size supported
298 */
299 void dh_sizes(int *low, int *high)
300 {
301 int x;
302 LTC_ARGCHK(low != NULL);
303 LTC_ARGCHK(high != NULL);
304 *low = INT_MAX;
305 *high = 0;
306 for (x = 0; sets[x].size != 0; x++) {
307 if (*low > sets[x].size) *low = sets[x].size;
308 if (*high < sets[x].size) *high = sets[x].size;
309 }
310 }
311
312 /**
313 Returns the key size of a given DH key (octets)
314 @param key The DH key to get the size of
315 @return The size if valid or INT_MAX if not
316 */
317 int dh_get_size(dh_key *key)
318 {
319 LTC_ARGCHK(key != NULL);
320 if (is_valid_idx(key->idx) == 1) {
321 return sets[key->idx].size;
322 } else {
323 return INT_MAX; /* large value that would cause dh_make_key() to fail */
324 }
325 }
326
327 /**
328 Make a DH key [private key pair]
329 @param prng An active PRNG state
330 @param wprng The index for the PRNG you desire to use
331 @param keysize The key size (octets) desired
332 @param key [out] Where the newly created DH key will be stored
333 @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically.
334 */
335 int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
336 {
337 unsigned char *buf;
338 unsigned long x;
339 void *p, *g;
340 int err;
341
342 LTC_ARGCHK(key != NULL);
343
344 /* good prng? */
345 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
346 return err;
347 }
348
349 /* find key size */
350 for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
351 #ifdef FAST_PK
352 keysize = MIN(sets[x].size, 32);
353 #else
354 keysize = sets[x].size;
355 #endif
356 if (sets[x].size == 0) {
357 return CRYPT_INVALID_KEYSIZE;
358 }
359 key->idx = x;
360
361 /* allocate buffer */
362 buf = XMALLOC(keysize);
363 if (buf == NULL) {
364 return CRYPT_MEM;
365 }
366
367 /* make up random string */
368 if ( rng_make_prng( keysize, wprng, prng, NULL) != CRYPT_OK) {
369 err = CRYPT_ERROR_READPRNG;
370 goto error2;
371 }
372
373 if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) {
374 err = CRYPT_ERROR_READPRNG;
375 goto error2;
376 }
377
378 /* init parameters */
379 if ((err = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != CRYPT_OK) {
380 goto error;
381 }
382
383 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; }
384 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
385
386 /* load the x value */
387 if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; }
388 if ((err = mp_exptmod(g, key->x, p, key->y)) != CRYPT_OK) { goto error; }
389 key->type = PK_PRIVATE;
390
391 /* free up ram */
392 err = CRYPT_OK;
393 goto done;
394 error:
395 mp_clear_multi(key->x, key->y, NULL);
396 done:
397 mp_clear_multi(p, g, NULL);
398 error2:
399 #ifdef LTC_CLEAN_STACK
400 zeromem(buf, keysize);
401 #endif
402 XFREE(buf);
403 return err;
404 }
405
406 /**
407 Free the allocated ram for a DH key
408 @param key The key which you wish to free
409 */
410 void dh_free(dh_key *key)
411 {
412 LTC_ARGCHK(key != NULL);
413 if ( key->x ) {
414 mp_clear( key->x );
415 key->x = NULL;
416 }
417 if ( key->y ) {
418 mp_clear( key->y );
419 key->y = NULL;
420 }
421 }
422
423 /**
424 Export a DH key to a binary packet
425 @param out [out] The destination for the key
426 @param outlen [in/out] The max size and resulting size of the DH key
427 @param type Which type of key (PK_PRIVATE or PK_PUBLIC)
428 @param key The key you wish to export
429 @return CRYPT_OK if successful
430 */
431 int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
432 {
433 unsigned long y, z;
434 int err;
435
436 LTC_ARGCHK(out != NULL);
437 LTC_ARGCHK(outlen != NULL);
438 LTC_ARGCHK(key != NULL);
439
440 /* can we store the static header? */
441 if (*outlen < (PACKET_SIZE + 2)) {
442 return CRYPT_BUFFER_OVERFLOW;
443 }
444
445 if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
446 return CRYPT_PK_NOT_PRIVATE;
447 }
448
449 /* header */
450 y = PACKET_SIZE;
451
452 /* header */
453 out[y++] = type;
454 out[y++] = (unsigned char)(sets[key->idx].size / 8);
455
456 /* export y */
457 OUTPUT_BIGNUM(key->y, out, y, z);
458
459 if (type == PK_PRIVATE) {
460 /* export x */
461 OUTPUT_BIGNUM(key->x, out, y, z);
462 }
463
464 /* store header */
465 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_KEY);
466
467 /* store len */
468 *outlen = y;
469 return CRYPT_OK;
470 }
471
472 /**
473 Import a DH key from a binary packet
474 @param in The packet to read
475 @param inlen The length of the input packet
476 @param key [out] Where to import the key to
477 @return CRYPT_OK if successful, on error all allocated memory is freed automatically
478 */
479 int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
480 {
481 unsigned long x, y, s;
482 int err;
483
484 LTC_ARGCHK(in != NULL);
485 LTC_ARGCHK(key != NULL);
486
487 /* make sure valid length */
488 if ((2+PACKET_SIZE) > inlen) {
489 return CRYPT_INVALID_PACKET;
490 }
491
492 /* check type byte */
493 if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
494 return err;
495 }
496
497 /* init */
498 if ((err = mp_init_multi(&key->x, &key->y, NULL)) != CRYPT_OK) {
499 return err;
500 }
501
502 /* advance past packet header */
503 y = PACKET_SIZE;
504
505 /* key type, e.g. private, public */
506 key->type = (int)in[y++];
507
508 /* key size in bytes */
509 s = (unsigned long)in[y++] * 8;
510
511 for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
512 if (sets[x].size == 0) {
513 err = CRYPT_INVALID_KEYSIZE;
514 goto error;
515 }
516 key->idx = (int)x;
517
518 /* type check both values */
519 if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
520 err = CRYPT_PK_TYPE_MISMATCH;
521 goto error;
522 }
523
524 /* is the key idx valid? */
525 if (is_valid_idx(key->idx) != 1) {
526 err = CRYPT_PK_TYPE_MISMATCH;
527 goto error;
528 }
529
530 /* load public value g^x mod p*/
531 INPUT_BIGNUM(key->y, in, x, y, inlen);
532
533 if (key->type == PK_PRIVATE) {
534 INPUT_BIGNUM(key->x, in, x, y, inlen);
535 }
536
537 /* eliminate private key if public */
538 if (key->type == PK_PUBLIC) {
539 mp_clear(key->x);
540 key->x = NULL;
541 }
542
543 return CRYPT_OK;
544 error:
545 mp_clear_multi(key->y, key->x, NULL);
546 return err;
547 }
548
549 /**
550 Create a DH shared secret.
551 @param private_key The private DH key in the pair
552 @param public_key The public DH key in the pair
553 @param out [out] The destination of the shared data
554 @param outlen [in/out] The max size and resulting size of the shared data.
555 @return CRYPT_OK if successful
556 */
557 int dh_shared_secret(dh_key *private_key, dh_key *public_key,
558 unsigned char *out, unsigned long *outlen)
559 {
560 void *tmp, *p;
561 unsigned long x;
562 int err;
563
564 LTC_ARGCHK(private_key != NULL);
565 LTC_ARGCHK(public_key != NULL);
566 LTC_ARGCHK(out != NULL);
567 LTC_ARGCHK(outlen != NULL);
568
569 /* types valid? */
570 if (private_key->type != PK_PRIVATE) {
571 return CRYPT_PK_NOT_PRIVATE;
572 }
573
574 /* same idx? */
575 if (private_key->idx != public_key->idx) {
576 return CRYPT_PK_TYPE_MISMATCH;
577 }
578
579 /* compute y^x mod p */
580 if ((err = mp_init_multi(&tmp, &p, NULL)) != CRYPT_OK) {
581 return err;
582 }
583
584 if ((err = mp_read_radix(p, (char *)sets[private_key->idx].prime, 64)) != CRYPT_OK) { goto error; }
585 if ((err = mp_exptmod(public_key->y, private_key->x, p, tmp)) != CRYPT_OK) { goto error; }
586
587 /* enough space for output? */
588 x = (unsigned long)mp_unsigned_bin_size(tmp);
589 if (*outlen < x) {
590 err = CRYPT_BUFFER_OVERFLOW;
591 goto done;
592 }
593 if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { goto error; }
594 *outlen = x;
595 err = CRYPT_OK;
596 goto done;
597 error:
598 done:
599 mp_clear_multi(p, tmp, NULL);
600 return err;
601 }
602
603 #include "dh_sys.c.inc"
604
605 #endif
+0
-487
libtom-src/pk/dh/dh_sys.c.inc less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
9 */
10
11 /**
12 @file dh_sys.c
13 DH Crypto, Tom St Denis
14 */
15
16 /**
17 Encrypt a short symmetric key with a public DH key
18 @param in The symmetric key to encrypt
19 @param inlen The length of the key (octets)
20 @param out [out] The ciphertext
21 @param outlen [in/out] The max size and resulting size of the ciphertext
22 @param prng An active PRNG state
23 @param wprng The index of the PRNG desired
24 @param hash The index of the hash desired (must produce a digest of size >= the size of the plaintext)
25 @param key The public key you wish to encrypt with.
26 @return CRYPT_OK if successful
27 */
28 int dh_encrypt_key(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen,
30 prng_state *prng, int wprng, int hash,
31 dh_key *key)
32 {
33 unsigned char *pub_expt, *dh_shared, *skey;
34 dh_key pubkey;
35 unsigned long x, y, z, pubkeysize;
36 int err;
37
38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41 LTC_ARGCHK(key != NULL);
42
43 /* check that wprng/hash are not invalid */
44 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
45 return err;
46 }
47
48 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
49 return err;
50 }
51
52 if (inlen > hash_descriptor[hash].hashsize) {
53 return CRYPT_INVALID_HASH;
54 }
55
56 /* allocate memory */
57 pub_expt = XMALLOC(DH_BUF_SIZE);
58 dh_shared = XMALLOC(DH_BUF_SIZE);
59 skey = XMALLOC(MAXBLOCKSIZE);
60 if (pub_expt == NULL || dh_shared == NULL || skey == NULL) {
61 if (pub_expt != NULL) {
62 XFREE(pub_expt);
63 }
64 if (dh_shared != NULL) {
65 XFREE(dh_shared);
66 }
67 if (skey != NULL) {
68 XFREE(skey);
69 }
70 return CRYPT_MEM;
71 }
72
73 /* make a random key and export the public copy */
74 if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77
78 pubkeysize = DH_BUF_SIZE;
79 if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
80 dh_free(&pubkey);
81 goto LBL_ERR;
82 }
83
84 /* now check if the out buffer is big enough */
85 if (*outlen < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + inlen)) {
86 dh_free(&pubkey);
87 err = CRYPT_BUFFER_OVERFLOW;
88 goto LBL_ERR;
89 }
90
91 /* make random key */
92
93 x = DH_BUF_SIZE;
94 if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) {
95 dh_free(&pubkey);
96 goto LBL_ERR;
97 }
98 dh_free(&pubkey);
99
100 z = MAXBLOCKSIZE;
101 if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104
105 /* store header */
106 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
107
108 /* output header */
109 y = PACKET_SIZE;
110
111 /* size of hash name and the name itself */
112 out[y++] = hash_descriptor[hash].ID;
113
114 /* length of DH pubkey and the key itself */
115 STORE32L(pubkeysize, out+y);
116 y += 4;
117 for (x = 0; x < pubkeysize; x++, y++) {
118 out[y] = pub_expt[x];
119 }
120
121 /* Store the encrypted key */
122 STORE32L(inlen, out+y);
123 y += 4;
124
125 for (x = 0; x < inlen; x++, y++) {
126 out[y] = skey[x] ^ in[x];
127 }
128 *outlen = y;
129
130 err = CRYPT_OK;
131 LBL_ERR:
132 #ifdef LTC_CLEAN_STACK
133 /* clean up */
134 zeromem(pub_expt, DH_BUF_SIZE);
135 zeromem(dh_shared, DH_BUF_SIZE);
136 zeromem(skey, MAXBLOCKSIZE);
137 #endif
138 XFREE(skey);
139 XFREE(dh_shared);
140 XFREE(pub_expt);
141
142 return err;
143 }
144
145 /**
146 Decrypt a DH encrypted symmetric key
147 @param in The DH encrypted packet
148 @param inlen The length of the DH encrypted packet
149 @param out The plaintext
150 @param outlen [in/out] The max size and resulting size of the plaintext
151 @param key The private DH key corresponding to the public key that encrypted the plaintext
152 @return CRYPT_OK if successful
153 */
154 int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
155 unsigned char *out, unsigned long *outlen,
156 dh_key *key)
157 {
158 unsigned char *shared_secret, *skey;
159 unsigned long x, y, z, keysize;
160 int hash, err;
161 dh_key pubkey;
162
163 LTC_ARGCHK(in != NULL);
164 LTC_ARGCHK(out != NULL);
165 LTC_ARGCHK(outlen != NULL);
166 LTC_ARGCHK(key != NULL);
167
168 /* right key type? */
169 if (key->type != PK_PRIVATE) {
170 return CRYPT_PK_NOT_PRIVATE;
171 }
172
173 /* allocate ram */
174 shared_secret = XMALLOC(DH_BUF_SIZE);
175 skey = XMALLOC(MAXBLOCKSIZE);
176 if (shared_secret == NULL || skey == NULL) {
177 if (shared_secret != NULL) {
178 XFREE(shared_secret);
179 }
180 if (skey != NULL) {
181 XFREE(skey);
182 }
183 return CRYPT_MEM;
184 }
185
186 /* check if initial header should fit */
187 if (inlen < PACKET_SIZE+1+4+4) {
188 err = CRYPT_INVALID_PACKET;
189 goto LBL_ERR;
190 } else {
191 inlen -= PACKET_SIZE+1+4+4;
192 }
193
194 /* is header correct? */
195 if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
196 goto LBL_ERR;
197 }
198
199 /* now lets get the hash name */
200 y = PACKET_SIZE;
201 hash = find_hash_id(in[y++]);
202 if (hash == -1) {
203 err = CRYPT_INVALID_HASH;
204 goto LBL_ERR;
205 }
206
207 /* get public key */
208 LOAD32L(x, in+y);
209
210 /* now check if the imported key will fit */
211 if (inlen < x) {
212 err = CRYPT_INVALID_PACKET;
213 goto LBL_ERR;
214 } else {
215 inlen -= x;
216 }
217
218 y += 4;
219 if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) {
220 goto LBL_ERR;
221 }
222 y += x;
223
224 /* make shared key */
225 x = DH_BUF_SIZE;
226 if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
227 dh_free(&pubkey);
228 goto LBL_ERR;
229 }
230 dh_free(&pubkey);
231
232 z = MAXBLOCKSIZE;
233 if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
234 goto LBL_ERR;
235 }
236
237 /* load in the encrypted key */
238 LOAD32L(keysize, in+y);
239
240 /* will the out fit as part of the input */
241 if (inlen < keysize) {
242 err = CRYPT_INVALID_PACKET;
243 goto LBL_ERR;
244 } else {
245 inlen -= keysize;
246 }
247
248 if (keysize > *outlen) {
249 err = CRYPT_BUFFER_OVERFLOW;
250 goto LBL_ERR;
251 }
252 y += 4;
253
254 *outlen = keysize;
255
256 for (x = 0; x < keysize; x++, y++) {
257 out[x] = skey[x] ^ in[y];
258 }
259
260 err = CRYPT_OK;
261 LBL_ERR:
262 #ifdef LTC_CLEAN_STACK
263 zeromem(shared_secret, DH_BUF_SIZE);
264 zeromem(skey, MAXBLOCKSIZE);
265 #endif
266
267 XFREE(skey);
268 XFREE(shared_secret);
269
270 return err;
271 }
272
273 /* perform an ElGamal Signature of a hash
274 *
275 * The math works as follows. x is the private key, M is the message to sign
276
277 1. pick a random k
278 2. compute a = g^k mod p
279 3. compute b = (M - xa)/k mod p
280 4. Send (a,b)
281
282 Now to verify with y=g^x mod p, a and b
283
284 1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k)
285 = g^(xa + (M - xa))
286 = g^M [all mod p]
287
288 2. Compare against g^M mod p [based on input hash].
289 3. If result of #2 == result of #1 then signature valid
290 */
291
292 /**
293 Sign a message digest using a DH private key
294 @param in The data to sign
295 @param inlen The length of the input (octets)
296 @param out [out] The destination of the signature
297 @param outlen [in/out] The max size and resulting size of the output
298 @param prng An active PRNG state
299 @param wprng The index of the PRNG desired
300 @param key A private DH key
301 @return CRYPT_OK if successful
302 */
303 int dh_sign_hash(const unsigned char *in, unsigned long inlen,
304 unsigned char *out, unsigned long *outlen,
305 prng_state *prng, int wprng, dh_key *key)
306 {
307 void *a, *b, *k, *m, *g, *p, *p1, *tmp;
308 unsigned char *buf;
309 unsigned long x, y;
310 int err;
311
312 LTC_ARGCHK(in != NULL);
313 LTC_ARGCHK(out != NULL);
314 LTC_ARGCHK(outlen != NULL);
315 LTC_ARGCHK(key != NULL);
316
317 /* check parameters */
318 if (key->type != PK_PRIVATE) {
319 return CRYPT_PK_NOT_PRIVATE;
320 }
321
322 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
323 return err;
324 }
325
326 /* is the IDX valid ? */
327 if (is_valid_idx(key->idx) != 1) {
328 return CRYPT_PK_INVALID_TYPE;
329 }
330
331 /* allocate ram for buf */
332 buf = XMALLOC(520);
333
334 /* make up a random value k,
335 * since the order of the group is prime
336 * we need not check if gcd(k, r) is 1
337 */
338 if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) !=
339 (unsigned long)(sets[key->idx].size)) {
340 err = CRYPT_ERROR_READPRNG;
341 goto LBL_ERR;
342 }
343
344 /* init bignums */
345 if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != CRYPT_OK) {
346 goto LBL_ERR;
347 }
348
349 /* load k and m */
350 if ((err = mp_read_unsigned_bin(m, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; }
351 if ((err = mp_read_unsigned_bin(k, buf, sets[key->idx].size)) != CRYPT_OK) { goto error; }
352
353 /* load g, p and p1 */
354 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; }
355 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
356 if ((err = mp_sub_d(p, 1, p1)) != CRYPT_OK) { goto error; }
357 if ((err = mp_div_2(p1, p1)) != CRYPT_OK) { goto error; } /* p1 = (p-1)/2 */
358
359 /* now get a = g^k mod p */
360 if ((err = mp_exptmod(g, k, p, a)) != CRYPT_OK) { goto error; }
361
362 /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */
363 if ((err = mp_invmod(k, p1, k)) != CRYPT_OK) { goto error; } /* k = 1/k mod p1 */
364 if ((err = mp_mulmod(a, key->x, p1, tmp)) != CRYPT_OK) { goto error; } /* tmp = xa */
365 if ((err = mp_submod(m, tmp, p1, tmp)) != CRYPT_OK) { goto error; } /* tmp = M - xa */
366 if ((err = mp_mulmod(k, tmp, p1, b)) != CRYPT_OK) { goto error; } /* b = (M - xa)/k */
367
368 /* check for overflow */
369 if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(a) + mp_unsigned_bin_size(b)) > *outlen) {
370 err = CRYPT_BUFFER_OVERFLOW;
371 goto LBL_ERR;
372 }
373
374 /* store header */
375 y = PACKET_SIZE;
376
377 /* now store them both (a,b) */
378 x = (unsigned long)mp_unsigned_bin_size(a);
379 STORE32L(x, out+y); y += 4;
380 if ((err = mp_to_unsigned_bin(a, out+y)) != CRYPT_OK) { goto error; }
381 y += x;
382
383 x = (unsigned long)mp_unsigned_bin_size(b);
384 STORE32L(x, out+y); y += 4;
385 if ((err = mp_to_unsigned_bin(b, out+y)) != CRYPT_OK) { goto error; }
386 y += x;
387
388 /* check if size too big */
389 if (*outlen < y) {
390 err = CRYPT_BUFFER_OVERFLOW;
391 goto LBL_ERR;
392 }
393
394 /* store header */
395 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED);
396 *outlen = y;
397
398 err = CRYPT_OK;
399 goto LBL_ERR;
400 error:
401 LBL_ERR:
402 mp_clear_multi(tmp, p1, g, p, m, k, b, a, NULL);
403
404 XFREE(buf);
405
406 return err;
407 }
408
409
410 /**
411 Verify the signature given
412 @param sig The signature
413 @param siglen The length of the signature (octets)
414 @param hash The hash that was signed
415 @param hashlen The length of the hash (octets)
416 @param stat [out] Result of signature comparison, 1==valid, 0==invalid
417 @param key The public DH key that signed the hash
418 @return CRYPT_OK if succsessful (even if signature is invalid)
419 */
420 int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
421 const unsigned char *hash, unsigned long hashlen,
422 int *stat, dh_key *key)
423 {
424 void *a, *b, *p, *g, *m, *tmp;
425 unsigned long x, y;
426 int err;
427
428 LTC_ARGCHK(sig != NULL);
429 LTC_ARGCHK(hash != NULL);
430 LTC_ARGCHK(stat != NULL);
431 LTC_ARGCHK(key != NULL);
432
433 /* default to invalid */
434 *stat = 0;
435
436 /* check initial input length */
437 if (siglen < PACKET_SIZE+4+4) {
438 return CRYPT_INVALID_PACKET;
439 }
440
441 /* header ok? */
442 if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) {
443 return err;
444 }
445
446 /* get hash out of packet */
447 y = PACKET_SIZE;
448
449 /* init all bignums */
450 if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != CRYPT_OK) {
451 return err;
452 }
453
454 /* load a and b */
455 INPUT_BIGNUM(a, sig, x, y, siglen);
456 INPUT_BIGNUM(b, sig, x, y, siglen);
457
458 /* load p and g */
459 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error1; }
460 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error1; }
461
462 /* load m */
463 if ((err = mp_read_unsigned_bin(m, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error1; }
464
465 /* find g^m mod p */
466 if ((err = mp_exptmod(g, m, p, m)) != CRYPT_OK) { goto error1; } /* m = g^m mod p */
467
468 /* find y^a * a^b */
469 if ((err = mp_exptmod(key->y, a, p, tmp)) != CRYPT_OK) { goto error1; } /* tmp = y^a mod p */
470 if ((err = mp_exptmod(a, b, p, a)) != CRYPT_OK) { goto error1; } /* a = a^b mod p */
471 if ((err = mp_mulmod(a, tmp, p, a)) != CRYPT_OK) { goto error1; } /* a = y^a * a^b mod p */
472
473 /* y^a * a^b == g^m ??? */
474 if (mp_cmp(a, m) == 0) {
475 *stat = 1;
476 }
477
478 /* clean up */
479 err = CRYPT_OK;
480 goto done;
481 error1:
482 error:
483 done:
484 mp_clear_multi(tmp, m, g, p, b, a, NULL);
485 return err;
486 }
+0
-139
libtom-src/pk/dsa/dsa_decrypt_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_decrypt_key.c
14 DSA Crypto, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Decrypt an DSA encrypted key
21 @param in The ciphertext
22 @param inlen The length of the ciphertext (octets)
23 @param out [out] The plaintext
24 @param outlen [in/out] The max size and resulting size of the plaintext
25 @param key The corresponding private DSA key
26 @return CRYPT_OK if successful
27 */
28 int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen,
30 dsa_key *key)
31 {
32 unsigned char *skey, *expt;
33 void *g_pub;
34 unsigned long x, y, hashOID[32];
35 int hash, err;
36 ltc_asn1_list decode[3];
37
38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41 LTC_ARGCHK(key != NULL);
42
43 /* right key type? */
44 if (key->type != PK_PRIVATE) {
45 return CRYPT_PK_NOT_PRIVATE;
46 }
47
48 /* decode to find out hash */
49 LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
50
51 if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
52 return err;
53 }
54
55 hash = find_hash_oid(hashOID, decode[0].size);
56 if (hash_is_valid(hash) != CRYPT_OK) {
57 return CRYPT_INVALID_PACKET;
58 }
59
60 /* we now have the hash! */
61
62 if ((err = mp_init(&g_pub)) != CRYPT_OK) {
63 return err;
64 }
65
66 /* allocate memory */
67 expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
68 skey = XMALLOC(MAXBLOCKSIZE);
69 if (expt == NULL || skey == NULL) {
70 if (expt != NULL) {
71 XFREE(expt);
72 }
73 if (skey != NULL) {
74 XFREE(skey);
75 }
76 mp_clear(g_pub);
77 return CRYPT_MEM;
78 }
79
80 LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL);
81 LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
82
83 /* read the structure in now */
84 if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
85 goto LBL_ERR;
86 }
87
88 /* make shared key */
89 x = mp_unsigned_bin_size(key->p) + 1;
90 if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) {
91 goto LBL_ERR;
92 }
93
94 y = MIN(mp_unsigned_bin_size(key->p) + 1, MAXBLOCKSIZE);
95 if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) {
96 goto LBL_ERR;
97 }
98
99 /* ensure the hash of the shared secret is at least as big as the encrypt itself */
100 if (decode[2].size > y) {
101 err = CRYPT_INVALID_PACKET;
102 goto LBL_ERR;
103 }
104
105 /* avoid buffer overflow */
106 if (*outlen < decode[2].size) {
107 *outlen = decode[2].size;
108 err = CRYPT_BUFFER_OVERFLOW;
109 goto LBL_ERR;
110 }
111
112 /* Decrypt the key */
113 for (x = 0; x < decode[2].size; x++) {
114 out[x] = expt[x] ^ skey[x];
115 }
116 *outlen = x;
117
118 err = CRYPT_OK;
119 LBL_ERR:
120 #ifdef LTC_CLEAN_STACK
121 zeromem(expt, mp_unsigned_bin_size(key->p) + 1);
122 zeromem(skey, MAXBLOCKSIZE);
123 #endif
124
125 XFREE(expt);
126 XFREE(skey);
127
128 mp_clear(g_pub);
129
130 return err;
131 }
132
133 #endif
134
135 /* $Source$ */
136 /* $Revision$ */
137 /* $Date$ */
138
+0
-135
libtom-src/pk/dsa/dsa_encrypt_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_encrypt_key.c
14 DSA Crypto, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Encrypt a symmetric key with DSA
21 @param in The symmetric key you want to encrypt
22 @param inlen The length of the key to encrypt (octets)
23 @param out [out] The destination for the ciphertext
24 @param outlen [in/out] The max size and resulting size of the ciphertext
25 @param prng An active PRNG state
26 @param wprng The index of the PRNG you wish to use
27 @param hash The index of the hash you want to use
28 @param key The DSA key you want to encrypt to
29 @return CRYPT_OK if successful
30 */
31 int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long *outlen,
33 prng_state *prng, int wprng, int hash,
34 dsa_key *key)
35 {
36 unsigned char *expt, *skey;
37 void *g_pub, *g_priv;
38 unsigned long x, y;
39 int err;
40
41 LTC_ARGCHK(in != NULL);
42 LTC_ARGCHK(out != NULL);
43 LTC_ARGCHK(outlen != NULL);
44 LTC_ARGCHK(key != NULL);
45
46 /* check that wprng/cipher/hash are not invalid */
47 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
48 return err;
49 }
50
51 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
52 return err;
53 }
54
55 if (inlen > hash_descriptor[hash].hashsize) {
56 return CRYPT_INVALID_HASH;
57 }
58
59 /* make a random key and export the public copy */
60 if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) {
61 return err;
62 }
63
64 expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
65 skey = XMALLOC(MAXBLOCKSIZE);
66 if (expt == NULL || skey == NULL) {
67 if (expt != NULL) {
68 XFREE(expt);
69 }
70 if (skey != NULL) {
71 XFREE(skey);
72 }
73 mp_clear_multi(g_pub, g_priv, NULL);
74 return CRYPT_MEM;
75 }
76
77 /* make a random x, g^x pair */
78 x = mp_unsigned_bin_size(key->q);
79 if (prng_descriptor[wprng].read(expt, x, prng) != x) {
80 err = CRYPT_ERROR_READPRNG;
81 goto LBL_ERR;
82 }
83
84 /* load x */
85 if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) {
86 goto LBL_ERR;
87 }
88
89 /* compute y */
90 if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) {
91 goto LBL_ERR;
92 }
93
94 /* make random key */
95 x = mp_unsigned_bin_size(key->p) + 1;
96 if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) {
97 goto LBL_ERR;
98 }
99
100 y = MAXBLOCKSIZE;
101 if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104
105 /* Encrypt key */
106 for (x = 0; x < inlen; x++) {
107 skey[x] ^= in[x];
108 }
109
110 err = der_encode_sequence_multi(out, outlen,
111 LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
112 LTC_ASN1_INTEGER, 1UL, g_pub,
113 LTC_ASN1_OCTET_STRING, inlen, skey,
114 LTC_ASN1_EOL, 0UL, NULL);
115
116 LBL_ERR:
117 #ifdef LTC_CLEAN_STACK
118 /* clean up */
119 zeromem(expt, mp_unsigned_bin_size(key->p) + 1);
120 zeromem(skey, MAXBLOCKSIZE);
121 #endif
122
123 XFREE(skey);
124 XFREE(expt);
125
126 mp_clear_multi(g_pub, g_priv, NULL);
127 return err;
128 }
129
130 #endif
131 /* $Source$ */
132 /* $Revision$ */
133 /* $Date$ */
134
+0
-99
libtom-src/pk/dsa/dsa_export.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_export.c
14 DSA implementation, export key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Export a DSA key to a binary packet
21 @param out [out] Where to store the packet
22 @param outlen [in/out] The max size and resulting size of the packet
23 @param type The type of key to export (PK_PRIVATE or PK_PUBLIC)
24 @param key The key to export
25 @return CRYPT_OK if successful
26 */
27 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key)
28 {
29 unsigned long zero=0;
30 int err;
31
32 LTC_ARGCHK(out != NULL);
33 LTC_ARGCHK(outlen != NULL);
34 LTC_ARGCHK(key != NULL);
35
36 /* can we store the static header? */
37 if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
38 return CRYPT_PK_TYPE_MISMATCH;
39 }
40
41 if (type != PK_PUBLIC && type != PK_PRIVATE) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 /* This encoding is different from the one in original
46 * libtomcrypt. It uses a compatible encoding with gnutls
47 * and openssl
48 */
49
50 if (type == PK_PRIVATE) {
51 return der_encode_sequence_multi(out, outlen,
52 LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
53 LTC_ASN1_INTEGER, 1UL, key->p,
54 LTC_ASN1_INTEGER, 1UL, key->q,
55 LTC_ASN1_INTEGER, 1UL, key->g,
56 LTC_ASN1_INTEGER, 1UL, key->y,
57 LTC_ASN1_INTEGER, 1UL, key->x,
58 LTC_ASN1_EOL, 0UL, NULL);
59 } else {
60 unsigned long tmplen = (mp_count_bits(key->y)/8)+8;
61 unsigned char* tmp = XMALLOC(tmplen);
62 ltc_asn1_list int_list[3];
63
64 if (tmp == NULL) {
65 return CRYPT_MEM;
66 }
67
68 err = der_encode_integer(key->y, tmp, &tmplen);
69 if (err != CRYPT_OK) {
70 goto error;
71 }
72
73 int_list[0].data = key->p;
74 int_list[0].size = 1UL;
75 int_list[0].type = LTC_ASN1_INTEGER;
76 int_list[1].data = key->q;
77 int_list[1].size = 1UL;
78 int_list[1].type = LTC_ASN1_INTEGER;
79 int_list[2].data = key->g;
80 int_list[2].size = 1UL;
81 int_list[2].type = LTC_ASN1_INTEGER;
82
83 err = der_encode_subject_public_key_info(out, outlen,
84 PKA_DSA, tmp, tmplen,
85 LTC_ASN1_SEQUENCE, int_list, sizeof(int_list)/sizeof(int_list[0]));
86
87 error:
88 XFREE(tmp);
89 return err;
90 }
91 }
92
93 #endif
94
95
96 /* $Source$ */
97 /* $Revision$ */
98 /* $Date$ */
+0
-34
libtom-src/pk/dsa/dsa_free.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_free.c
14 DSA implementation, free a DSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Free a DSA key
21 @param key The key to free from memory
22 */
23 void dsa_free(dsa_key *key)
24 {
25 LTC_ARGCHKVD(key != NULL);
26 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
27 }
28
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
+0
-100
libtom-src/pk/dsa/dsa_import.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_import.c
14 DSA implementation, import a DSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Import a DSA key
21 @param in The binary packet to import from
22 @param inlen The length of the binary packet
23 @param key [out] Where to store the imported key
24 @return CRYPT_OK if successful, upon error this function will free all allocated memory
25 */
26 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
27 {
28 int err;
29 unsigned long zero = 0;
30 unsigned char* tmpbuf = NULL;
31
32 LTC_ARGCHK(in != NULL);
33 LTC_ARGCHK(key != NULL);
34 LTC_ARGCHK(ltc_mp.name != NULL);
35
36 /* init key */
37 if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {
38 return CRYPT_MEM;
39 }
40
41 /* get key type */
42 if ((err = der_decode_sequence_multi(in, inlen,
43 LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
44 LTC_ASN1_INTEGER, 1UL, key->p,
45 LTC_ASN1_INTEGER, 1UL, key->q,
46 LTC_ASN1_INTEGER, 1UL, key->g,
47 LTC_ASN1_INTEGER, 1UL, key->y,
48 LTC_ASN1_INTEGER, 1UL, key->x,
49 LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
50
51 key->type = PK_PRIVATE;
52 } else { /* public */
53 ltc_asn1_list params[3];
54 unsigned long tmpbuf_len = MAX_RSA_SIZE*8;
55
56 LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
57 LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
58 LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);
59
60 tmpbuf = XCALLOC(1, tmpbuf_len);
61 if (tmpbuf == NULL) {
62 err = CRYPT_MEM;
63 goto LBL_ERR;
64 }
65
66 err = der_decode_subject_public_key_info(in, inlen,
67 PKA_DSA, tmpbuf, &tmpbuf_len,
68 LTC_ASN1_SEQUENCE, params, 3);
69 if (err != CRYPT_OK) {
70 goto LBL_ERR;
71 }
72
73 if ((err=der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76
77 XFREE(tmpbuf);
78 key->type = PK_PUBLIC;
79 }
80 key->qord = mp_unsigned_bin_size(key->q);
81
82 if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 ||
83 (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) {
84 err = CRYPT_INVALID_PACKET;
85 goto LBL_ERR;
86 }
87
88 return CRYPT_OK;
89 LBL_ERR:
90 XFREE(tmpbuf);
91 mp_clear_multi(key->p, key->g, key->q, key->x, key->y, NULL);
92 return err;
93 }
94
95 #endif
96
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
+0
-137
libtom-src/pk/dsa/dsa_make_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_make_key.c
14 DSA implementation, generate a DSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Create a DSA key
21 @param prng An active PRNG state
22 @param wprng The index of the PRNG desired
23 @param group_size Size of the multiplicative group (octets)
24 @param modulus_size Size of the modulus (octets)
25 @param key [out] Where to store the created key
26 @return CRYPT_OK if successful, upon error this function will free all allocated memory
27 */
28 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
29 {
30 void *tmp, *tmp2;
31 int err, res;
32 unsigned char *buf;
33
34 LTC_ARGCHK(key != NULL);
35 LTC_ARGCHK(ltc_mp.name != NULL);
36
37 /* check prng */
38 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* check size */
43 if (group_size >= LTC_MDSA_MAX_GROUP || group_size <= 15 ||
44 group_size >= modulus_size || (modulus_size - group_size) >= LTC_MDSA_DELTA) {
45 return CRYPT_INVALID_ARG;
46 }
47
48 /* allocate ram */
49 buf = XMALLOC(LTC_MDSA_DELTA);
50 if (buf == NULL) {
51 return CRYPT_MEM;
52 }
53
54 /* init mp_ints */
55 if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) {
56 XFREE(buf);
57 return err;
58 }
59
60 /* make our prime q */
61 if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK) { goto error; }
62
63 /* double q */
64 if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK) { goto error; }
65
66 /* now make a random string and multply it against q */
67 if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) {
68 err = CRYPT_ERROR_READPRNG;
69 goto error;
70 }
71
72 /* force magnitude */
73 buf[0] |= 0xC0;
74
75 /* force even */
76 buf[modulus_size - group_size - 1] &= ~1;
77
78 if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; }
79 if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK) { goto error; }
80 if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK) { goto error; }
81
82 /* now loop until p is prime */
83 for (;;) {
84 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { goto error; }
85 if (res == LTC_MP_YES) break;
86
87 /* add 2q to p and 2 to tmp2 */
88 if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK) { goto error; }
89 if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK) { goto error; }
90 }
91
92 /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */
93 mp_set(key->g, 1);
94
95 do {
96 if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK) { goto error; }
97 if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK) { goto error; }
98 } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ);
99
100 /* at this point tmp generates a group of order q mod p */
101 mp_exch(tmp, key->g);
102
103 /* so now we have our DH structure, generator g, order q, modulus p
104 Now we need a random exponent [mod q] and it's power g^x mod p
105 */
106 do {
107 if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) {
108 err = CRYPT_ERROR_READPRNG;
109 goto error;
110 }
111 if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK) { goto error; }
112 } while (mp_cmp_d(key->x, 1) != LTC_MP_GT);
113 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto error; }
114
115 key->type = PK_PRIVATE;
116 key->qord = group_size;
117
118 #ifdef LTC_CLEAN_STACK
119 zeromem(buf, LTC_MDSA_DELTA);
120 #endif
121
122 err = CRYPT_OK;
123 goto done;
124 error:
125 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
126 done:
127 mp_clear_multi(tmp, tmp2, NULL);
128 XFREE(buf);
129 return err;
130 }
131
132 #endif
133
134 /* $Source$ */
135 /* $Revision$ */
136 /* $Date$ */
+0
-72
libtom-src/pk/dsa/dsa_shared_secret.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_shared_secret.c
14 DSA Crypto, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Create a DSA shared secret between two keys
21 @param private_key The private DSA key (the exponent)
22 @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt)
23 @param public_key The public key
24 @param out [out] Destination of the shared secret
25 @param outlen [in/out] The max size and resulting size of the shared secret
26 @return CRYPT_OK if successful
27 */
28 int dsa_shared_secret(void *private_key, void *base,
29 dsa_key *public_key,
30 unsigned char *out, unsigned long *outlen)
31 {
32 unsigned long x;
33 void *res;
34 int err;
35
36 LTC_ARGCHK(private_key != NULL);
37 LTC_ARGCHK(public_key != NULL);
38 LTC_ARGCHK(out != NULL);
39 LTC_ARGCHK(outlen != NULL);
40
41 /* make new point */
42 if ((err = mp_init(&res)) != CRYPT_OK) {
43 return err;
44 }
45
46 if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) {
47 mp_clear(res);
48 return err;
49 }
50
51 x = (unsigned long)mp_unsigned_bin_size(res);
52 if (*outlen < x) {
53 *outlen = x;
54 err = CRYPT_BUFFER_OVERFLOW;
55 goto done;
56 }
57 zeromem(out, x);
58 if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; }
59
60 err = CRYPT_OK;
61 *outlen = x;
62 done:
63 mp_clear(res);
64 return err;
65 }
66
67 #endif
68 /* $Source$ */
69 /* $Revision$ */
70 /* $Date$ */
71
+0
-156
libtom-src/pk/dsa/dsa_sign_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_sign_hash.c
14 DSA implementation, sign a hash, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Sign a hash with DSA
21 @param in The hash to sign
22 @param inlen The length of the hash to sign
23 @param r The "r" integer of the signature (caller must initialize with mp_init() first)
24 @param s The "s" integer of the signature (caller must initialize with mp_init() first)
25 @param prng An active PRNG state
26 @param wprng The index of the PRNG desired
27 @param key A private DSA key
28 @return CRYPT_OK if successful
29 */
30 int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
31 void *r, void *s,
32 prng_state *prng, int wprng, dsa_key *key)
33 {
34 void *k, *kinv, *tmp;
35 unsigned char *buf;
36 int err;
37
38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(r != NULL);
40 LTC_ARGCHK(s != NULL);
41 LTC_ARGCHK(key != NULL);
42
43 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
44 return err;
45 }
46 if (key->type != PK_PRIVATE) {
47 return CRYPT_PK_NOT_PRIVATE;
48 }
49
50 /* check group order size */
51 if (key->qord >= LTC_MDSA_MAX_GROUP) {
52 return CRYPT_INVALID_ARG;
53 }
54
55 buf = XMALLOC(LTC_MDSA_MAX_GROUP);
56 if (buf == NULL) {
57 return CRYPT_MEM;
58 }
59
60 /* Init our temps */
61 if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; }
62
63 retry:
64
65 do {
66 /* gen random k */
67 if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
68 err = CRYPT_ERROR_READPRNG;
69 goto error;
70 }
71
72 /* read k */
73 if ((err = mp_read_unsigned_bin(k, buf, key->qord)) != CRYPT_OK) { goto error; }
74
75 /* k > 1 ? */
76 if (mp_cmp_d(k, 1) != LTC_MP_GT) { goto retry; }
77
78 /* test gcd */
79 if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; }
80 } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ);
81
82 /* now find 1/k mod q */
83 if ((err = mp_invmod(k, key->q, kinv)) != CRYPT_OK) { goto error; }
84
85 /* now find r = g^k mod p mod q */
86 if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; }
87 if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; }
88
89 if (mp_iszero(r) == LTC_MP_YES) { goto retry; }
90
91 /* now find s = (in + xr)/k mod q */
92 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; }
93 if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; }
94 if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { goto error; }
95 if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; }
96
97 if (mp_iszero(s) == LTC_MP_YES) { goto retry; }
98
99 err = CRYPT_OK;
100 error:
101 mp_clear_multi(k, kinv, tmp, NULL);
102 ERRBUF:
103 #ifdef LTC_CLEAN_STACK
104 zeromem(buf, LTC_MDSA_MAX_GROUP);
105 #endif
106 XFREE(buf);
107 return err;
108 }
109
110 /**
111 Sign a hash with DSA
112 @param in The hash to sign
113 @param inlen The length of the hash to sign
114 @param out [out] Where to store the signature
115 @param outlen [in/out] The max size and resulting size of the signature
116 @param prng An active PRNG state
117 @param wprng The index of the PRNG desired
118 @param key A private DSA key
119 @return CRYPT_OK if successful
120 */
121 int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
122 unsigned char *out, unsigned long *outlen,
123 prng_state *prng, int wprng, dsa_key *key)
124 {
125 void *r, *s;
126 int err;
127
128 LTC_ARGCHK(in != NULL);
129 LTC_ARGCHK(out != NULL);
130 LTC_ARGCHK(outlen != NULL);
131 LTC_ARGCHK(key != NULL);
132
133 if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) {
134 return CRYPT_MEM;
135 }
136
137 if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) {
138 goto error;
139 }
140
141 err = der_encode_sequence_multi(out, outlen,
142 LTC_ASN1_INTEGER, 1UL, r,
143 LTC_ASN1_INTEGER, 1UL, s,
144 LTC_ASN1_EOL, 0UL, NULL);
145
146 error:
147 mp_clear_multi(r, s, NULL);
148 return err;
149 }
150
151 #endif
152
153 /* $Source$ */
154 /* $Revision$ */
155 /* $Date$ */
+0
-126
libtom-src/pk/dsa/dsa_verify_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_verify_hash.c
14 DSA implementation, verify a signature, Tom St Denis
15 */
16
17
18 #ifdef LTC_MDSA
19
20 /**
21 Verify a DSA signature
22 @param r DSA "r" parameter
23 @param s DSA "s" parameter
24 @param hash The hash that was signed
25 @param hashlen The length of the hash that was signed
26 @param stat [out] The result of the signature verification, 1==valid, 0==invalid
27 @param key The corresponding public DH key
28 @return CRYPT_OK if successful (even if the signature is invalid)
29 */
30 int dsa_verify_hash_raw( void *r, void *s,
31 const unsigned char *hash, unsigned long hashlen,
32 int *stat, dsa_key *key)
33 {
34 void *w, *v, *u1, *u2;
35 int err;
36
37 LTC_ARGCHK(r != NULL);
38 LTC_ARGCHK(s != NULL);
39 LTC_ARGCHK(stat != NULL);
40 LTC_ARGCHK(key != NULL);
41
42 /* default to invalid signature */
43 *stat = 0;
44
45 /* init our variables */
46 if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != CRYPT_OK) {
47 return err;
48 }
49
50 /* neither r or s can be null or >q*/
51 if (mp_iszero(r) == LTC_MP_YES || mp_iszero(s) == LTC_MP_YES || mp_cmp(r, key->q) != LTC_MP_LT || mp_cmp(s, key->q) != LTC_MP_LT) {
52 err = CRYPT_INVALID_PACKET;
53 goto error;
54 }
55
56 /* w = 1/s mod q */
57 if ((err = mp_invmod(s, key->q, w)) != CRYPT_OK) { goto error; }
58
59 /* u1 = m * w mod q */
60 if ((err = mp_read_unsigned_bin(u1, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; }
61 if ((err = mp_mulmod(u1, w, key->q, u1)) != CRYPT_OK) { goto error; }
62
63 /* u2 = r*w mod q */
64 if ((err = mp_mulmod(r, w, key->q, u2)) != CRYPT_OK) { goto error; }
65
66 /* v = g^u1 * y^u2 mod p mod q */
67 if ((err = mp_exptmod(key->g, u1, key->p, u1)) != CRYPT_OK) { goto error; }
68 if ((err = mp_exptmod(key->y, u2, key->p, u2)) != CRYPT_OK) { goto error; }
69 if ((err = mp_mulmod(u1, u2, key->p, v)) != CRYPT_OK) { goto error; }
70 if ((err = mp_mod(v, key->q, v)) != CRYPT_OK) { goto error; }
71
72 /* if r = v then we're set */
73 if (mp_cmp(r, v) == LTC_MP_EQ) {
74 *stat = 1;
75 }
76
77 err = CRYPT_OK;
78 error:
79 mp_clear_multi(w, v, u1, u2, NULL);
80 return err;
81 }
82
83 /**
84 Verify a DSA signature
85 @param sig The signature
86 @param siglen The length of the signature (octets)
87 @param hash The hash that was signed
88 @param hashlen The length of the hash that was signed
89 @param stat [out] The result of the signature verification, 1==valid, 0==invalid
90 @param key The corresponding public DH key
91 @return CRYPT_OK if successful (even if the signature is invalid)
92 */
93 int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
94 const unsigned char *hash, unsigned long hashlen,
95 int *stat, dsa_key *key)
96 {
97 int err;
98 void *r, *s;
99
100 if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) {
101 return CRYPT_MEM;
102 }
103
104 /* decode the sequence */
105 if ((err = der_decode_sequence_multi(sig, siglen,
106 LTC_ASN1_INTEGER, 1UL, r,
107 LTC_ASN1_INTEGER, 1UL, s,
108 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
109 goto LBL_ERR;
110 }
111
112 /* do the op */
113 err = dsa_verify_hash_raw(r, s, hash, hashlen, stat, key);
114
115 LBL_ERR:
116 mp_clear_multi(r, s, NULL);
117 return err;
118 }
119
120 #endif
121
122
123 /* $Source$ */
124 /* $Revision$ */
125 /* $Date$ */
+0
-100
libtom-src/pk/dsa/dsa_verify_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_verify_key.c
14 DSA implementation, verify a key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Verify a DSA key for validity
21 @param key The key to verify
22 @param stat [out] Result of test, 1==valid, 0==invalid
23 @return CRYPT_OK if successful
24 */
25 int dsa_verify_key(dsa_key *key, int *stat)
26 {
27 void *tmp, *tmp2;
28 int res, err;
29
30 LTC_ARGCHK(key != NULL);
31 LTC_ARGCHK(stat != NULL);
32
33 /* default to an invalid key */
34 *stat = 0;
35
36 /* first make sure key->q and key->p are prime */
37 if ((err = mp_prime_is_prime(key->q, 8, &res)) != CRYPT_OK) {
38 return err;
39 }
40 if (res == 0) {
41 return CRYPT_OK;
42 }
43
44 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) {
45 return err;
46 }
47 if (res == 0) {
48 return CRYPT_OK;
49 }
50
51 /* now make sure that g is not -1, 0 or 1 and <p */
52 if (mp_cmp_d(key->g, 0) == LTC_MP_EQ || mp_cmp_d(key->g, 1) == LTC_MP_EQ) {
53 return CRYPT_OK;
54 }
55 if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK) { return err; }
56 if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) { goto error; }
57 if (mp_cmp(tmp, key->g) == LTC_MP_EQ || mp_cmp(key->g, key->p) != LTC_MP_LT) {
58 err = CRYPT_OK;
59 goto error;
60 }
61
62 /* 1 < y < p-1 */
63 if (!(mp_cmp_d(key->y, 1) == LTC_MP_GT && mp_cmp(key->y, tmp) == LTC_MP_LT)) {
64 err = CRYPT_OK;
65 goto error;
66 }
67
68 /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */
69 if ((err = mp_div(tmp, key->q, tmp, tmp2)) != CRYPT_OK) { goto error; }
70 if (mp_iszero(tmp2) != LTC_MP_YES) {
71 err = CRYPT_OK;
72 goto error;
73 }
74
75 if ((err = mp_exptmod(key->g, key->q, key->p, tmp)) != CRYPT_OK) { goto error; }
76 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
77 err = CRYPT_OK;
78 goto error;
79 }
80
81 /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */
82 if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) { goto error; }
83 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
84 err = CRYPT_OK;
85 goto error;
86 }
87
88 /* at this point we are out of tests ;-( */
89 err = CRYPT_OK;
90 *stat = 1;
91 error:
92 mp_clear_multi(tmp, tmp2, NULL);
93 return err;
94 }
95 #endif
96
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
+0
-127
libtom-src/pk/ecc/ecc.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
26 const ltc_ecc_set_type ltc_ecc_sets[] = {
27 #ifdef ECC112
28 {
29 14,
30 "SECP112R1",
31 "DB7C2ABF62E35E668076BEAD208B",
32 "659EF8BA043916EEDE8911702B22",
33 "DB7C2ABF62E35E7628DFAC6561C5",
34 "09487239995A5EE76B55F9C2F098",
35 "A89CE5AF8724C0A23E0E0FF77500"
36 },
37 #endif
38 #ifdef ECC128
39 {
40 16,
41 "SECP128R1",
42 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
43 "E87579C11079F43DD824993C2CEE5ED3",
44 "FFFFFFFE0000000075A30D1B9038A115",
45 "161FF7528B899B2D0C28607CA52C5B86",
46 "CF5AC8395BAFEB13C02DA292DDED7A83",
47 },
48 #endif
49 #ifdef ECC160
50 {
51 20,
52 "SECP160R1",
53 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
54 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
55 "0100000000000000000001F4C8F927AED3CA752257",
56 "4A96B5688EF573284664698968C38BB913CBFC82",
57 "23A628553168947D59DCC912042351377AC5FB32",
58 },
59 #endif
60 #ifdef ECC192
61 {
62 24,
63 "ECC-192",
64 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
65 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
66 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
67 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
68 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
69 },
70 #endif
71 #ifdef ECC224
72 {
73 28,
74 "ECC-224",
75 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
76 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
77 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
78 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
79 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
80 },
81 #endif
82 #ifdef ECC256
83 {
84 32,
85 "ECC-256",
86 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
87 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
88 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
89 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
90 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
91 },
92 #endif
93 #ifdef ECC384
94 {
95 48,
96 "ECC-384",
97 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
98 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
99 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
100 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
101 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
102 },
103 #endif
104 #ifdef ECC521
105 {
106 66,
107 "ECC-521",
108 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
109 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
110 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
111 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
112 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
113 },
114 #endif
115 {
116 0,
117 NULL, NULL, NULL, NULL, NULL, NULL
118 }
119 };
120
121 #endif
122
123 /* $Source$ */
124 /* $Revision$ */
125 /* $Date$ */
126
+0
-72
libtom-src/pk/ecc/ecc_ansi_x963_export.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_ansi_x963_export.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /** ECC X9.63 (Sec. 4.3.6) uncompressed export
26 @param key Key to export
27 @param out [out] destination of export
28 @param outlen [in/out] Length of destination and final output size
29 Return CRYPT_OK on success
30 */
31 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen)
32 {
33 unsigned char buf[ECC_BUF_SIZE];
34 unsigned long numlen;
35
36 LTC_ARGCHK(key != NULL);
37 LTC_ARGCHK(out != NULL);
38 LTC_ARGCHK(outlen != NULL);
39
40 if (ltc_ecc_is_valid_idx(key->idx) == 0) {
41 return CRYPT_INVALID_ARG;
42 }
43 numlen = key->dp->size;
44
45 if (*outlen < (1 + 2*numlen)) {
46 *outlen = 1 + 2*numlen;
47 return CRYPT_BUFFER_OVERFLOW;
48 }
49
50 /* store byte 0x04 */
51 out[0] = 0x04;
52
53 /* pad and store x */
54 zeromem(buf, sizeof(buf));
55 mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
56 XMEMCPY(out+1, buf, numlen);
57
58 /* pad and store y */
59 zeromem(buf, sizeof(buf));
60 mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - mp_unsigned_bin_size(key->pubkey.y)));
61 XMEMCPY(out+1+numlen, buf, numlen);
62
63 *outlen = 1 + 2*numlen;
64 return CRYPT_OK;
65 }
66
67 #endif
68
69 /* $Source$ */
70 /* $Revision$ */
71 /* $Date$ */
+0
-104
libtom-src/pk/ecc/ecc_ansi_x963_import.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_ansi_x963_import.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /** Import an ANSI X9.63 format public key
26 @param in The input data to read
27 @param inlen The length of the input data
28 @param key [out] destination to store imported key \
29 */
30 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
31 {
32 return ecc_ansi_x963_import_ex(in, inlen, key, NULL);
33 }
34
35 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
36 {
37 int x, err;
38
39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(key != NULL);
41
42 /* must be odd */
43 if ((inlen & 1) == 0) {
44 return CRYPT_INVALID_ARG;
45 }
46
47 /* init key */
48 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) {
49 return CRYPT_MEM;
50 }
51
52 /* check for 4, 6 or 7 */
53 if (in[0] != 4 && in[0] != 6 && in[0] != 7) {
54 err = CRYPT_INVALID_PACKET;
55 goto error;
56 }
57
58 /* read data */
59 if ((err = mp_read_unsigned_bin(key->pubkey.x, (unsigned char *)in+1, (inlen-1)>>1)) != CRYPT_OK) {
60 goto error;
61 }
62
63 if ((err = mp_read_unsigned_bin(key->pubkey.y, (unsigned char *)in+1+((inlen-1)>>1), (inlen-1)>>1)) != CRYPT_OK) {
64 goto error;
65 }
66 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; }
67
68 if (dp == NULL) {
69 /* determine the idx */
70 for (x = 0; ltc_ecc_sets[x].size != 0; x++) {
71 if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) {
72 break;
73 }
74 }
75 if (ltc_ecc_sets[x].size == 0) {
76 err = CRYPT_INVALID_PACKET;
77 goto error;
78 }
79 /* set the idx */
80 key->idx = x;
81 key->dp = &ltc_ecc_sets[x];
82 } else {
83 if (((inlen-1)>>1) != (unsigned long) dp->size) {
84 err = CRYPT_INVALID_PACKET;
85 goto error;
86 }
87 key->idx = -1;
88 key->dp = dp;
89 }
90 key->type = PK_PUBLIC;
91
92 /* we're done */
93 return CRYPT_OK;
94 error:
95 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
96 return err;
97 }
98
99 #endif
100
101 /* $Source$ */
102 /* $Revision$ */
103 /* $Date$ */
+0
-150
libtom-src/pk/ecc/ecc_decrypt_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_decrypt_key.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Decrypt an ECC encrypted key
27 @param in The ciphertext
28 @param inlen The length of the ciphertext (octets)
29 @param out [out] The plaintext
30 @param outlen [in/out] The max size and resulting size of the plaintext
31 @param key The corresponding private ECC key
32 @return CRYPT_OK if successful
33 */
34 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
35 unsigned char *out, unsigned long *outlen,
36 ecc_key *key)
37 {
38 unsigned char *ecc_shared, *skey, *pub_expt;
39 unsigned long x, y, hashOID[32];
40 int hash, err;
41 ecc_key pubkey;
42 ltc_asn1_list decode[3];
43
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47 LTC_ARGCHK(key != NULL);
48
49 /* right key type? */
50 if (key->type != PK_PRIVATE) {
51 return CRYPT_PK_NOT_PRIVATE;
52 }
53
54 /* decode to find out hash */
55 LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
56
57 if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
58 return err;
59 }
60
61 hash = find_hash_oid(hashOID, decode[0].size);
62 if (hash_is_valid(hash) != CRYPT_OK) {
63 return CRYPT_INVALID_PACKET;
64 }
65
66 /* we now have the hash! */
67
68 /* allocate memory */
69 pub_expt = XMALLOC(ECC_BUF_SIZE);
70 ecc_shared = XMALLOC(ECC_BUF_SIZE);
71 skey = XMALLOC(MAXBLOCKSIZE);
72 if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
73 if (pub_expt != NULL) {
74 XFREE(pub_expt);
75 }
76 if (ecc_shared != NULL) {
77 XFREE(ecc_shared);
78 }
79 if (skey != NULL) {
80 XFREE(skey);
81 }
82 return CRYPT_MEM;
83 }
84 LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE);
85 LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
86
87 /* read the structure in now */
88 if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
89 goto LBL_ERR;
90 }
91
92 /* import ECC key from packet */
93 if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
94 goto LBL_ERR;
95 }
96
97 /* make shared key */
98 x = ECC_BUF_SIZE;
99 if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {
100 ecc_free(&pubkey);
101 goto LBL_ERR;
102 }
103 ecc_free(&pubkey);
104
105 y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE);
106 if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {
107 goto LBL_ERR;
108 }
109
110 /* ensure the hash of the shared secret is at least as big as the encrypt itself */
111 if (decode[2].size > y) {
112 err = CRYPT_INVALID_PACKET;
113 goto LBL_ERR;
114 }
115
116 /* avoid buffer overflow */
117 if (*outlen < decode[2].size) {
118 *outlen = decode[2].size;
119 err = CRYPT_BUFFER_OVERFLOW;
120 goto LBL_ERR;
121 }
122
123 /* Decrypt the key */
124 for (x = 0; x < decode[2].size; x++) {
125 out[x] = skey[x] ^ ecc_shared[x];
126 }
127 *outlen = x;
128
129 err = CRYPT_OK;
130 LBL_ERR:
131 #ifdef LTC_CLEAN_STACK
132 zeromem(pub_expt, ECC_BUF_SIZE);
133 zeromem(ecc_shared, ECC_BUF_SIZE);
134 zeromem(skey, MAXBLOCKSIZE);
135 #endif
136
137 XFREE(pub_expt);
138 XFREE(ecc_shared);
139 XFREE(skey);
140
141 return err;
142 }
143
144 #endif
145
146 /* $Source$ */
147 /* $Revision$ */
148 /* $Date$ */
149
+0
-136
libtom-src/pk/ecc/ecc_encrypt_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_encrypt_key.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Encrypt a symmetric key with ECC
27 @param in The symmetric key you want to encrypt
28 @param inlen The length of the key to encrypt (octets)
29 @param out [out] The destination for the ciphertext
30 @param outlen [in/out] The max size and resulting size of the ciphertext
31 @param prng An active PRNG state
32 @param wprng The index of the PRNG you wish to use
33 @param hash The index of the hash you want to use
34 @param key The ECC key you want to encrypt to
35 @return CRYPT_OK if successful
36 */
37 int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
38 unsigned char *out, unsigned long *outlen,
39 prng_state *prng, int wprng, int hash,
40 ecc_key *key)
41 {
42 unsigned char *pub_expt, *ecc_shared, *skey;
43 ecc_key pubkey;
44 unsigned long x, y, pubkeysize;
45 int err;
46
47 LTC_ARGCHK(in != NULL);
48 LTC_ARGCHK(out != NULL);
49 LTC_ARGCHK(outlen != NULL);
50 LTC_ARGCHK(key != NULL);
51
52 /* check that wprng/cipher/hash are not invalid */
53 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
54 return err;
55 }
56
57 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
58 return err;
59 }
60
61 if (inlen > hash_descriptor[hash].hashsize) {
62 return CRYPT_INVALID_HASH;
63 }
64
65 /* make a random key and export the public copy */
66 if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) {
67 return err;
68 }
69
70 pub_expt = XMALLOC(ECC_BUF_SIZE);
71 ecc_shared = XMALLOC(ECC_BUF_SIZE);
72 skey = XMALLOC(MAXBLOCKSIZE);
73 if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
74 if (pub_expt != NULL) {
75 XFREE(pub_expt);
76 }
77 if (ecc_shared != NULL) {
78 XFREE(ecc_shared);
79 }
80 if (skey != NULL) {
81 XFREE(skey);
82 }
83 ecc_free(&pubkey);
84 return CRYPT_MEM;
85 }
86
87 pubkeysize = ECC_BUF_SIZE;
88 if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
89 ecc_free(&pubkey);
90 goto LBL_ERR;
91 }
92
93 /* make random key */
94 x = ECC_BUF_SIZE;
95 if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
96 ecc_free(&pubkey);
97 goto LBL_ERR;
98 }
99 ecc_free(&pubkey);
100 y = MAXBLOCKSIZE;
101 if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104
105 /* Encrypt key */
106 for (x = 0; x < inlen; x++) {
107 skey[x] ^= in[x];
108 }
109
110 err = der_encode_sequence_multi(out, outlen,
111 LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
112 LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt,
113 LTC_ASN1_OCTET_STRING, inlen, skey,
114 LTC_ASN1_EOL, 0UL, NULL);
115
116 LBL_ERR:
117 #ifdef LTC_CLEAN_STACK
118 /* clean up */
119 zeromem(pub_expt, ECC_BUF_SIZE);
120 zeromem(ecc_shared, ECC_BUF_SIZE);
121 zeromem(skey, MAXBLOCKSIZE);
122 #endif
123
124 XFREE(skey);
125 XFREE(ecc_shared);
126 XFREE(pub_expt);
127
128 return err;
129 }
130
131 #endif
132 /* $Source$ */
133 /* $Revision$ */
134 /* $Date$ */
135
+0
-82
libtom-src/pk/ecc/ecc_export.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_export.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Export an ECC key as a binary packet
27 @param out [out] Destination for the key
28 @param outlen [in/out] Max size and resulting size of the exported key
29 @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC)
30 @param key The key to export
31 @return CRYPT_OK if successful
32 */
33 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
34 {
35 int err;
36 unsigned char flags[1];
37 unsigned long key_size;
38
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41 LTC_ARGCHK(key != NULL);
42
43 /* type valid? */
44 if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
45 return CRYPT_PK_TYPE_MISMATCH;
46 }
47
48 if (ltc_ecc_is_valid_idx(key->idx) == 0) {
49 return CRYPT_INVALID_ARG;
50 }
51
52 /* we store the NIST byte size */
53 key_size = key->dp->size;
54
55 if (type == PK_PRIVATE) {
56 flags[0] = 1;
57 err = der_encode_sequence_multi(out, outlen,
58 LTC_ASN1_BIT_STRING, 1UL, flags,
59 LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
60 LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
61 LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
62 LTC_ASN1_INTEGER, 1UL, key->k,
63 LTC_ASN1_EOL, 0UL, NULL);
64 } else {
65 flags[0] = 0;
66 err = der_encode_sequence_multi(out, outlen,
67 LTC_ASN1_BIT_STRING, 1UL, flags,
68 LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
69 LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
70 LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
71 LTC_ASN1_EOL, 0UL, NULL);
72 }
73
74 return err;
75 }
76
77 #endif
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
81
+0
-40
libtom-src/pk/ecc/ecc_free.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_free.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Free an ECC key from memory
27 @param key The key you wish to free
28 */
29 void ecc_free(ecc_key *key)
30 {
31 LTC_ARGCHKVD(key != NULL);
32 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
33 }
34
35 #endif
36 /* $Source$ */
37 /* $Revision$ */
38 /* $Date$ */
39
+0
-44
libtom-src/pk/ecc/ecc_get_size.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_get_size.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Get the size of an ECC key
27 @param key The key to get the size of
28 @return The size (octets) of the key or INT_MAX on error
29 */
30 int ecc_get_size(ecc_key *key)
31 {
32 LTC_ARGCHK(key != NULL);
33 if (ltc_ecc_is_valid_idx(key->idx))
34 return key->dp->size;
35 else
36 return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */
37 }
38
39 #endif
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
43
+0
-172
libtom-src/pk/ecc/ecc_import.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_import.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 static int is_point(ecc_key *key)
26 {
27 void *prime, *b, *t1, *t2;
28 int err;
29
30 if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) {
31 return err;
32 }
33
34 /* load prime and b */
35 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; }
36 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; }
37
38 /* compute y^2 */
39 if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; }
40
41 /* compute x^3 */
42 if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; }
43 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; }
44 if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; }
45
46 /* compute y^2 - x^3 */
47 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; }
48
49 /* compute y^2 - x^3 + 3x */
50 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
51 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
52 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
53 if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; }
54 while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
55 if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; }
56 }
57 while (mp_cmp(t1, prime) != LTC_MP_LT) {
58 if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; }
59 }
60
61 /* compare to b */
62 if (mp_cmp(t1, b) != LTC_MP_EQ) {
63 err = CRYPT_INVALID_PACKET;
64 } else {
65 err = CRYPT_OK;
66 }
67
68 error:
69 mp_clear_multi(prime, b, t1, t2, NULL);
70 return err;
71 }
72
73 /**
74 Import an ECC key from a binary packet
75 @param in The packet to import
76 @param inlen The length of the packet
77 @param key [out] The destination of the import
78 @return CRYPT_OK if successful, upon error all allocated memory will be freed
79 */
80 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
81 {
82 return ecc_import_ex(in, inlen, key, NULL);
83 }
84
85 /**
86 Import an ECC key from a binary packet, using user supplied domain params rather than one of the NIST ones
87 @param in The packet to import
88 @param inlen The length of the packet
89 @param key [out] The destination of the import
90 @param dp pointer to user supplied params; must be the same as the params used when exporting
91 @return CRYPT_OK if successful, upon error all allocated memory will be freed
92 */
93 int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp)
94 {
95 unsigned long key_size;
96 unsigned char flags[1];
97 int err;
98
99 LTC_ARGCHK(in != NULL);
100 LTC_ARGCHK(key != NULL);
101 LTC_ARGCHK(ltc_mp.name != NULL);
102
103 /* init key */
104 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) {
105 return CRYPT_MEM;
106 }
107
108 /* find out what type of key it is */
109 if ((err = der_decode_sequence_multi(in, inlen,
110 LTC_ASN1_BIT_STRING, 1UL, &flags,
111 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
112 goto done;
113 }
114
115
116 if (flags[0] == 1) {
117 /* private key */
118 key->type = PK_PRIVATE;
119 if ((err = der_decode_sequence_multi(in, inlen,
120 LTC_ASN1_BIT_STRING, 1UL, flags,
121 LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
122 LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
123 LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
124 LTC_ASN1_INTEGER, 1UL, key->k,
125 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
126 goto done;
127 }
128 } else {
129 /* public key */
130 key->type = PK_PUBLIC;
131 if ((err = der_decode_sequence_multi(in, inlen,
132 LTC_ASN1_BIT_STRING, 1UL, flags,
133 LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
134 LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
135 LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
136 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
137 goto done;
138 }
139 }
140
141 if (dp == NULL) {
142 /* find the idx */
143 for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx);
144 if (ltc_ecc_sets[key->idx].size == 0) {
145 err = CRYPT_INVALID_PACKET;
146 goto done;
147 }
148 key->dp = &ltc_ecc_sets[key->idx];
149 } else {
150 key->idx = -1;
151 key->dp = dp;
152 }
153 /* set z */
154 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; }
155
156 /* is it a point on the curve? */
157 if ((err = is_point(key)) != CRYPT_OK) {
158 goto done;
159 }
160
161 /* we're good */
162 return CRYPT_OK;
163 done:
164 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
165 return err;
166 }
167 #endif
168 /* $Source$ */
169 /* $Revision$ */
170 /* $Date$ */
171
+0
-130
libtom-src/pk/ecc/ecc_make_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_make_key.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Make a new ECC key
27 @param prng An active PRNG state
28 @param wprng The index of the PRNG you wish to use
29 @param keysize The keysize for the new key (in octets from 20 to 65 bytes)
30 @param key [out] Destination of the newly created key
31 @return CRYPT_OK if successful, upon error all allocated memory will be freed
32 */
33 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
34 {
35 int x, err;
36
37 /* find key size */
38 for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++);
39 keysize = ltc_ecc_sets[x].size;
40
41 if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) {
42 return CRYPT_INVALID_KEYSIZE;
43 }
44 err = ecc_make_key_ex(prng, wprng, key, &ltc_ecc_sets[x]);
45 key->idx = x;
46 return err;
47 }
48
49 int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp)
50 {
51 int err;
52 ecc_point *base;
53 void *prime, *order;
54 unsigned char *buf;
55 int keysize;
56
57 LTC_ARGCHK(key != NULL);
58 LTC_ARGCHK(ltc_mp.name != NULL);
59 LTC_ARGCHK(dp != NULL);
60
61 /* good prng? */
62 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
63 return err;
64 }
65
66 key->idx = -1;
67 key->dp = dp;
68 keysize = dp->size;
69
70 /* allocate ram */
71 base = NULL;
72 buf = XMALLOC(ECC_MAXSIZE);
73 if (buf == NULL) {
74 return CRYPT_MEM;
75 }
76
77 /* make up random string */
78 if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) {
79 err = CRYPT_ERROR_READPRNG;
80 goto ERR_BUF;
81 }
82
83 /* setup the key variables */
84 if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, NULL)) != CRYPT_OK) {
85 goto ERR_BUF;
86 }
87 base = ltc_ecc_new_point();
88 if (base == NULL) {
89 err = CRYPT_MEM;
90 goto errkey;
91 }
92
93 /* read in the specs for this key */
94 if ((err = mp_read_radix(prime, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto errkey; }
95 if ((err = mp_read_radix(order, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errkey; }
96 if ((err = mp_read_radix(base->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto errkey; }
97 if ((err = mp_read_radix(base->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto errkey; }
98 if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; }
99 if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; }
100
101 /* the key should be smaller than the order of base point */
102 if (mp_cmp(key->k, order) != LTC_MP_LT) {
103 if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; }
104 }
105 /* make the public key */
106 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto errkey; }
107 key->type = PK_PRIVATE;
108
109 /* free up ram */
110 err = CRYPT_OK;
111 goto cleanup;
112 errkey:
113 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
114 cleanup:
115 ltc_ecc_del_point(base);
116 mp_clear_multi(prime, order, NULL);
117 ERR_BUF:
118 #ifdef LTC_CLEAN_STACK
119 zeromem(buf, ECC_MAXSIZE);
120 #endif
121 XFREE(buf);
122 return err;
123 }
124
125 #endif
126 /* $Source$ */
127 /* $Revision$ */
128 /* $Date$ */
129
+0
-95
libtom-src/pk/ecc/ecc_shared_secret.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_shared_secret.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Create an ECC shared secret between two keys
27 @param private_key The private ECC key
28 @param public_key The public key
29 @param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63)
30 @param outlen [in/out] The max size and resulting size of the shared secret
31 @return CRYPT_OK if successful
32 */
33 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
34 unsigned char *out, unsigned long *outlen)
35 {
36 unsigned long x;
37 ecc_point *result;
38 void *prime;
39 int err;
40
41 LTC_ARGCHK(private_key != NULL);
42 LTC_ARGCHK(public_key != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45
46 /* type valid? */
47 if (private_key->type != PK_PRIVATE) {
48 return CRYPT_PK_NOT_PRIVATE;
49 }
50
51 if (ltc_ecc_is_valid_idx(private_key->idx) == 0 || ltc_ecc_is_valid_idx(public_key->idx) == 0) {
52 return CRYPT_INVALID_ARG;
53 }
54
55 if (XSTRCMP(private_key->dp->name, public_key->dp->name) != 0) {
56 return CRYPT_PK_TYPE_MISMATCH;
57 }
58
59 /* make new point */
60 result = ltc_ecc_new_point();
61 if (result == NULL) {
62 return CRYPT_MEM;
63 }
64
65 if ((err = mp_init(&prime)) != CRYPT_OK) {
66 ltc_ecc_del_point(result);
67 return err;
68 }
69
70 if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != CRYPT_OK) { goto done; }
71 if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK) { goto done; }
72
73 x = (unsigned long)mp_unsigned_bin_size(prime);
74 if (*outlen < x) {
75 *outlen = x;
76 err = CRYPT_BUFFER_OVERFLOW;
77 goto done;
78 }
79 zeromem(out, x);
80 if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x)))) != CRYPT_OK) { goto done; }
81
82 err = CRYPT_OK;
83 *outlen = x;
84 done:
85 mp_clear(prime);
86 ltc_ecc_del_point(result);
87 return err;
88 }
89
90 #endif
91 /* $Source$ */
92 /* $Revision$ */
93 /* $Date$ */
94
+0
-114
libtom-src/pk/ecc/ecc_sign_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_sign_hash.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Sign a message digest
27 @param in The message digest to sign
28 @param inlen The length of the digest
29 @param out [out] The destination for the signature
30 @param outlen [in/out] The max size and resulting size of the signature
31 @param prng An active PRNG state
32 @param wprng The index of the PRNG you wish to use
33 @param key A private ECC key
34 @return CRYPT_OK if successful
35 */
36 int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
37 unsigned char *out, unsigned long *outlen,
38 prng_state *prng, int wprng, ecc_key *key)
39 {
40 ecc_key pubkey;
41 void *r, *s, *e, *p;
42 int err;
43
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47 LTC_ARGCHK(key != NULL);
48
49 /* is this a private key? */
50 if (key->type != PK_PRIVATE) {
51 return CRYPT_PK_NOT_PRIVATE;
52 }
53
54 /* is the IDX valid ? */
55 if (ltc_ecc_is_valid_idx(key->idx) != 1) {
56 return CRYPT_PK_INVALID_TYPE;
57 }
58
59 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
60 return err;
61 }
62
63 /* get the hash and load it as a bignum into 'e' */
64 /* init the bignums */
65 if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) {
66 return err;
67 }
68 if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; }
69 if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto errnokey; }
70
71 /* make up a key and export the public copy */
72 for (;;) {
73 if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) {
74 goto errnokey;
75 }
76
77 /* find r = x1 mod n */
78 if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; }
79
80 if (mp_iszero(r) == LTC_MP_YES) {
81 ecc_free(&pubkey);
82 } else {
83 /* find s = (e + xr)/k */
84 if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */
85 if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */
86 if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
87 if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
88 if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */
89 ecc_free(&pubkey);
90 if (mp_iszero(s) == LTC_MP_NO) {
91 break;
92 }
93 }
94 }
95
96 /* store as SEQUENCE { r, s -- integer } */
97 err = der_encode_sequence_multi(out, outlen,
98 LTC_ASN1_INTEGER, 1UL, r,
99 LTC_ASN1_INTEGER, 1UL, s,
100 LTC_ASN1_EOL, 0UL, NULL);
101 goto errnokey;
102 error:
103 ecc_free(&pubkey);
104 errnokey:
105 mp_clear_multi(r, s, p, e, NULL);
106 return err;
107 }
108
109 #endif
110 /* $Source$ */
111 /* $Revision$ */
112 /* $Date$ */
113
+0
-48
libtom-src/pk/ecc/ecc_sizes.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_sizes.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 void ecc_sizes(int *low, int *high)
26 {
27 int i;
28 LTC_ARGCHKVD(low != NULL);
29 LTC_ARGCHKVD(high != NULL);
30
31 *low = INT_MAX;
32 *high = 0;
33 for (i = 0; ltc_ecc_sets[i].size != 0; i++) {
34 if (ltc_ecc_sets[i].size < *low) {
35 *low = ltc_ecc_sets[i].size;
36 }
37 if (ltc_ecc_sets[i].size > *high) {
38 *high = ltc_ecc_sets[i].size;
39 }
40 }
41 }
42
43 #endif
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
47
+0
-165
libtom-src/pk/ecc/ecc_verify_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_verify_hash.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /* verify
26 *
27 * w = s^-1 mod n
28 * u1 = xw
29 * u2 = rw
30 * X = u1*G + u2*Q
31 * v = X_x1 mod n
32 * accept if v == r
33 */
34
35 /**
36 Verify an ECC signature
37 @param sig The signature to verify
38 @param siglen The length of the signature (octets)
39 @param hash The hash (message digest) that was signed
40 @param hashlen The length of the hash (octets)
41 @param stat Result of signature, 1==valid, 0==invalid
42 @param key The corresponding public ECC key
43 @return CRYPT_OK if successful (even if the signature is not valid)
44 */
45 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
46 const unsigned char *hash, unsigned long hashlen,
47 int *stat, ecc_key *key)
48 {
49 ecc_point *mG, *mQ;
50 void *r, *s, *v, *w, *u1, *u2, *e, *p, *m;
51 void *mp;
52 int err;
53
54 LTC_ARGCHK(sig != NULL);
55 LTC_ARGCHK(hash != NULL);
56 LTC_ARGCHK(stat != NULL);
57 LTC_ARGCHK(key != NULL);
58
59 /* default to invalid signature */
60 *stat = 0;
61 mp = NULL;
62
63 /* is the IDX valid ? */
64 if (ltc_ecc_is_valid_idx(key->idx) != 1) {
65 return CRYPT_PK_INVALID_TYPE;
66 }
67
68 /* allocate ints */
69 if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) {
70 return CRYPT_MEM;
71 }
72
73 /* allocate points */
74 mG = ltc_ecc_new_point();
75 mQ = ltc_ecc_new_point();
76 if (mQ == NULL || mG == NULL) {
77 err = CRYPT_MEM;
78 goto error;
79 }
80
81 /* parse header */
82 if ((err = der_decode_sequence_multi(sig, siglen,
83 LTC_ASN1_INTEGER, 1UL, r,
84 LTC_ASN1_INTEGER, 1UL, s,
85 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
86 goto error;
87 }
88
89 /* get the order */
90 if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto error; }
91
92 /* get the modulus */
93 if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; }
94
95 /* check for zero */
96 if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) {
97 err = CRYPT_INVALID_PACKET;
98 goto error;
99 }
100
101 /* read hash */
102 if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; }
103
104 /* w = s^-1 mod n */
105 if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; }
106
107 /* u1 = ew */
108 if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK) { goto error; }
109
110 /* u2 = rw */
111 if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; }
112
113 /* find mG and mQ */
114 if ((err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto error; }
115 if ((err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto error; }
116 if ((err = mp_set(mG->z, 1)) != CRYPT_OK) { goto error; }
117
118 if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; }
119 if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; }
120 if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; }
121
122 /* compute u1*mG + u2*mQ = mG */
123 if (ltc_mp.ecc_mul2add == NULL) {
124 if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK) { goto error; }
125 if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK) { goto error; }
126
127 /* find the montgomery mp */
128 if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; }
129
130 /* add them */
131 if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto error; }
132
133 /* reduce */
134 if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; }
135 } else {
136 /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */
137 if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m)) != CRYPT_OK) { goto error; }
138 }
139
140 /* v = X_x1 mod n */
141 if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK) { goto error; }
142
143 /* does v == r */
144 if (mp_cmp(v, r) == LTC_MP_EQ) {
145 *stat = 1;
146 }
147
148 /* clear up and return */
149 err = CRYPT_OK;
150 error:
151 ltc_ecc_del_point(mG);
152 ltc_ecc_del_point(mQ);
153 mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
154 if (mp != NULL) {
155 mp_montgomery_free(mp);
156 }
157 return err;
158 }
159
160 #endif
161 /* $Source$ */
162 /* $Revision$ */
163 /* $Date$ */
164
+0
-46
libtom-src/pk/ecc/ltc_ecc_is_valid_idx.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_is_valid_idx.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /** Returns whether an ECC idx is valid or not
26 @param n The idx number to check
27 @return 1 if valid, 0 if not
28 */
29 int ltc_ecc_is_valid_idx(int n)
30 {
31 int x;
32
33 for (x = 0; ltc_ecc_sets[x].size != 0; x++);
34 /* -1 is a valid index --- indicating that the domain params were supplied by the user */
35 if ((n >= -1) && (n < x)) {
36 return 1;
37 }
38 return 0;
39 }
40
41 #endif
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
45
+0
-76
libtom-src/pk/ecc/ltc_ecc_map.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_map.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Map a projective jacbobian point back to affine space
27 @param P [in/out] The point to map
28 @param modulus The modulus of the field the ECC curve is in
29 @param mp The "b" value from montgomery_setup()
30 @return CRYPT_OK on success
31 */
32 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
33 {
34 void *t1, *t2;
35 int err;
36
37 LTC_ARGCHK(P != NULL);
38 LTC_ARGCHK(modulus != NULL);
39 LTC_ARGCHK(mp != NULL);
40
41 if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
42 return CRYPT_MEM;
43 }
44
45 /* first map z back to normal */
46 if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; }
47
48 /* get 1/z */
49 if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; }
50
51 /* get 1/z^2 and 1/z^3 */
52 if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; }
53 if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; }
54 if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; }
55 if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; }
56
57 /* multiply against x/y */
58 if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; }
59 if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; }
60 if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; }
61 if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; }
62 if ((err = mp_set(P->z, 1)) != CRYPT_OK) { goto done; }
63
64 err = CRYPT_OK;
65 done:
66 mp_clear_multi(t1, t2, NULL);
67 return err;
68 }
69
70 #endif
71
72 /* $Source$ */
73 /* $Revision$ */
74 /* $Date$ */
75
+0
-207
libtom-src/pk/ecc/ltc_ecc_mul2add.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_mul2add.c
20 ECC Crypto, Shamir's Trick, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 #ifdef LTC_ECC_SHAMIR
26
27 /** Computes kA*A + kB*B = C using Shamir's Trick
28 @param A First point to multiply
29 @param kA What to multiple A by
30 @param B Second point to multiply
31 @param kB What to multiple B by
32 @param C [out] Destination point (can overlap with A or B
33 @param modulus Modulus for curve
34 @return CRYPT_OK on success
35 */
36 int ltc_ecc_mul2add(ecc_point *A, void *kA,
37 ecc_point *B, void *kB,
38 ecc_point *C,
39 void *modulus)
40 {
41 ecc_point *precomp[16];
42 unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble;
43 unsigned char *tA, *tB;
44 int err, first;
45 void *mp, *mu;
46
47 /* argchks */
48 LTC_ARGCHK(A != NULL);
49 LTC_ARGCHK(B != NULL);
50 LTC_ARGCHK(C != NULL);
51 LTC_ARGCHK(kA != NULL);
52 LTC_ARGCHK(kB != NULL);
53 LTC_ARGCHK(modulus != NULL);
54
55 /* allocate memory */
56 tA = XCALLOC(1, ECC_BUF_SIZE);
57 if (tA == NULL) {
58 return CRYPT_MEM;
59 }
60 tB = XCALLOC(1, ECC_BUF_SIZE);
61 if (tB == NULL) {
62 XFREE(tA);
63 return CRYPT_MEM;
64 }
65
66 /* get sizes */
67 lenA = mp_unsigned_bin_size(kA);
68 lenB = mp_unsigned_bin_size(kB);
69 len = MAX(lenA, lenB);
70
71 /* sanity check */
72 if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) {
73 err = CRYPT_INVALID_ARG;
74 goto ERR_T;
75 }
76
77 /* extract and justify kA */
78 mp_to_unsigned_bin(kA, (len - lenA) + tA);
79
80 /* extract and justify kB */
81 mp_to_unsigned_bin(kB, (len - lenB) + tB);
82
83 /* allocate the table */
84 for (x = 0; x < 16; x++) {
85 precomp[x] = ltc_ecc_new_point();
86 if (precomp[x] == NULL) {
87 for (y = 0; y < x; ++y) {
88 ltc_ecc_del_point(precomp[y]);
89 }
90 err = CRYPT_MEM;
91 goto ERR_T;
92 }
93 }
94
95 /* init montgomery reduction */
96 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
97 goto ERR_P;
98 }
99 if ((err = mp_init(&mu)) != CRYPT_OK) {
100 goto ERR_MP;
101 }
102 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
103 goto ERR_MU;
104 }
105
106 /* copy ones ... */
107 if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; }
108 if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; }
109 if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; }
110
111 if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; }
112 if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; }
113 if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; }
114
115 /* precomp [i,0](A + B) table */
116 if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
117 if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
118
119 /* precomp [0,i](A + B) table */
120 if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
121 if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
122
123 /* precomp [i,j](A + B) table (i != 0, j != 0) */
124 for (x = 1; x < 4; x++) {
125 for (y = 1; y < 4; y++) {
126 if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
127 }
128 }
129
130 nibble = 3;
131 first = 1;
132 bitbufA = tA[0];
133 bitbufB = tB[0];
134
135 /* for every byte of the multiplicands */
136 for (x = -1;; ) {
137 /* grab a nibble */
138 if (++nibble == 4) {
139 ++x; if (x == len) break;
140 bitbufA = tA[x];
141 bitbufB = tB[x];
142 nibble = 0;
143 }
144
145 /* extract two bits from both, shift/update */
146 nA = (bitbufA >> 6) & 0x03;
147 nB = (bitbufB >> 6) & 0x03;
148 bitbufA = (bitbufA << 2) & 0xFF;
149 bitbufB = (bitbufB << 2) & 0xFF;
150
151 /* if both zero, if first, continue */
152 if ((nA == 0) && (nB == 0) && (first == 1)) {
153 continue;
154 }
155
156 /* double twice, only if this isn't the first */
157 if (first == 0) {
158 /* double twice */
159 if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
160 if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
161 }
162
163 /* if not both zero */
164 if ((nA != 0) || (nB != 0)) {
165 if (first == 1) {
166 /* if first, copy from table */
167 first = 0;
168 if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; }
169 if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; }
170 if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; }
171 } else {
172 /* if not first, add from table */
173 if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
174 }
175 }
176 }
177
178 /* reduce to affine */
179 err = ltc_ecc_map(C, modulus, mp);
180
181 /* clean up */
182 ERR_MU:
183 mp_clear(mu);
184 ERR_MP:
185 mp_montgomery_free(mp);
186 ERR_P:
187 for (x = 0; x < 16; x++) {
188 ltc_ecc_del_point(precomp[x]);
189 }
190 ERR_T:
191 #ifdef LTC_CLEAN_STACK
192 zeromem(tA, ECC_BUF_SIZE);
193 zeromem(tB, ECC_BUF_SIZE);
194 #endif
195 XFREE(tA);
196 XFREE(tB);
197
198 return err;
199 }
200
201 #endif
202 #endif
203
204 /* $Source$ */
205 /* $Revision$ */
206 /* $Date$ */
+0
-222
libtom-src/pk/ecc/ltc_ecc_mulmod.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_mulmod.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24 #ifndef LTC_ECC_TIMING_RESISTANT
25
26 /* size of sliding window, don't change this! */
27 #define WINSIZE 4
28
29 /**
30 Perform a point multiplication
31 @param k The scalar to multiply by
32 @param G The base point
33 @param R [out] Destination for kG
34 @param modulus The modulus of the field the ECC curve is in
35 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
36 @return CRYPT_OK on success
37 */
38 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
39 {
40 ecc_point *tG, *M[8];
41 int i, j, err;
42 void *mu, *mp;
43 unsigned long buf;
44 int first, bitbuf, bitcpy, bitcnt, mode, digidx;
45
46 LTC_ARGCHK(k != NULL);
47 LTC_ARGCHK(G != NULL);
48 LTC_ARGCHK(R != NULL);
49 LTC_ARGCHK(modulus != NULL);
50
51 /* init montgomery reduction */
52 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
53 return err;
54 }
55 if ((err = mp_init(&mu)) != CRYPT_OK) {
56 mp_montgomery_free(mp);
57 return err;
58 }
59 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
60 mp_montgomery_free(mp);
61 mp_clear(mu);
62 return err;
63 }
64
65 /* alloc ram for window temps */
66 for (i = 0; i < 8; i++) {
67 M[i] = ltc_ecc_new_point();
68 if (M[i] == NULL) {
69 for (j = 0; j < i; j++) {
70 ltc_ecc_del_point(M[j]);
71 }
72 mp_montgomery_free(mp);
73 mp_clear(mu);
74 return CRYPT_MEM;
75 }
76 }
77
78 /* make a copy of G incase R==G */
79 tG = ltc_ecc_new_point();
80 if (tG == NULL) { err = CRYPT_MEM; goto done; }
81
82 /* tG = G and convert to montgomery */
83 if (mp_cmp_d(mu, 1) == LTC_MP_EQ) {
84 if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; }
85 if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; }
86 if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; }
87 } else {
88 if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; }
89 if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; }
90 if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; }
91 }
92 mp_clear(mu);
93 mu = NULL;
94
95 /* calc the M tab, which holds kG for k==8..15 */
96 /* M[0] == 8G */
97 if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; }
98 if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
99 if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
100
101 /* now find (8+k)G for k=1..7 */
102 for (j = 9; j < 16; j++) {
103 if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; }
104 }
105
106 /* setup sliding window */
107 mode = 0;
108 bitcnt = 1;
109 buf = 0;
110 digidx = mp_get_digit_count(k) - 1;
111 bitcpy = bitbuf = 0;
112 first = 1;
113
114 /* perform ops */
115 for (;;) {
116 /* grab next digit as required */
117 if (--bitcnt == 0) {
118 if (digidx == -1) {
119 break;
120 }
121 buf = mp_get_digit(k, digidx);
122 bitcnt = (int) ltc_mp.bits_per_digit;
123 --digidx;
124 }
125
126 /* grab the next msb from the ltiplicand */
127 i = (buf >> (ltc_mp.bits_per_digit - 1)) & 1;
128 buf <<= 1;
129
130 /* skip leading zero bits */
131 if (mode == 0 && i == 0) {
132 continue;
133 }
134
135 /* if the bit is zero and mode == 1 then we double */
136 if (mode == 1 && i == 0) {
137 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
138 continue;
139 }
140
141 /* else we add it to the window */
142 bitbuf |= (i << (WINSIZE - ++bitcpy));
143 mode = 2;
144
145 if (bitcpy == WINSIZE) {
146 /* if this is the first window we do a simple copy */
147 if (first == 1) {
148 /* R = kG [k = first window] */
149 if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; }
150 if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; }
151 if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; }
152 first = 0;
153 } else {
154 /* normal window */
155 /* ok window is filled so double as required and add */
156 /* double first */
157 for (j = 0; j < WINSIZE; j++) {
158 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
159 }
160
161 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
162 if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; }
163 }
164 /* empty window and reset */
165 bitcpy = bitbuf = 0;
166 mode = 1;
167 }
168 }
169
170 /* if bits remain then double/add */
171 if (mode == 2 && bitcpy > 0) {
172 /* double then add */
173 for (j = 0; j < bitcpy; j++) {
174 /* only double if we have had at least one add first */
175 if (first == 0) {
176 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
177 }
178
179 bitbuf <<= 1;
180 if ((bitbuf & (1 << WINSIZE)) != 0) {
181 if (first == 1){
182 /* first add, so copy */
183 if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; }
184 if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; }
185 if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; }
186 first = 0;
187 } else {
188 /* then add */
189 if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; }
190 }
191 }
192 }
193 }
194
195 /* map R back from projective space */
196 if (map) {
197 err = ltc_ecc_map(R, modulus, mp);
198 } else {
199 err = CRYPT_OK;
200 }
201 done:
202 if (mu != NULL) {
203 mp_clear(mu);
204 }
205 mp_montgomery_free(mp);
206 ltc_ecc_del_point(tG);
207 for (i = 0; i < 8; i++) {
208 ltc_ecc_del_point(M[i]);
209 }
210 return err;
211 }
212
213 #endif
214
215 #undef WINSIZE
216
217 #endif
218
219 /* $Source$ */
220 /* $Revision$ */
221 /* $Date$ */
+0
-167
libtom-src/pk/ecc/ltc_ecc_mulmod_timing.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_mulmod_timing.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 #ifdef LTC_ECC_TIMING_RESISTANT
26
27 /**
28 Perform a point multiplication (timing resistant)
29 @param k The scalar to multiply by
30 @param G The base point
31 @param R [out] Destination for kG
32 @param modulus The modulus of the field the ECC curve is in
33 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
34 @return CRYPT_OK on success
35 */
36 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
37 {
38 ecc_point *tG, *M[3];
39 int i, j, err;
40 void *mu, *mp;
41 unsigned long buf;
42 int first, bitbuf, bitcpy, bitcnt, mode, digidx;
43
44 LTC_ARGCHK(k != NULL);
45 LTC_ARGCHK(G != NULL);
46 LTC_ARGCHK(R != NULL);
47 LTC_ARGCHK(modulus != NULL);
48
49 /* init montgomery reduction */
50 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
51 return err;
52 }
53 if ((err = mp_init(&mu)) != CRYPT_OK) {
54 mp_montgomery_free(mp);
55 return err;
56 }
57 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
58 mp_clear(mu);
59 mp_montgomery_free(mp);
60 return err;
61 }
62
63 /* alloc ram for window temps */
64 for (i = 0; i < 3; i++) {
65 M[i] = ltc_ecc_new_point();
66 if (M[i] == NULL) {
67 for (j = 0; j < i; j++) {
68 ltc_ecc_del_point(M[j]);
69 }
70 mp_clear(mu);
71 mp_montgomery_free(mp);
72 return CRYPT_MEM;
73 }
74 }
75
76 /* make a copy of G incase R==G */
77 tG = ltc_ecc_new_point();
78 if (tG == NULL) { err = CRYPT_MEM; goto done; }
79
80 /* tG = G and convert to montgomery */
81 if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; }
82 if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; }
83 if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; }
84 mp_clear(mu);
85 mu = NULL;
86
87 /* calc the M tab */
88 /* M[0] == G */
89 if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK) { goto done; }
90 if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; }
91 if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; }
92 /* M[1] == 2G */
93 if ((err = ltc_mp.ecc_ptdbl(tG, M[1], modulus, mp)) != CRYPT_OK) { goto done; }
94
95 /* setup sliding window */
96 mode = 0;
97 bitcnt = 1;
98 buf = 0;
99 digidx = mp_get_digit_count(k) - 1;
100 bitcpy = bitbuf = 0;
101 first = 1;
102
103 /* perform ops */
104 for (;;) {
105 /* grab next digit as required */
106 if (--bitcnt == 0) {
107 if (digidx == -1) {
108 break;
109 }
110 buf = mp_get_digit(k, digidx);
111 bitcnt = (int) MP_DIGIT_BIT;
112 --digidx;
113 }
114
115 /* grab the next msb from the ltiplicand */
116 i = (buf >> (MP_DIGIT_BIT - 1)) & 1;
117 buf <<= 1;
118
119 if (mode == 0 && i == 0) {
120 /* dummy operations */
121 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
122 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
123 continue;
124 }
125
126 if (mode == 0 && i == 1) {
127 mode = 1;
128 /* dummy operations */
129 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
130 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
131 continue;
132 }
133
134 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; }
135 if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; }
136 }
137
138 /* copy result out */
139 if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK) { goto done; }
140 if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK) { goto done; }
141 if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK) { goto done; }
142
143 /* map R back from projective space */
144 if (map) {
145 err = ltc_ecc_map(R, modulus, mp);
146 } else {
147 err = CRYPT_OK;
148 }
149 done:
150 if (mu != NULL) {
151 mp_clear(mu);
152 }
153 mp_montgomery_free(mp);
154 ltc_ecc_del_point(tG);
155 for (i = 0; i < 3; i++) {
156 ltc_ecc_del_point(M[i]);
157 }
158 return err;
159 }
160
161 #endif
162 #endif
163 /* $Source$ */
164 /* $Revision$ */
165 /* $Date$ */
166
+0
-60
libtom-src/pk/ecc/ltc_ecc_points.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_points.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Allocate a new ECC point
27 @return A newly allocated point or NULL on error
28 */
29 ecc_point *ltc_ecc_new_point(void)
30 {
31 ecc_point *p;
32 p = XCALLOC(1, sizeof(*p));
33 if (p == NULL) {
34 return NULL;
35 }
36 if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) {
37 XFREE(p);
38 return NULL;
39 }
40 return p;
41 }
42
43 /** Free an ECC point from memory
44 @param p The point to free
45 */
46 void ltc_ecc_del_point(ecc_point *p)
47 {
48 /* prevents free'ing null arguments */
49 if (p != NULL) {
50 mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */
51 XFREE(p);
52 }
53 }
54
55 #endif
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
59
+0
-196
libtom-src/pk/ecc/ltc_ecc_projective_add_point.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_projective_add_point.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
24
25 /**
26 Add two ECC points
27 @param P The point to add
28 @param Q The point to add
29 @param R [out] The destination of the double
30 @param modulus The modulus of the field the ECC curve is in
31 @param mp The "b" value from montgomery_setup()
32 @return CRYPT_OK on success
33 */
34 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp)
35 {
36 void *t1, *t2, *x, *y, *z;
37 int err;
38
39 LTC_ARGCHK(P != NULL);
40 LTC_ARGCHK(Q != NULL);
41 LTC_ARGCHK(R != NULL);
42 LTC_ARGCHK(modulus != NULL);
43 LTC_ARGCHK(mp != NULL);
44
45 if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) {
46 return err;
47 }
48
49 /* should we dbl instead? */
50 if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; }
51
52 if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) &&
53 (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) &&
54 (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) {
55 mp_clear_multi(t1, t2, x, y, z, NULL);
56 return ltc_ecc_projective_dbl_point(P, R, modulus, mp);
57 }
58
59 if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; }
60 if ((err = mp_copy(P->y, y)) != CRYPT_OK) { goto done; }
61 if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; }
62
63 /* if Z is one then these are no-operations */
64 if (Q->z != NULL) {
65 /* T1 = Z' * Z' */
66 if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; }
67 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
68 /* X = X * T1 */
69 if ((err = mp_mul(t1, x, x)) != CRYPT_OK) { goto done; }
70 if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
71 /* T1 = Z' * T1 */
72 if ((err = mp_mul(Q->z, t1, t1)) != CRYPT_OK) { goto done; }
73 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
74 /* Y = Y * T1 */
75 if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; }
76 if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; }
77 }
78
79 /* T1 = Z*Z */
80 if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; }
81 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
82 /* T2 = X' * T1 */
83 if ((err = mp_mul(Q->x, t1, t2)) != CRYPT_OK) { goto done; }
84 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
85 /* T1 = Z * T1 */
86 if ((err = mp_mul(z, t1, t1)) != CRYPT_OK) { goto done; }
87 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
88 /* T1 = Y' * T1 */
89 if ((err = mp_mul(Q->y, t1, t1)) != CRYPT_OK) { goto done; }
90 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
91
92 /* Y = Y - T1 */
93 if ((err = mp_sub(y, t1, y)) != CRYPT_OK) { goto done; }
94 if (mp_cmp_d(y, 0) == LTC_MP_LT) {
95 if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
96 }
97 /* T1 = 2T1 */
98 if ((err = mp_add(t1, t1, t1)) != CRYPT_OK) { goto done; }
99 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
100 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
101 }
102 /* T1 = Y + T1 */
103 if ((err = mp_add(t1, y, t1)) != CRYPT_OK) { goto done; }
104 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
105 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
106 }
107 /* X = X - T2 */
108 if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; }
109 if (mp_cmp_d(x, 0) == LTC_MP_LT) {
110 if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; }
111 }
112 /* T2 = 2T2 */
113 if ((err = mp_add(t2, t2, t2)) != CRYPT_OK) { goto done; }
114 if (mp_cmp(t2, modulus) != LTC_MP_LT) {
115 if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; }
116 }
117 /* T2 = X + T2 */
118 if ((err = mp_add(t2, x, t2)) != CRYPT_OK) { goto done; }
119 if (mp_cmp(t2, modulus) != LTC_MP_LT) {
120 if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; }
121 }
122
123 /* if Z' != 1 */
124 if (Q->z != NULL) {
125 /* Z = Z * Z' */
126 if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; }
127 if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; }
128 }
129
130 /* Z = Z * X */
131 if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; }
132 if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; }
133
134 /* T1 = T1 * X */
135 if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; }
136 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
137 /* X = X * X */
138 if ((err = mp_sqr(x, x)) != CRYPT_OK) { goto done; }
139 if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
140 /* T2 = T2 * x */
141 if ((err = mp_mul(t2, x, t2)) != CRYPT_OK) { goto done; }
142 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
143 /* T1 = T1 * X */
144 if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; }
145 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
146
147 /* X = Y*Y */
148 if ((err = mp_sqr(y, x)) != CRYPT_OK) { goto done; }
149 if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
150 /* X = X - T2 */
151 if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; }
152 if (mp_cmp_d(x, 0) == LTC_MP_LT) {
153 if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; }
154 }
155
156 /* T2 = T2 - X */
157 if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; }
158 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
159 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
160 }
161 /* T2 = T2 - X */
162 if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; }
163 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
164 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
165 }
166 /* T2 = T2 * Y */
167 if ((err = mp_mul(t2, y, t2)) != CRYPT_OK) { goto done; }
168 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
169 /* Y = T2 - T1 */
170 if ((err = mp_sub(t2, t1, y)) != CRYPT_OK) { goto done; }
171 if (mp_cmp_d(y, 0) == LTC_MP_LT) {
172 if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
173 }
174 /* Y = Y/2 */
175 if (mp_isodd(y)) {
176 if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
177 }
178 if ((err = mp_div_2(y, y)) != CRYPT_OK) { goto done; }
179
180 if ((err = mp_copy(x, R->x)) != CRYPT_OK) { goto done; }
181 if ((err = mp_copy(y, R->y)) != CRYPT_OK) { goto done; }
182 if ((err = mp_copy(z, R->z)) != CRYPT_OK) { goto done; }
183
184 err = CRYPT_OK;
185 done:
186 mp_clear_multi(t1, t2, x, y, z, NULL);
187 return err;
188 }
189
190 #endif
191
192 /* $Source$ */
193 /* $Revision$ */
194 /* $Date$ */
195
+0
-147
libtom-src/pk/ecc/ltc_ecc_projective_dbl_point.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_projective_dbl_point.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
24
25 /**
26 Double an ECC point
27 @param P The point to double
28 @param R [out] The destination of the double
29 @param modulus The modulus of the field the ECC curve is in
30 @param mp The "b" value from montgomery_setup()
31 @return CRYPT_OK on success
32 */
33 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp)
34 {
35 void *t1, *t2;
36 int err;
37
38 LTC_ARGCHK(P != NULL);
39 LTC_ARGCHK(R != NULL);
40 LTC_ARGCHK(modulus != NULL);
41 LTC_ARGCHK(mp != NULL);
42
43 if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
44 return err;
45 }
46
47 if (P != R) {
48 if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; }
49 if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; }
50 if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; }
51 }
52
53 /* t1 = Z * Z */
54 if ((err = mp_sqr(R->z, t1)) != CRYPT_OK) { goto done; }
55 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
56 /* Z = Y * Z */
57 if ((err = mp_mul(R->z, R->y, R->z)) != CRYPT_OK) { goto done; }
58 if ((err = mp_montgomery_reduce(R->z, modulus, mp)) != CRYPT_OK) { goto done; }
59 /* Z = 2Z */
60 if ((err = mp_add(R->z, R->z, R->z)) != CRYPT_OK) { goto done; }
61 if (mp_cmp(R->z, modulus) != LTC_MP_LT) {
62 if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; }
63 }
64
65 /* T2 = X - T1 */
66 if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; }
67 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
68 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
69 }
70 /* T1 = X + T1 */
71 if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; }
72 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
73 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
74 }
75 /* T2 = T1 * T2 */
76 if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; }
77 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
78 /* T1 = 2T2 */
79 if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; }
80 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
81 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
82 }
83 /* T1 = T1 + T2 */
84 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
85 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
86 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
87 }
88
89 /* Y = 2Y */
90 if ((err = mp_add(R->y, R->y, R->y)) != CRYPT_OK) { goto done; }
91 if (mp_cmp(R->y, modulus) != LTC_MP_LT) {
92 if ((err = mp_sub(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
93 }
94 /* Y = Y * Y */
95 if ((err = mp_sqr(R->y, R->y)) != CRYPT_OK) { goto done; }
96 if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
97 /* T2 = Y * Y */
98 if ((err = mp_sqr(R->y, t2)) != CRYPT_OK) { goto done; }
99 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
100 /* T2 = T2/2 */
101 if (mp_isodd(t2)) {
102 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
103 }
104 if ((err = mp_div_2(t2, t2)) != CRYPT_OK) { goto done; }
105 /* Y = Y * X */
106 if ((err = mp_mul(R->y, R->x, R->y)) != CRYPT_OK) { goto done; }
107 if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
108
109 /* X = T1 * T1 */
110 if ((err = mp_sqr(t1, R->x)) != CRYPT_OK) { goto done; }
111 if ((err = mp_montgomery_reduce(R->x, modulus, mp)) != CRYPT_OK) { goto done; }
112 /* X = X - Y */
113 if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; }
114 if (mp_cmp_d(R->x, 0) == LTC_MP_LT) {
115 if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; }
116 }
117 /* X = X - Y */
118 if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; }
119 if (mp_cmp_d(R->x, 0) == LTC_MP_LT) {
120 if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; }
121 }
122
123 /* Y = Y - X */
124 if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; }
125 if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
126 if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
127 }
128 /* Y = Y * T1 */
129 if ((err = mp_mul(R->y, t1, R->y)) != CRYPT_OK) { goto done; }
130 if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
131 /* Y = Y - T2 */
132 if ((err = mp_sub(R->y, t2, R->y)) != CRYPT_OK) { goto done; }
133 if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
134 if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
135 }
136
137 err = CRYPT_OK;
138 done:
139 mp_clear_multi(t1, t2, NULL);
140 return err;
141 }
142 #endif
143 /* $Source$ */
144 /* $Revision$ */
145 /* $Date$ */
146
+0
-51
libtom-src/pk/pkcs1/pkcs_1_i2osp.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_i2osp.c
14 Integer to Octet I2OSP, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /* always stores the same # of bytes, pads with leading zero bytes
20 as required
21 */
22
23 /**
24 LTC_PKCS #1 Integer to binary
25 @param n The integer to store
26 @param modulus_len The length of the RSA modulus
27 @param out [out] The destination for the integer
28 @return CRYPT_OK if successful
29 */
30 int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out)
31 {
32 unsigned long size;
33
34 size = mp_unsigned_bin_size(n);
35
36 if (size > modulus_len) {
37 return CRYPT_BUFFER_OVERFLOW;
38 }
39
40 /* store it */
41 zeromem(out, modulus_len);
42 return mp_to_unsigned_bin(n, out+(modulus_len-size));
43 }
44
45 #endif /* LTC_PKCS_1 */
46
47
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
+0
-108
libtom-src/pk/pkcs1/pkcs_1_mgf1.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_mgf1.c
14 The Mask Generation Function (MGF1) for LTC_PKCS #1, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 Perform LTC_PKCS #1 MGF1 (internal)
21 @param seed The seed for MGF1
22 @param seedlen The length of the seed
23 @param hash_idx The index of the hash desired
24 @param mask [out] The destination
25 @param masklen The length of the mask desired
26 @return CRYPT_OK if successful
27 */
28 int pkcs_1_mgf1(int hash_idx,
29 const unsigned char *seed, unsigned long seedlen,
30 unsigned char *mask, unsigned long masklen)
31 {
32 unsigned long hLen, x;
33 ulong32 counter;
34 int err;
35 hash_state *md;
36 unsigned char *buf;
37
38 LTC_ARGCHK(seed != NULL);
39 LTC_ARGCHK(mask != NULL);
40
41 /* ensure valid hash */
42 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
43 return err;
44 }
45
46 /* get hash output size */
47 hLen = hash_descriptor[hash_idx].hashsize;
48
49 /* allocate memory */
50 md = XMALLOC(sizeof(hash_state));
51 buf = XMALLOC(hLen);
52 if (md == NULL || buf == NULL) {
53 if (md != NULL) {
54 XFREE(md);
55 }
56 if (buf != NULL) {
57 XFREE(buf);
58 }
59 return CRYPT_MEM;
60 }
61
62 /* start counter */
63 counter = 0;
64
65 while (masklen > 0) {
66 /* handle counter */
67 STORE32H(counter, buf);
68 ++counter;
69
70 /* get hash of seed || counter */
71 if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
72 goto LBL_ERR;
73 }
74 if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77 if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80 if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
81 goto LBL_ERR;
82 }
83
84 /* store it */
85 for (x = 0; x < hLen && masklen > 0; x++, masklen--) {
86 *mask++ = buf[x];
87 }
88 }
89
90 err = CRYPT_OK;
91 LBL_ERR:
92 #ifdef LTC_CLEAN_STACK
93 zeromem(buf, hLen);
94 zeromem(md, sizeof(hash_state));
95 #endif
96
97 XFREE(buf);
98 XFREE(md);
99
100 return err;
101 }
102
103 #endif /* LTC_PKCS_1 */
104
105 /* $Source$ */
106 /* $Revision$ */
107 /* $Date$ */
+0
-189
libtom-src/pk/pkcs1/pkcs_1_oaep_decode.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_oaep_decode.c
14 OAEP Padding for LTC_PKCS #1, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 LTC_PKCS #1 v2.00 OAEP decode
21 @param msg The encoded data to decode
22 @param msglen The length of the encoded data (octets)
23 @param lparam The session or system data (can be NULL)
24 @param lparamlen The length of the lparam
25 @param modulus_bitlen The bit length of the RSA modulus
26 @param hash_idx The index of the hash desired
27 @param out [out] Destination of decoding
28 @param outlen [in/out] The max size and resulting size of the decoding
29 @param res [out] Result of decoding, 1==valid, 0==invalid
30 @return CRYPT_OK if successful (even if invalid)
31 */
32 int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
33 const unsigned char *lparam, unsigned long lparamlen,
34 unsigned long modulus_bitlen, int hash_idx,
35 unsigned char *out, unsigned long *outlen,
36 int *res)
37 {
38 unsigned char *DB, *seed, *mask;
39 unsigned long hLen, x, y, modulus_len;
40 int err;
41
42 LTC_ARGCHK(msg != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(res != NULL);
46
47 /* default to invalid packet */
48 *res = 0;
49
50 /* test valid hash */
51 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
52 return err;
53 }
54 hLen = hash_descriptor[hash_idx].hashsize;
55 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
56
57 /* test hash/message size */
58 if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) {
59 return CRYPT_PK_INVALID_SIZE;
60 }
61
62 /* allocate ram for DB/mask/salt of size modulus_len */
63 DB = XMALLOC(modulus_len);
64 mask = XMALLOC(modulus_len);
65 seed = XMALLOC(hLen);
66 if (DB == NULL || mask == NULL || seed == NULL) {
67 if (DB != NULL) {
68 XFREE(DB);
69 }
70 if (mask != NULL) {
71 XFREE(mask);
72 }
73 if (seed != NULL) {
74 XFREE(seed);
75 }
76 return CRYPT_MEM;
77 }
78
79 /* ok so it's now in the form
80
81 0x00 || maskedseed || maskedDB
82
83 1 || hLen || modulus_len - hLen - 1
84
85 */
86
87 /* must have leading 0x00 byte */
88 if (msg[0] != 0x00) {
89 err = CRYPT_OK;
90 goto LBL_ERR;
91 }
92
93 /* now read the masked seed */
94 x = 1;
95 XMEMCPY(seed, msg + x, hLen);
96 x += hLen;
97
98 /* now read the masked DB */
99 XMEMCPY(DB, msg + x, modulus_len - hLen - 1);
100 x += modulus_len - hLen - 1;
101
102 /* compute MGF1 of maskedDB (hLen) */
103 if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
104 goto LBL_ERR;
105 }
106
107 /* XOR against seed */
108 for (y = 0; y < hLen; y++) {
109 seed[y] ^= mask[y];
110 }
111
112 /* compute MGF1 of seed (k - hlen - 1) */
113 if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
114 goto LBL_ERR;
115 }
116
117 /* xor against DB */
118 for (y = 0; y < (modulus_len - hLen - 1); y++) {
119 DB[y] ^= mask[y];
120 }
121
122 /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */
123
124 /* compute lhash and store it in seed [reuse temps!] */
125 x = modulus_len;
126 if (lparam != NULL) {
127 if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) {
128 goto LBL_ERR;
129 }
130 } else {
131 /* can't pass hash_memory a NULL so use DB with zero length */
132 if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) {
133 goto LBL_ERR;
134 }
135 }
136
137 /* compare the lhash'es */
138 if (XMEMCMP(seed, DB, hLen) != 0) {
139 err = CRYPT_OK;
140 goto LBL_ERR;
141 }
142
143 /* now zeroes before a 0x01 */
144 for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) {
145 /* step... */
146 }
147
148 /* error out if wasn't 0x01 */
149 if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) {
150 err = CRYPT_INVALID_PACKET;
151 goto LBL_ERR;
152 }
153
154 /* rest is the message (and skip 0x01) */
155 if ((modulus_len - hLen - 1 - ++x) > *outlen) {
156 *outlen = modulus_len - hLen - 1 - x;
157 err = CRYPT_BUFFER_OVERFLOW;
158 goto LBL_ERR;
159 }
160
161 /* copy message */
162 *outlen = modulus_len - hLen - 1 - x;
163 XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x);
164 x += modulus_len - hLen - 1;
165
166 /* valid packet */
167 *res = 1;
168
169 err = CRYPT_OK;
170 LBL_ERR:
171 #ifdef LTC_CLEAN_STACK
172 zeromem(DB, modulus_len);
173 zeromem(seed, hLen);
174 zeromem(mask, modulus_len);
175 #endif
176
177 XFREE(seed);
178 XFREE(mask);
179 XFREE(DB);
180
181 return err;
182 }
183
184 #endif /* LTC_PKCS_1 */
185
186 /* $Source$ */
187 /* $Revision$ */
188 /* $Date$ */
+0
-173
libtom-src/pk/pkcs1/pkcs_1_oaep_encode.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_oaep_encode.c
14 OAEP Padding for LTC_PKCS #1, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 LTC_PKCS #1 v2.00 OAEP encode
21 @param msg The data to encode
22 @param msglen The length of the data to encode (octets)
23 @param lparam A session or system parameter (can be NULL)
24 @param lparamlen The length of the lparam data
25 @param modulus_bitlen The bit length of the RSA modulus
26 @param prng An active PRNG state
27 @param prng_idx The index of the PRNG desired
28 @param hash_idx The index of the hash desired
29 @param out [out] The destination for the encoded data
30 @param outlen [in/out] The max size and resulting size of the encoded data
31 @return CRYPT_OK if successful
32 */
33 int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
34 const unsigned char *lparam, unsigned long lparamlen,
35 unsigned long modulus_bitlen, prng_state *prng,
36 int prng_idx, int hash_idx,
37 unsigned char *out, unsigned long *outlen)
38 {
39 unsigned char *DB, *seed, *mask;
40 unsigned long hLen, x, y, modulus_len;
41 int err;
42
43 LTC_ARGCHK(msg != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 /* test valid hash */
48 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
49 return err;
50 }
51
52 /* valid prng */
53 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
54 return err;
55 }
56
57 hLen = hash_descriptor[hash_idx].hashsize;
58 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
59
60 /* test message size */
61 if ((2*hLen >= (modulus_len - 2)) || (msglen > (modulus_len - 2*hLen - 2))) {
62 return CRYPT_PK_INVALID_SIZE;
63 }
64
65 /* allocate ram for DB/mask/salt of size modulus_len */
66 DB = XMALLOC(modulus_len);
67 mask = XMALLOC(modulus_len);
68 seed = XMALLOC(hLen);
69 if (DB == NULL || mask == NULL || seed == NULL) {
70 if (DB != NULL) {
71 XFREE(DB);
72 }
73 if (mask != NULL) {
74 XFREE(mask);
75 }
76 if (seed != NULL) {
77 XFREE(seed);
78 }
79 return CRYPT_MEM;
80 }
81
82 /* get lhash */
83 /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */
84 x = modulus_len;
85 if (lparam != NULL) {
86 if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) {
87 goto LBL_ERR;
88 }
89 } else {
90 /* can't pass hash_memory a NULL so use DB with zero length */
91 if ((err = hash_memory(hash_idx, DB, 0, DB, &x)) != CRYPT_OK) {
92 goto LBL_ERR;
93 }
94 }
95
96 /* append PS then 0x01 (to lhash) */
97 x = hLen;
98 y = modulus_len - msglen - 2*hLen - 2;
99 XMEMSET(DB+x, 0, y);
100 x += y;
101
102 /* 0x01 byte */
103 DB[x++] = 0x01;
104
105 /* message (length = msglen) */
106 XMEMCPY(DB+x, msg, msglen);
107 x += msglen;
108
109 /* now choose a random seed */
110 if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) {
111 err = CRYPT_ERROR_READPRNG;
112 goto LBL_ERR;
113 }
114
115 /* compute MGF1 of seed (k - hlen - 1) */
116 if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
117 goto LBL_ERR;
118 }
119
120 /* xor against DB */
121 for (y = 0; y < (modulus_len - hLen - 1); y++) {
122 DB[y] ^= mask[y];
123 }
124
125 /* compute MGF1 of maskedDB (hLen) */
126 if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
127 goto LBL_ERR;
128 }
129
130 /* XOR against seed */
131 for (y = 0; y < hLen; y++) {
132 seed[y] ^= mask[y];
133 }
134
135 /* create string of length modulus_len */
136 if (*outlen < modulus_len) {
137 *outlen = modulus_len;
138 err = CRYPT_BUFFER_OVERFLOW;
139 goto LBL_ERR;
140 }
141
142 /* start output which is 0x00 || maskedSeed || maskedDB */
143 x = 0;
144 out[x++] = 0x00;
145 XMEMCPY(out+x, seed, hLen);
146 x += hLen;
147 XMEMCPY(out+x, DB, modulus_len - hLen - 1);
148 x += modulus_len - hLen - 1;
149
150 *outlen = x;
151
152 err = CRYPT_OK;
153 LBL_ERR:
154 #ifdef LTC_CLEAN_STACK
155 zeromem(DB, modulus_len);
156 zeromem(seed, hLen);
157 zeromem(mask, modulus_len);
158 #endif
159
160 XFREE(seed);
161 XFREE(mask);
162 XFREE(DB);
163
164 return err;
165 }
166
167 #endif /* LTC_PKCS_1 */
168
169
170 /* $Source$ */
171 /* $Revision$ */
172 /* $Date$ */
+0
-36
libtom-src/pk/pkcs1/pkcs_1_os2ip.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_os2ip.c
14 Octet to Integer OS2IP, Tom St Denis
15 */
16 #ifdef LTC_PKCS_1
17
18 /**
19 Read a binary string into an mp_int
20 @param n [out] The mp_int destination
21 @param in The binary string to read
22 @param inlen The length of the binary string
23 @return CRYPT_OK if successful
24 */
25 int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen)
26 {
27 return mp_read_unsigned_bin(n, in, inlen);
28 }
29
30 #endif /* LTC_PKCS_1 */
31
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
+0
-177
libtom-src/pk/pkcs1/pkcs_1_pss_decode.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_pss_decode.c
14 LTC_PKCS #1 PSS Signature Padding, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 LTC_PKCS #1 v2.00 PSS decode
21 @param msghash The hash to verify
22 @param msghashlen The length of the hash (octets)
23 @param sig The signature data (encoded data)
24 @param siglen The length of the signature data (octets)
25 @param saltlen The length of the salt used (octets)
26 @param hash_idx The index of the hash desired
27 @param modulus_bitlen The bit length of the RSA modulus
28 @param res [out] The result of the comparison, 1==valid, 0==invalid
29 @return CRYPT_OK if successful (even if the comparison failed)
30 */
31 int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
32 const unsigned char *sig, unsigned long siglen,
33 unsigned long saltlen, int hash_idx,
34 unsigned long modulus_bitlen, int *res)
35 {
36 unsigned char *DB, *mask, *salt, *hash;
37 unsigned long x, y, hLen, modulus_len;
38 int err;
39 hash_state md;
40
41 LTC_ARGCHK(msghash != NULL);
42 LTC_ARGCHK(res != NULL);
43
44 /* default to invalid */
45 *res = 0;
46
47 /* ensure hash is valid */
48 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
49 return err;
50 }
51
52 hLen = hash_descriptor[hash_idx].hashsize;
53 modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
54
55 /* check sizes */
56 if ((saltlen > modulus_len) ||
57 (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) {
58 return CRYPT_PK_INVALID_SIZE;
59 }
60
61 /* allocate ram for DB/mask/salt/hash of size modulus_len */
62 DB = XMALLOC(modulus_len);
63 mask = XMALLOC(modulus_len);
64 salt = XMALLOC(modulus_len);
65 hash = XMALLOC(modulus_len);
66 if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) {
67 if (DB != NULL) {
68 XFREE(DB);
69 }
70 if (mask != NULL) {
71 XFREE(mask);
72 }
73 if (salt != NULL) {
74 XFREE(salt);
75 }
76 if (hash != NULL) {
77 XFREE(hash);
78 }
79 return CRYPT_MEM;
80 }
81
82 /* ensure the 0xBC byte */
83 if (sig[siglen-1] != 0xBC) {
84 err = CRYPT_INVALID_PACKET;
85 goto LBL_ERR;
86 }
87
88 /* copy out the DB */
89 x = 0;
90 XMEMCPY(DB, sig + x, modulus_len - hLen - 1);
91 x += modulus_len - hLen - 1;
92
93 /* copy out the hash */
94 XMEMCPY(hash, sig + x, hLen);
95 x += hLen;
96
97 /* check the MSB */
98 if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
99 err = CRYPT_INVALID_PACKET;
100 goto LBL_ERR;
101 }
102
103 /* generate mask of length modulus_len - hLen - 1 from hash */
104 if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
105 goto LBL_ERR;
106 }
107
108 /* xor against DB */
109 for (y = 0; y < (modulus_len - hLen - 1); y++) {
110 DB[y] ^= mask[y];
111 }
112
113 /* now clear the first byte [make sure smaller than modulus] */
114 DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
115
116 /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
117
118 /* check for zeroes and 0x01 */
119 for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) {
120 if (DB[x] != 0x00) {
121 err = CRYPT_INVALID_PACKET;
122 goto LBL_ERR;
123 }
124 }
125
126 /* check for the 0x01 */
127 if (DB[x++] != 0x01) {
128 err = CRYPT_INVALID_PACKET;
129 goto LBL_ERR;
130 }
131
132 /* M = (eight) 0x00 || msghash || salt, mask = H(M) */
133 if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) {
134 goto LBL_ERR;
135 }
136 zeromem(mask, 8);
137 if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) {
138 goto LBL_ERR;
139 }
140 if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) {
141 goto LBL_ERR;
142 }
143 if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) {
144 goto LBL_ERR;
145 }
146 if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) {
147 goto LBL_ERR;
148 }
149
150 /* mask == hash means valid signature */
151 if (XMEMCMP(mask, hash, hLen) == 0) {
152 *res = 1;
153 }
154
155 err = CRYPT_OK;
156 LBL_ERR:
157 #ifdef LTC_CLEAN_STACK
158 zeromem(DB, modulus_len);
159 zeromem(mask, modulus_len);
160 zeromem(salt, modulus_len);
161 zeromem(hash, modulus_len);
162 #endif
163
164 XFREE(hash);
165 XFREE(salt);
166 XFREE(mask);
167 XFREE(DB);
168
169 return err;
170 }
171
172 #endif /* LTC_PKCS_1 */
173
174 /* $Source$ */
175 /* $Revision$ */
176 /* $Date$ */
+0
-175
libtom-src/pk/pkcs1/pkcs_1_pss_encode.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_pss_encode.c
14 LTC_PKCS #1 PSS Signature Padding, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 LTC_PKCS #1 v2.00 Signature Encoding
21 @param msghash The hash to encode
22 @param msghashlen The length of the hash (octets)
23 @param saltlen The length of the salt desired (octets)
24 @param prng An active PRNG context
25 @param prng_idx The index of the PRNG desired
26 @param hash_idx The index of the hash desired
27 @param modulus_bitlen The bit length of the RSA modulus
28 @param out [out] The destination of the encoding
29 @param outlen [in/out] The max size and resulting size of the encoded data
30 @return CRYPT_OK if successful
31 */
32 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
33 unsigned long saltlen, prng_state *prng,
34 int prng_idx, int hash_idx,
35 unsigned long modulus_bitlen,
36 unsigned char *out, unsigned long *outlen)
37 {
38 unsigned char *DB, *mask, *salt, *hash;
39 unsigned long x, y, hLen, modulus_len;
40 int err;
41 hash_state md;
42
43 LTC_ARGCHK(msghash != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 /* ensure hash and PRNG are valid */
48 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
49 return err;
50 }
51 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
52 return err;
53 }
54
55 hLen = hash_descriptor[hash_idx].hashsize;
56 modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
57
58 /* check sizes */
59 if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2)) {
60 return CRYPT_PK_INVALID_SIZE;
61 }
62
63 /* allocate ram for DB/mask/salt/hash of size modulus_len */
64 DB = XMALLOC(modulus_len);
65 mask = XMALLOC(modulus_len);
66 salt = XMALLOC(modulus_len);
67 hash = XMALLOC(modulus_len);
68 if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) {
69 if (DB != NULL) {
70 XFREE(DB);
71 }
72 if (mask != NULL) {
73 XFREE(mask);
74 }
75 if (salt != NULL) {
76 XFREE(salt);
77 }
78 if (hash != NULL) {
79 XFREE(hash);
80 }
81 return CRYPT_MEM;
82 }
83
84
85 /* generate random salt */
86 if (saltlen > 0) {
87 if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) {
88 err = CRYPT_ERROR_READPRNG;
89 goto LBL_ERR;
90 }
91 }
92
93 /* M = (eight) 0x00 || msghash || salt, hash = H(M) */
94 if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) {
95 goto LBL_ERR;
96 }
97 zeromem(DB, 8);
98 if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) {
99 goto LBL_ERR;
100 }
101 if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104 if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) {
105 goto LBL_ERR;
106 }
107 if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) {
108 goto LBL_ERR;
109 }
110
111 /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
112 x = 0;
113 XMEMSET(DB + x, 0, modulus_len - saltlen - hLen - 2);
114 x += modulus_len - saltlen - hLen - 2;
115 DB[x++] = 0x01;
116 XMEMCPY(DB + x, salt, saltlen);
117 x += saltlen;
118
119 /* generate mask of length modulus_len - hLen - 1 from hash */
120 if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
121 goto LBL_ERR;
122 }
123
124 /* xor against DB */
125 for (y = 0; y < (modulus_len - hLen - 1); y++) {
126 DB[y] ^= mask[y];
127 }
128
129 /* output is DB || hash || 0xBC */
130 if (*outlen < modulus_len) {
131 *outlen = modulus_len;
132 err = CRYPT_BUFFER_OVERFLOW;
133 goto LBL_ERR;
134 }
135
136 /* DB len = modulus_len - hLen - 1 */
137 y = 0;
138 XMEMCPY(out + y, DB, modulus_len - hLen - 1);
139 y += modulus_len - hLen - 1;
140
141 /* hash */
142 XMEMCPY(out + y, hash, hLen);
143 y += hLen;
144
145 /* 0xBC */
146 out[y] = 0xBC;
147
148 /* now clear the 8*modulus_len - modulus_bitlen most significant bits */
149 out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
150
151 /* store output size */
152 *outlen = modulus_len;
153 err = CRYPT_OK;
154 LBL_ERR:
155 #ifdef LTC_CLEAN_STACK
156 zeromem(DB, modulus_len);
157 zeromem(mask, modulus_len);
158 zeromem(salt, modulus_len);
159 zeromem(hash, modulus_len);
160 #endif
161
162 XFREE(hash);
163 XFREE(salt);
164 XFREE(mask);
165 XFREE(DB);
166
167 return err;
168 }
169
170 #endif /* LTC_PKCS_1 */
171
172 /* $Source$ */
173 /* $Revision$ */
174 /* $Date$ */
+0
-110
libtom-src/pk/pkcs1/pkcs_1_v1_5_decode.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /** @file pkcs_1_v1_5_decode.c
13 *
14 * LTC_PKCS #1 v1.5 Padding. (Andreas Lange)
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /** @brief LTC_PKCS #1 v1.5 decode.
20 *
21 * @param msg The encoded data to decode
22 * @param msglen The length of the encoded data (octets)
23 * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
24 * @param modulus_bitlen The bit length of the RSA modulus
25 * @param out [out] Destination of decoding
26 * @param outlen [in/out] The max size and resulting size of the decoding
27 * @param is_valid [out] Boolean whether the padding was valid
28 *
29 * @return CRYPT_OK if successful (even if invalid)
30 */
31 int pkcs_1_v1_5_decode(const unsigned char *msg,
32 unsigned long msglen,
33 int block_type,
34 unsigned long modulus_bitlen,
35 unsigned char *out,
36 unsigned long *outlen,
37 int *is_valid)
38 {
39 unsigned long modulus_len, ps_len, i;
40 int result;
41
42 /* default to invalid packet */
43 *is_valid = 0;
44
45 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
46
47 /* test message size */
48
49 if ((msglen > modulus_len) || (modulus_len < 11)) {
50 return CRYPT_PK_INVALID_SIZE;
51 }
52
53 /* separate encoded message */
54
55 if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) {
56 result = CRYPT_INVALID_PACKET;
57 goto bail;
58 }
59
60 if (block_type == LTC_PKCS_1_EME) {
61 for (i = 2; i < modulus_len; i++) {
62 /* separator */
63 if (msg[i] == 0x00) { break; }
64 }
65 ps_len = i++ - 2;
66
67 if ((i >= modulus_len) || (ps_len < 8)) {
68 /* There was no octet with hexadecimal value 0x00 to separate ps from m,
69 * or the length of ps is less than 8 octets.
70 */
71 result = CRYPT_INVALID_PACKET;
72 goto bail;
73 }
74 } else {
75 for (i = 2; i < modulus_len - 1; i++) {
76 if (msg[i] != 0xFF) { break; }
77 }
78
79 /* separator check */
80 if (msg[i] != 0) {
81 /* There was no octet with hexadecimal value 0x00 to separate ps from m. */
82 result = CRYPT_INVALID_PACKET;
83 goto bail;
84 }
85
86 ps_len = i - 2;
87 }
88
89 if (*outlen < (msglen - (2 + ps_len + 1))) {
90 *outlen = msglen - (2 + ps_len + 1);
91 result = CRYPT_BUFFER_OVERFLOW;
92 goto bail;
93 }
94
95 *outlen = (msglen - (2 + ps_len + 1));
96 XMEMCPY(out, &msg[2 + ps_len + 1], *outlen);
97
98 /* valid packet */
99 *is_valid = 1;
100 result = CRYPT_OK;
101 bail:
102 return result;
103 } /* pkcs_1_v1_5_decode */
104
105 #endif /* #ifdef LTC_PKCS_1 */
106
107 /* $Source$ */
108 /* $Revision$ */
109 /* $Date$ */
+0
-111
libtom-src/pk/pkcs1/pkcs_1_v1_5_encode.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /*! \file pkcs_1_v1_5_encode.c
13 *
14 * LTC_PKCS #1 v1.5 Padding (Andreas Lange)
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /*! \brief LTC_PKCS #1 v1.5 encode.
20 *
21 * \param msg The data to encode
22 * \param msglen The length of the data to encode (octets)
23 * \param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
24 * \param modulus_bitlen The bit length of the RSA modulus
25 * \param prng An active PRNG state (only for LTC_PKCS_1_EME)
26 * \param prng_idx The index of the PRNG desired (only for LTC_PKCS_1_EME)
27 * \param out [out] The destination for the encoded data
28 * \param outlen [in/out] The max size and resulting size of the encoded data
29 *
30 * \return CRYPT_OK if successful
31 */
32 int pkcs_1_v1_5_encode(const unsigned char *msg,
33 unsigned long msglen,
34 int block_type,
35 unsigned long modulus_bitlen,
36 prng_state *prng,
37 int prng_idx,
38 unsigned char *out,
39 unsigned long *outlen)
40 {
41 unsigned long modulus_len, ps_len, i;
42 unsigned char *ps;
43 int result;
44
45 /* valid block_type? */
46 if ((block_type != LTC_PKCS_1_EMSA) &&
47 (block_type != LTC_PKCS_1_EME)) {
48 return CRYPT_PK_INVALID_PADDING;
49 }
50
51 if (block_type == LTC_PKCS_1_EME) { /* encryption padding, we need a valid PRNG */
52 if ((result = prng_is_valid(prng_idx)) != CRYPT_OK) {
53 return result;
54 }
55 }
56
57 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
58
59 /* test message size */
60 if ((msglen + 11) > modulus_len) {
61 return CRYPT_PK_INVALID_SIZE;
62 }
63
64 if (*outlen < modulus_len) {
65 *outlen = modulus_len;
66 result = CRYPT_BUFFER_OVERFLOW;
67 goto bail;
68 }
69
70 /* generate an octets string PS */
71 ps = &out[2];
72 ps_len = modulus_len - msglen - 3;
73
74 if (block_type == LTC_PKCS_1_EME) {
75 /* now choose a random ps */
76 if (prng_descriptor[prng_idx].read(ps, ps_len, prng) != ps_len) {
77 result = CRYPT_ERROR_READPRNG;
78 goto bail;
79 }
80
81 /* transform zero bytes (if any) to non-zero random bytes */
82 for (i = 0; i < ps_len; i++) {
83 while (ps[i] == 0) {
84 if (prng_descriptor[prng_idx].read(&ps[i], 1, prng) != 1) {
85 result = CRYPT_ERROR_READPRNG;
86 goto bail;
87 }
88 }
89 }
90 } else {
91 XMEMSET(ps, 0xFF, ps_len);
92 }
93
94 /* create string of length modulus_len */
95 out[0] = 0x00;
96 out[1] = (unsigned char)block_type; /* block_type 1 or 2 */
97 out[2 + ps_len] = 0x00;
98 XMEMCPY(&out[2 + ps_len + 1], msg, msglen);
99 *outlen = modulus_len;
100
101 result = CRYPT_OK;
102 bail:
103 return result;
104 } /* pkcs_1_v1_5_encode */
105
106 #endif /* #ifdef LTC_PKCS_1 */
107
108 /* $Source$ */
109 /* $Revision$ */
110 /* $Date$ */
+0
-105
libtom-src/pk/rsa/rsa_decrypt_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_decrypt_key.c
14 RSA LTC_PKCS #1 Decryption, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 LTC_PKCS #1 decrypt then v1.5 or OAEP depad
21 @param in The ciphertext
22 @param inlen The length of the ciphertext (octets)
23 @param out [out] The plaintext
24 @param outlen [in/out] The max size and resulting size of the plaintext (octets)
25 @param lparam The system "lparam" value
26 @param lparamlen The length of the lparam value (octets)
27 @param hash_idx The index of the hash desired
28 @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5)
29 @param stat [out] Result of the decryption, 1==valid, 0==invalid
30 @param key The corresponding private RSA key
31 @return CRYPT_OK if succcessul (even if invalid)
32 */
33 int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *lparam, unsigned long lparamlen,
36 int hash_idx, int padding,
37 int *stat, rsa_key *key)
38 {
39 unsigned long modulus_bitlen, modulus_bytelen, x;
40 int err;
41 unsigned char *tmp;
42
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(key != NULL);
46 LTC_ARGCHK(stat != NULL);
47
48 /* default to invalid */
49 *stat = 0;
50
51 /* valid padding? */
52
53 if ((padding != LTC_PKCS_1_V1_5) &&
54 (padding != LTC_PKCS_1_OAEP)) {
55 return CRYPT_PK_INVALID_PADDING;
56 }
57
58 if (padding == LTC_PKCS_1_OAEP) {
59 /* valid hash ? */
60 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
61 return err;
62 }
63 }
64
65 /* get modulus len in bits */
66 modulus_bitlen = mp_count_bits( (key->N));
67
68 /* outlen must be at least the size of the modulus */
69 modulus_bytelen = mp_unsigned_bin_size( (key->N));
70 if (modulus_bytelen != inlen) {
71 return CRYPT_INVALID_PACKET;
72 }
73
74 /* allocate ram */
75 tmp = XMALLOC(inlen);
76 if (tmp == NULL) {
77 return CRYPT_MEM;
78 }
79
80 /* rsa decode the packet */
81 x = inlen;
82 if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) {
83 XFREE(tmp);
84 return err;
85 }
86
87 if (padding == LTC_PKCS_1_OAEP) {
88 /* now OAEP decode the packet */
89 err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx,
90 out, outlen, stat);
91 } else {
92 /* now LTC_PKCS #1 v1.5 depad the packet */
93 err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat);
94 }
95
96 XFREE(tmp);
97 return err;
98 }
99
100 #endif /* LTC_MRSA */
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
+0
-102
libtom-src/pk/rsa/rsa_encrypt_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_encrypt_key.c
14 RSA LTC_PKCS #1 encryption, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 (LTC_PKCS #1 v2.0) OAEP pad then encrypt
21 @param in The plaintext
22 @param inlen The length of the plaintext (octets)
23 @param out [out] The ciphertext
24 @param outlen [in/out] The max size and resulting size of the ciphertext
25 @param lparam The system "lparam" for the encryption
26 @param lparamlen The length of lparam (octets)
27 @param prng An active PRNG
28 @param prng_idx The index of the desired prng
29 @param hash_idx The index of the desired hash
30 @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5)
31 @param key The RSA key to encrypt to
32 @return CRYPT_OK if successful
33 */
34 int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
35 unsigned char *out, unsigned long *outlen,
36 const unsigned char *lparam, unsigned long lparamlen,
37 prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key)
38 {
39 unsigned long modulus_bitlen, modulus_bytelen, x;
40 int err;
41
42 LTC_ARGCHK(in != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(key != NULL);
46
47 /* valid padding? */
48 if ((padding != LTC_PKCS_1_V1_5) &&
49 (padding != LTC_PKCS_1_OAEP)) {
50 return CRYPT_PK_INVALID_PADDING;
51 }
52
53 /* valid prng? */
54 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
55 return err;
56 }
57
58 if (padding == LTC_PKCS_1_OAEP) {
59 /* valid hash? */
60 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
61 return err;
62 }
63 }
64
65 /* get modulus len in bits */
66 modulus_bitlen = mp_count_bits( (key->N));
67
68 /* outlen must be at least the size of the modulus */
69 modulus_bytelen = mp_unsigned_bin_size( (key->N));
70 if (modulus_bytelen > *outlen) {
71 *outlen = modulus_bytelen;
72 return CRYPT_BUFFER_OVERFLOW;
73 }
74
75 if (padding == LTC_PKCS_1_OAEP) {
76 /* OAEP pad the key */
77 x = *outlen;
78 if ((err = pkcs_1_oaep_encode(in, inlen, lparam,
79 lparamlen, modulus_bitlen, prng, prng_idx, hash_idx,
80 out, &x)) != CRYPT_OK) {
81 return err;
82 }
83 } else {
84 /* LTC_PKCS #1 v1.5 pad the key */
85 x = *outlen;
86 if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_PKCS_1_EME,
87 modulus_bitlen, prng, prng_idx,
88 out, &x)) != CRYPT_OK) {
89 return err;
90 }
91 }
92
93 /* rsa exptmod the OAEP or LTC_PKCS #1 v1.5 pad */
94 return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key);
95 }
96
97 #endif /* LTC_MRSA */
98
99 /* $Source$ */
100 /* $Revision$ */
101 /* $Date$ */
+0
-89
libtom-src/pk/rsa/rsa_export.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_export.c
14 Export RSA LTC_PKCS keys, Tom St Denis
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 This will export either an RSAPublicKey or RSAPrivateKey [defined in LTC_PKCS #1 v2.1]
21 @param out [out] Destination of the packet
22 @param outlen [in/out] The max size and resulting size of the packet
23 @param type The type of exported key (PK_PRIVATE or PK_PUBLIC)
24 @param key The RSA key to export
25 @return CRYPT_OK if successful
26 */
27 int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
28 {
29 unsigned long zero=0;
30 int err;
31 LTC_ARGCHK(out != NULL);
32 LTC_ARGCHK(outlen != NULL);
33 LTC_ARGCHK(key != NULL);
34
35 /* type valid? */
36 if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) {
37 return CRYPT_PK_INVALID_TYPE;
38 }
39
40 if (type == PK_PRIVATE) {
41 /* private key */
42 /* output is
43 Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p
44 */
45 return der_encode_sequence_multi(out, outlen,
46 LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
47 LTC_ASN1_INTEGER, 1UL, key->N,
48 LTC_ASN1_INTEGER, 1UL, key->e,
49 LTC_ASN1_INTEGER, 1UL, key->d,
50 LTC_ASN1_INTEGER, 1UL, key->p,
51 LTC_ASN1_INTEGER, 1UL, key->q,
52 LTC_ASN1_INTEGER, 1UL, key->dP,
53 LTC_ASN1_INTEGER, 1UL, key->dQ,
54 LTC_ASN1_INTEGER, 1UL, key->qP,
55 LTC_ASN1_EOL, 0UL, NULL);
56 } else {
57 /* public key */
58 unsigned long tmplen = (mp_count_bits(key->N)/8)*2+8;
59 unsigned char* tmp = XMALLOC(tmplen);
60
61 if (tmp == NULL) {
62 return CRYPT_MEM;
63 }
64
65 err = der_encode_sequence_multi(tmp, &tmplen,
66 LTC_ASN1_INTEGER, 1UL, key->N,
67 LTC_ASN1_INTEGER, 1UL, key->e,
68 LTC_ASN1_EOL, 0UL, NULL);
69
70 if (err != CRYPT_OK) {
71 goto error;
72 }
73
74 err = der_encode_subject_public_key_info(out, outlen,
75 PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0);
76
77 error:
78 XFREE(tmp);
79 return err;
80
81 }
82 }
83
84 #endif /* LTC_MRSA */
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
+0
-161
libtom-src/pk/rsa/rsa_exptmod.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 *
10 * Added RSA blinding --nmav
11 */
12 #include "tomcrypt.h"
13
14 /**
15 @file rsa_exptmod.c
16 RSA LTC_PKCS exptmod, Tom St Denis
17 */
18
19 #ifdef LTC_MRSA
20
21 /**
22 Compute an RSA modular exponentiation
23 @param in The input data to send into RSA
24 @param inlen The length of the input (octets)
25 @param out [out] The destination
26 @param outlen [in/out] The max size and resulting size of the output
27 @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC
28 @param key The RSA key to use
29 @return CRYPT_OK if successful
30 */
31 int rsa_exptmod(const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long *outlen, int which,
33 rsa_key *key)
34 {
35 void *tmp, *tmpa, *tmpb;
36 #ifdef LTC_RSA_BLINDING
37 void *rnd = NULL, *rndi = NULL /* inverse of rnd */;
38 #endif
39 unsigned long x;
40 int err;
41
42 LTC_ARGCHK(in != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(key != NULL);
46
47 /* is the key of the right type for the operation? */
48 if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) {
49 return CRYPT_PK_NOT_PRIVATE;
50 }
51
52 /* must be a private or public operation */
53 if (which != PK_PRIVATE && which != PK_PUBLIC) {
54 return CRYPT_PK_INVALID_TYPE;
55 }
56
57 /* init and copy into tmp */
58 if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK)
59 { return err; }
60 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK)
61 { goto error; }
62
63
64 /* sanity check on the input */
65 if (mp_cmp(key->N, tmp) == LTC_MP_LT) {
66 err = CRYPT_PK_INVALID_SIZE;
67 goto error;
68 }
69
70 /* are we using the private exponent and is the key optimized? */
71 if (which == PK_PRIVATE) {
72 #ifdef LTC_RSA_BLINDING
73 if ((err = mp_init_multi(&rnd, &rndi, NULL)) != CRYPT_OK)
74 { goto error; }
75 /* do blinding */
76 err = mp_rand(rnd, mp_count_bits(key->N));
77 if (err != CRYPT_OK) {
78 goto error_blind;
79 }
80
81 /* rndi = 1/rnd mod N */
82 err = mp_invmod(rnd, key->N, rndi);
83 if (err != CRYPT_OK) {
84 goto error_blind;
85 }
86
87 /* rnd = rnd^e */
88 err = mp_exptmod( rnd, key->e, key->N, rnd);
89 if (err != CRYPT_OK) {
90 goto error_blind;
91 }
92
93 /* tmp = tmp*rnd mod N */
94 err = mp_mulmod( tmp, rnd, key->N, tmp);
95 if (err != CRYPT_OK) {
96 goto error_blind;
97 }
98 #endif /* LTC_RSA_BLINDING */
99
100 /* tmpa = tmp^dP mod p */
101 if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error_blind; }
102
103 /* tmpb = tmp^dQ mod q */
104 if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error_blind; }
105
106 /* tmp = (tmpa - tmpb) * qInv (mod p) */
107 if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error_blind; }
108 if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error_blind; }
109
110 /* tmp = tmpb + q * tmp */
111 if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error_blind; }
112 if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error_blind; }
113
114 #ifdef LTC_RSA_BLINDING
115 /* unblind */
116 err = mp_mulmod( tmp, rndi, key->N, tmp);
117 if (err != CRYPT_OK) {
118 goto error_blind;
119 }
120 #endif
121 } else {
122 /* exptmod it */
123 if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; }
124 }
125
126 /* read it back */
127 x = (unsigned long)mp_unsigned_bin_size(key->N);
128 if (x > *outlen) {
129 *outlen = x;
130 err = CRYPT_BUFFER_OVERFLOW;
131 goto error;
132 }
133
134 /* this should never happen ... */
135 if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) {
136 err = CRYPT_ERROR;
137 goto error;
138 }
139 *outlen = x;
140
141 /* convert it */
142 zeromem(out, x);
143 if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; }
144
145 /* clean up and return */
146 err = CRYPT_OK;
147 error_blind:
148 #ifdef LTC_RSA_BLINDING
149 mp_clear_multi(rnd, rndi, NULL);
150 #endif
151 error:
152 mp_clear_multi(tmp, tmpa, tmpb, NULL);
153 return err;
154 }
155
156 #endif
157
158 /* $Source$ */
159 /* $Revision$ */
160 /* $Date$ */
+0
-34
libtom-src/pk/rsa/rsa_free.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_free.c
14 Free an RSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 Free an RSA key from memory
21 @param key The RSA key to free
22 */
23 void rsa_free(rsa_key *key)
24 {
25 LTC_ARGCHKVD(key != NULL);
26 mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
27 }
28
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
+0
-130
libtom-src/pk/rsa/rsa_import.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_import.c
14 Import a LTC_PKCS RSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1]
21 @param in The packet to import from
22 @param inlen It's length (octets)
23 @param key [out] Destination for newly imported key
24 @return CRYPT_OK if successful, upon error allocated memory is freed
25 */
26 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
27 {
28 int err;
29 void *zero;
30 unsigned char *tmpbuf=NULL;
31 unsigned long tmpbuf_len;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(key != NULL);
35 LTC_ARGCHK(ltc_mp.name != NULL);
36
37 /* init key */
38 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,
39 &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* see if the OpenSSL DER format RSA public key will work */
44 tmpbuf_len = MAX_RSA_SIZE * 8;
45 tmpbuf = XCALLOC(1, tmpbuf_len);
46 if (tmpbuf == NULL) {
47 err = CRYPT_MEM;
48 goto LBL_ERR;
49 }
50
51 err = der_decode_subject_public_key_info(in, inlen,
52 PKA_RSA, tmpbuf, &tmpbuf_len,
53 LTC_ASN1_NULL, NULL, 0);
54
55 if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */
56
57 /* now it should be SEQUENCE { INTEGER, INTEGER } */
58 if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len,
59 LTC_ASN1_INTEGER, 1UL, key->N,
60 LTC_ASN1_INTEGER, 1UL, key->e,
61 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
62 goto LBL_ERR;
63 }
64 key->type = PK_PUBLIC;
65 err = CRYPT_OK;
66 goto LBL_FREE;
67 }
68
69 /* not SSL public key, try to match against LTC_PKCS #1 standards */
70 if ((err = der_decode_sequence_multi(in, inlen,
71 LTC_ASN1_INTEGER, 1UL, key->N,
72 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
73 goto LBL_ERR;
74 }
75
76 if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) {
77 if ((err = mp_init(&zero)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80 /* it's a private key */
81 if ((err = der_decode_sequence_multi(in, inlen,
82 LTC_ASN1_INTEGER, 1UL, zero,
83 LTC_ASN1_INTEGER, 1UL, key->N,
84 LTC_ASN1_INTEGER, 1UL, key->e,
85 LTC_ASN1_INTEGER, 1UL, key->d,
86 LTC_ASN1_INTEGER, 1UL, key->p,
87 LTC_ASN1_INTEGER, 1UL, key->q,
88 LTC_ASN1_INTEGER, 1UL, key->dP,
89 LTC_ASN1_INTEGER, 1UL, key->dQ,
90 LTC_ASN1_INTEGER, 1UL, key->qP,
91 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
92 mp_clear(zero);
93 goto LBL_ERR;
94 }
95 mp_clear(zero);
96 key->type = PK_PRIVATE;
97 } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) {
98 /* we don't support multi-prime RSA */
99 err = CRYPT_PK_INVALID_TYPE;
100 goto LBL_ERR;
101 } else {
102 /* it's a public key and we lack e */
103 if ((err = der_decode_sequence_multi(in, inlen,
104 LTC_ASN1_INTEGER, 1UL, key->N,
105 LTC_ASN1_INTEGER, 1UL, key->e,
106 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
107 goto LBL_ERR;
108 }
109 key->type = PK_PUBLIC;
110 }
111 err = CRYPT_OK;
112 goto LBL_FREE;
113
114 LBL_ERR:
115 mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
116
117 LBL_FREE:
118 if (tmpbuf != NULL)
119 XFREE(tmpbuf);
120
121 return err;
122 }
123
124 #endif /* LTC_MRSA */
125
126
127 /* $Source$ */
128 /* $Revision$ */
129 /* $Date$ */
+0
-112
libtom-src/pk/rsa/rsa_make_key.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_make_key.c
14 RSA key generation, Tom St Denis
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 Create an RSA key
21 @param prng An active PRNG state
22 @param wprng The index of the PRNG desired
23 @param size The size of the modulus (key size) desired (octets)
24 @param e The "e" value (public key). e==65537 is a good choice
25 @param key [out] Destination of a newly created private key pair
26 @return CRYPT_OK if successful, upon error all allocated ram is freed
27 */
28 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
29 {
30 void *p, *q, *tmp1, *tmp2, *tmp3;
31 int err;
32
33 LTC_ARGCHK(ltc_mp.name != NULL);
34 LTC_ARGCHK(key != NULL);
35
36 if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
37 return CRYPT_INVALID_KEYSIZE;
38 }
39
40 if ((e < 3) || ((e & 1) == 0)) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
45 return err;
46 }
47
48 if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) {
49 return err;
50 }
51
52 /* make primes p and q (optimization provided by Wayne Scott) */
53 if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto errkey; } /* tmp3 = e */
54
55 /* make prime "p" */
56 do {
57 if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; }
58 if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = p-1 */
59 if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(p-1, e) */
60 } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides p-1 */
61
62 /* make prime "q" */
63 do {
64 if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; }
65 if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */
66 if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(q-1, e) */
67 } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides q-1 */
68
69 /* tmp1 = lcm(p-1, q-1) */
70 if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */
71 /* tmp1 = q-1 (previous do/while loop) */
72 if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = lcm(p-1, q-1) */
73
74 /* make key */
75 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
76 goto errkey;
77 }
78
79 if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */
80 if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */
81 if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */
82
83 /* optimize for CRT now */
84 /* find d mod q-1 and d mod p-1 */
85 if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */
86 if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */
87 if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */
88 if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */
89 if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */
90
91 if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto errkey; }
92 if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto errkey; }
93
94 /* set key type (in this case it's CRT optimized) */
95 key->type = PK_PRIVATE;
96
97 /* return ok and free temps */
98 err = CRYPT_OK;
99 goto cleanup;
100 errkey:
101 mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
102 cleanup:
103 mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL);
104 return err;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
+0
-134
libtom-src/pk/rsa/rsa_sign_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_sign_hash.c
14 RSA LTC_PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 LTC_PKCS #1 pad then sign
21 @param in The hash to sign
22 @param inlen The length of the hash to sign (octets)
23 @param out [out] The signature
24 @param outlen [in/out] The max size and resulting size of the signature
25 @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5)
26 @param prng An active PRNG state
27 @param prng_idx The index of the PRNG desired
28 @param hash_idx The index of the hash desired
29 @param saltlen The length of the salt desired (octets)
30 @param key The private RSA key to use
31 @return CRYPT_OK if successful
32 */
33 int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
34 unsigned char *out, unsigned long *outlen,
35 int padding,
36 prng_state *prng, int prng_idx,
37 int hash_idx, unsigned long saltlen,
38 rsa_key *key)
39 {
40 unsigned long modulus_bitlen, modulus_bytelen, x, y;
41 int err;
42
43 LTC_ARGCHK(in != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46 LTC_ARGCHK(key != NULL);
47
48 /* valid padding? */
49 if ((padding != LTC_PKCS_1_V1_5) && (padding != LTC_PKCS_1_PSS)) {
50 return CRYPT_PK_INVALID_PADDING;
51 }
52
53 if (padding == LTC_PKCS_1_PSS) {
54 /* valid prng and hash ? */
55 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
56 return err;
57 }
58 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
59 return err;
60 }
61 }
62
63 /* get modulus len in bits */
64 modulus_bitlen = mp_count_bits((key->N));
65
66 /* outlen must be at least the size of the modulus */
67 modulus_bytelen = mp_unsigned_bin_size((key->N));
68 if (modulus_bytelen > *outlen) {
69 *outlen = modulus_bytelen;
70 return CRYPT_BUFFER_OVERFLOW;
71 }
72
73 if (padding == LTC_PKCS_1_PSS) {
74 /* PSS pad the key */
75 x = *outlen;
76 if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx,
77 hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) {
78 return err;
79 }
80 } else {
81 /* LTC_PKCS #1 v1.5 pad the hash */
82 unsigned char *tmpin;
83 ltc_asn1_list digestinfo[2], siginfo[2];
84
85 /* not all hashes have OIDs... so sad */
86 if (hash_descriptor[hash_idx].OIDlen == 0) {
87 return CRYPT_INVALID_ARG;
88 }
89
90 /* construct the SEQUENCE
91 SEQUENCE {
92 SEQUENCE {hashoid OID
93 blah NULL
94 }
95 hash OCTET STRING
96 }
97 */
98 LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen);
99 LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
100 LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
101 LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen);
102
103 /* allocate memory for the encoding */
104 y = mp_unsigned_bin_size(key->N);
105 tmpin = XMALLOC(y);
106 if (tmpin == NULL) {
107 return CRYPT_MEM;
108 }
109
110 if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) {
111 XFREE(tmpin);
112 return err;
113 }
114
115 x = *outlen;
116 if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_PKCS_1_EMSA,
117 modulus_bitlen, NULL, 0,
118 out, &x)) != CRYPT_OK) {
119 XFREE(tmpin);
120 return err;
121 }
122 XFREE(tmpin);
123 }
124
125 /* RSA encode it */
126 return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key);
127 }
128
129 #endif /* LTC_MRSA */
130
131 /* $Source$ */
132 /* $Revision$ */
133 /* $Date$ */
+0
-167
libtom-src/pk/rsa/rsa_verify_hash.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_verify_hash.c
14 RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 LTC_PKCS #1 de-sign then v1.5 or PSS depad
21 @param sig The signature data
22 @param siglen The length of the signature data (octets)
23 @param hash The hash of the message that was signed
24 @param hashlen The length of the hash of the message that was signed (octets)
25 @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5)
26 @param hash_idx The index of the desired hash
27 @param saltlen The length of the salt used during signature
28 @param stat [out] The result of the signature comparison, 1==valid, 0==invalid
29 @param key The public RSA key corresponding to the key that performed the signature
30 @return CRYPT_OK on success (even if the signature is invalid)
31 */
32 int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
33 const unsigned char *hash, unsigned long hashlen,
34 int padding,
35 int hash_idx, unsigned long saltlen,
36 int *stat, rsa_key *key)
37 {
38 unsigned long modulus_bitlen, modulus_bytelen, x;
39 int err;
40 unsigned char *tmpbuf;
41
42 LTC_ARGCHK(hash != NULL);
43 LTC_ARGCHK(sig != NULL);
44 LTC_ARGCHK(stat != NULL);
45 LTC_ARGCHK(key != NULL);
46
47 /* default to invalid */
48 *stat = 0;
49
50 /* valid padding? */
51
52 if ((padding != LTC_PKCS_1_V1_5) &&
53 (padding != LTC_PKCS_1_PSS)) {
54 return CRYPT_PK_INVALID_PADDING;
55 }
56
57 if (padding == LTC_PKCS_1_PSS) {
58 /* valid hash ? */
59 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
60 return err;
61 }
62 }
63
64 /* get modulus len in bits */
65 modulus_bitlen = mp_count_bits( (key->N));
66
67 /* outlen must be at least the size of the modulus */
68 modulus_bytelen = mp_unsigned_bin_size( (key->N));
69 if (modulus_bytelen != siglen) {
70 return CRYPT_INVALID_PACKET;
71 }
72
73 /* allocate temp buffer for decoded sig */
74 tmpbuf = XMALLOC(siglen);
75 if (tmpbuf == NULL) {
76 return CRYPT_MEM;
77 }
78
79 /* RSA decode it */
80 x = siglen;
81 if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
82 XFREE(tmpbuf);
83 return err;
84 }
85
86 /* make sure the output is the right size */
87 if (x != siglen) {
88 XFREE(tmpbuf);
89 return CRYPT_INVALID_PACKET;
90 }
91
92 if (padding == LTC_PKCS_1_PSS) {
93 /* PSS decode and verify it */
94 err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
95 } else {
96 /* LTC_PKCS #1 v1.5 decode it */
97 unsigned char *out;
98 unsigned long outlen, loid[16];
99 int decoded;
100 ltc_asn1_list digestinfo[2], siginfo[2];
101
102 /* not all hashes have OIDs... so sad */
103 if (hash_descriptor[hash_idx].OIDlen == 0) {
104 err = CRYPT_INVALID_ARG;
105 goto bail_2;
106 }
107
108 /* allocate temp buffer for decoded hash */
109 outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3;
110 out = XMALLOC(outlen);
111 if (out == NULL) {
112 err = CRYPT_MEM;
113 goto bail_2;
114 }
115
116 if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) {
117 XFREE(out);
118 goto bail_2;
119 }
120
121 /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */
122 /* construct the SEQUENCE
123 SEQUENCE {
124 SEQUENCE {hashoid OID
125 blah NULL
126 }
127 hash OCTET STRING
128 }
129 */
130 LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0]));
131 LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
132 LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
133 LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
134
135 if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
136 XFREE(out);
137 goto bail_2;
138 }
139
140 /* test OID */
141 if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) &&
142 (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) &&
143 (siginfo[1].size == hashlen) &&
144 (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) {
145 *stat = 1;
146 }
147
148 #ifdef LTC_CLEAN_STACK
149 zeromem(out, outlen);
150 #endif
151 XFREE(out);
152 }
153
154 bail_2:
155 #ifdef LTC_CLEAN_STACK
156 zeromem(tmpbuf, siglen);
157 #endif
158 XFREE(tmpbuf);
159 return err;
160 }
161
162 #endif /* LTC_MRSA */
163
164 /* $Source$ */
165 /* $Revision$ */
166 /* $Date$ */
+0
-430
libtom-src/prngs/fortuna.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file fortuna.c
14 Fortuna PRNG, Tom St Denis
15 */
16
17 /* Implementation of Fortuna by Tom St Denis
18
19 We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources"
20 in the AddEntropy function are fixed to 0. Second since no reliable timer is provided
21 we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */
22
23 #ifdef LTC_FORTUNA
24
25 /* requries LTC_SHA256 and AES */
26 #if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256))
27 #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES)
28 #endif
29
30 #ifndef LTC_FORTUNA_POOLS
31 #warning LTC_FORTUNA_POOLS was not previously defined (old headers?)
32 #define LTC_FORTUNA_POOLS 32
33 #endif
34
35 #if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32
36 #error LTC_FORTUNA_POOLS must be in [4..32]
37 #endif
38
39 const struct ltc_prng_descriptor fortuna_desc = {
40 "fortuna", 1024,
41 &fortuna_start,
42 &fortuna_add_entropy,
43 &fortuna_ready,
44 &fortuna_read,
45 &fortuna_done,
46 &fortuna_export,
47 &fortuna_import,
48 &fortuna_test
49 };
50
51 /* update the IV */
52 static void fortuna_update_iv(prng_state *prng)
53 {
54 int x;
55 unsigned char *IV;
56 /* update IV */
57 IV = prng->fortuna.IV;
58 for (x = 0; x < 16; x++) {
59 IV[x] = (IV[x] + 1) & 255;
60 if (IV[x] != 0) break;
61 }
62 }
63
64 /* reseed the PRNG */
65 static int fortuna_reseed(prng_state *prng)
66 {
67 unsigned char tmp[MAXBLOCKSIZE];
68 hash_state md;
69 int err, x;
70
71 ++prng->fortuna.reset_cnt;
72
73 /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */
74 sha256_init(&md);
75 if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) {
76 sha256_done(&md, tmp);
77 return err;
78 }
79
80 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
81 if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) {
82 /* terminate this hash */
83 if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) {
84 sha256_done(&md, tmp);
85 return err;
86 }
87 /* add it to the string */
88 if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) {
89 sha256_done(&md, tmp);
90 return err;
91 }
92 /* reset this pool */
93 if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) {
94 sha256_done(&md, tmp);
95 return err;
96 }
97 } else {
98 break;
99 }
100 }
101
102 /* finish key */
103 if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) {
104 return err;
105 }
106 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) {
107 return err;
108 }
109 fortuna_update_iv(prng);
110
111 /* reset pool len */
112 prng->fortuna.pool0_len = 0;
113 prng->fortuna.wd = 0;
114
115
116 #ifdef LTC_CLEAN_STACK
117 zeromem(&md, sizeof(md));
118 zeromem(tmp, sizeof(tmp));
119 #endif
120
121 return CRYPT_OK;
122 }
123
124 /**
125 Start the PRNG
126 @param prng [out] The PRNG state to initialize
127 @return CRYPT_OK if successful
128 */
129 int fortuna_start(prng_state *prng)
130 {
131 int err, x, y;
132 unsigned char tmp[MAXBLOCKSIZE];
133
134 LTC_ARGCHK(prng != NULL);
135
136 /* initialize the pools */
137 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
138 if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) {
139 for (y = 0; y < x; y++) {
140 sha256_done(&prng->fortuna.pool[y], tmp);
141 }
142 return err;
143 }
144 }
145 prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.wd = 0;
146 prng->fortuna.reset_cnt = 0;
147
148 /* reset bufs */
149 zeromem(prng->fortuna.K, 32);
150 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) {
151 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
152 sha256_done(&prng->fortuna.pool[x], tmp);
153 }
154 return err;
155 }
156 zeromem(prng->fortuna.IV, 16);
157
158 LTC_MUTEX_INIT(&prng->fortuna.prng_lock)
159
160 return CRYPT_OK;
161 }
162
163 /**
164 Add entropy to the PRNG state
165 @param in The data to add
166 @param inlen Length of the data to add
167 @param prng PRNG state to update
168 @return CRYPT_OK if successful
169 */
170 int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
171 {
172 unsigned char tmp[2];
173 int err;
174
175 LTC_ARGCHK(in != NULL);
176 LTC_ARGCHK(prng != NULL);
177
178 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
179
180 /* ensure inlen <= 32 */
181 if (inlen > 32) {
182 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
183 return CRYPT_INVALID_ARG;
184 }
185
186 /* add s || length(in) || in to pool[pool_idx] */
187 tmp[0] = 0;
188 tmp[1] = (unsigned char)inlen;
189 if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) {
190 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
191 return err;
192 }
193 if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], in, inlen)) != CRYPT_OK) {
194 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
195 return err;
196 }
197 if (prng->fortuna.pool_idx == 0) {
198 prng->fortuna.pool0_len += inlen;
199 }
200 if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) {
201 prng->fortuna.pool_idx = 0;
202 }
203
204 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
205 return CRYPT_OK;
206 }
207
208 /**
209 Make the PRNG ready to read from
210 @param prng The PRNG to make active
211 @return CRYPT_OK if successful
212 */
213 int fortuna_ready(prng_state *prng)
214 {
215 return fortuna_reseed(prng);
216 }
217
218 /**
219 Read from the PRNG
220 @param out Destination
221 @param outlen Length of output
222 @param prng The active PRNG to read from
223 @return Number of octets read
224 */
225 unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng)
226 {
227 unsigned char tmp[16];
228 unsigned long tlen;
229
230 LTC_ARGCHK(out != NULL);
231 LTC_ARGCHK(prng != NULL);
232
233 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
234
235 /* do we have to reseed? */
236 if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) {
237 if (fortuna_reseed(prng) != CRYPT_OK) {
238 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
239 return 0;
240 }
241 }
242
243 /* now generate the blocks required */
244 tlen = outlen;
245
246 /* handle whole blocks without the extra XMEMCPY */
247 while (outlen >= 16) {
248 /* encrypt the IV and store it */
249 rijndael_ecb_encrypt(prng->fortuna.IV, out, &prng->fortuna.skey);
250 out += 16;
251 outlen -= 16;
252 fortuna_update_iv(prng);
253 }
254
255 /* left over bytes? */
256 if (outlen > 0) {
257 rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey);
258 XMEMCPY(out, tmp, outlen);
259 fortuna_update_iv(prng);
260 }
261
262 /* generate new key */
263 rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey);
264 fortuna_update_iv(prng);
265
266 rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey);
267 fortuna_update_iv(prng);
268
269 if (rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey) != CRYPT_OK) {
270 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
271 return 0;
272 }
273
274 #ifdef LTC_CLEAN_STACK
275 zeromem(tmp, sizeof(tmp));
276 #endif
277 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
278 return tlen;
279 }
280
281 /**
282 Terminate the PRNG
283 @param prng The PRNG to terminate
284 @return CRYPT_OK if successful
285 */
286 int fortuna_done(prng_state *prng)
287 {
288 int err, x;
289 unsigned char tmp[32];
290
291 LTC_ARGCHK(prng != NULL);
292 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
293
294 /* terminate all the hashes */
295 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
296 if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) {
297 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
298 return err;
299 }
300 }
301 /* call cipher done when we invent one ;-) */
302
303 #ifdef LTC_CLEAN_STACK
304 zeromem(tmp, sizeof(tmp));
305 #endif
306
307 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
308 return CRYPT_OK;
309 }
310
311 /**
312 Export the PRNG state
313 @param out [out] Destination
314 @param outlen [in/out] Max size and resulting size of the state
315 @param prng The PRNG to export
316 @return CRYPT_OK if successful
317 */
318 int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
319 {
320 int x, err;
321 hash_state *md;
322
323 LTC_ARGCHK(out != NULL);
324 LTC_ARGCHK(outlen != NULL);
325 LTC_ARGCHK(prng != NULL);
326
327 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
328
329 /* we'll write bytes for s&g's */
330 if (*outlen < 32*LTC_FORTUNA_POOLS) {
331 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
332 *outlen = 32*LTC_FORTUNA_POOLS;
333 return CRYPT_BUFFER_OVERFLOW;
334 }
335
336 md = XMALLOC(sizeof(hash_state));
337 if (md == NULL) {
338 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
339 return CRYPT_MEM;
340 }
341
342 /* to emit the state we copy each pool, terminate it then hash it again so
343 * an attacker who sees the state can't determine the current state of the PRNG
344 */
345 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
346 /* copy the PRNG */
347 XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md));
348
349 /* terminate it */
350 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) {
351 goto LBL_ERR;
352 }
353
354 /* now hash it */
355 if ((err = sha256_init(md)) != CRYPT_OK) {
356 goto LBL_ERR;
357 }
358 if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) {
359 goto LBL_ERR;
360 }
361 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) {
362 goto LBL_ERR;
363 }
364 }
365 *outlen = 32*LTC_FORTUNA_POOLS;
366 err = CRYPT_OK;
367
368 LBL_ERR:
369 #ifdef LTC_CLEAN_STACK
370 zeromem(md, sizeof(*md));
371 #endif
372 XFREE(md);
373 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
374 return err;
375 }
376
377 /**
378 Import a PRNG state
379 @param in The PRNG state
380 @param inlen Size of the state
381 @param prng The PRNG to import
382 @return CRYPT_OK if successful
383 */
384 int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
385 {
386 int err, x;
387
388 LTC_ARGCHK(in != NULL);
389 LTC_ARGCHK(prng != NULL);
390
391 if (inlen != 32*LTC_FORTUNA_POOLS) {
392 return CRYPT_INVALID_ARG;
393 }
394
395 if ((err = fortuna_start(prng)) != CRYPT_OK) {
396 return err;
397 }
398 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
399 if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) {
400 return err;
401 }
402 }
403 return err;
404 }
405
406 /**
407 PRNG self-test
408 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
409 */
410 int fortuna_test(void)
411 {
412 #ifndef LTC_TEST
413 return CRYPT_NOP;
414 #else
415 int err;
416
417 if ((err = sha256_test()) != CRYPT_OK) {
418 return err;
419 }
420 return rijndael_test();
421 #endif
422 }
423
424 #endif
425
426
427 /* $Source$ */
428 /* $Revision$ */
429 /* $Date$ */
+0
-269
libtom-src/prngs/rc4.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rc4.c
14 LTC_RC4 PRNG, Tom St Denis
15 */
16
17 #ifdef LTC_RC4
18
19 const struct ltc_prng_descriptor rc4_desc =
20 {
21 "rc4", 32,
22 &rc4_start,
23 &rc4_add_entropy,
24 &rc4_ready,
25 &rc4_read,
26 &rc4_done,
27 &rc4_export,
28 &rc4_import,
29 &rc4_test
30 };
31
32 /**
33 Start the PRNG
34 @param prng [out] The PRNG state to initialize
35 @return CRYPT_OK if successful
36 */
37 int rc4_start(prng_state *prng)
38 {
39 LTC_ARGCHK(prng != NULL);
40
41 /* set keysize to zero */
42 prng->rc4.x = 0;
43
44 return CRYPT_OK;
45 }
46
47 /**
48 Add entropy to the PRNG state
49 @param in The data to add
50 @param inlen Length of the data to add
51 @param prng PRNG state to update
52 @return CRYPT_OK if successful
53 */
54 int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
55 {
56 LTC_ARGCHK(in != NULL);
57 LTC_ARGCHK(prng != NULL);
58
59 /* trim as required */
60 if (prng->rc4.x + inlen > 256) {
61 if (prng->rc4.x == 256) {
62 /* I can't possibly accept another byte, ok maybe a mint wafer... */
63 return CRYPT_OK;
64 } else {
65 /* only accept part of it */
66 inlen = 256 - prng->rc4.x;
67 }
68 }
69
70 while (inlen--) {
71 prng->rc4.buf[prng->rc4.x++] = *in++;
72 }
73
74 return CRYPT_OK;
75
76 }
77
78 /**
79 Make the PRNG ready to read from
80 @param prng The PRNG to make active
81 @return CRYPT_OK if successful
82 */
83 int rc4_ready(prng_state *prng)
84 {
85 unsigned char key[256], tmp, *s;
86 int keylen, x, y, j;
87
88 LTC_ARGCHK(prng != NULL);
89
90 /* extract the key */
91 s = prng->rc4.buf;
92 XMEMCPY(key, s, 256);
93 keylen = prng->rc4.x;
94
95 /* make LTC_RC4 perm and shuffle */
96 for (x = 0; x < 256; x++) {
97 s[x] = x;
98 }
99
100 for (j = x = y = 0; x < 256; x++) {
101 y = (y + prng->rc4.buf[x] + key[j++]) & 255;
102 if (j == keylen) {
103 j = 0;
104 }
105 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
106 }
107 prng->rc4.x = 0;
108 prng->rc4.y = 0;
109
110 #ifdef LTC_CLEAN_STACK
111 zeromem(key, sizeof(key));
112 #endif
113
114 return CRYPT_OK;
115 }
116
117 /**
118 Read from the PRNG
119 @param out Destination
120 @param outlen Length of output
121 @param prng The active PRNG to read from
122 @return Number of octets read
123 */
124 unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng)
125 {
126 unsigned char x, y, *s, tmp;
127 unsigned long n;
128
129 LTC_ARGCHK(out != NULL);
130 LTC_ARGCHK(prng != NULL);
131
132 #ifdef LTC_VALGRIND
133 zeromem(out, outlen);
134 #endif
135
136 n = outlen;
137 x = prng->rc4.x;
138 y = prng->rc4.y;
139 s = prng->rc4.buf;
140 while (outlen--) {
141 x = (x + 1) & 255;
142 y = (y + s[x]) & 255;
143 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
144 tmp = (s[x] + s[y]) & 255;
145 *out++ ^= s[tmp];
146 }
147 prng->rc4.x = x;
148 prng->rc4.y = y;
149 return n;
150 }
151
152 /**
153 Terminate the PRNG
154 @param prng The PRNG to terminate
155 @return CRYPT_OK if successful
156 */
157 int rc4_done(prng_state *prng)
158 {
159 LTC_ARGCHK(prng != NULL);
160 return CRYPT_OK;
161 }
162
163 /**
164 Export the PRNG state
165 @param out [out] Destination
166 @param outlen [in/out] Max size and resulting size of the state
167 @param prng The PRNG to export
168 @return CRYPT_OK if successful
169 */
170 int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
171 {
172 LTC_ARGCHK(outlen != NULL);
173 LTC_ARGCHK(out != NULL);
174 LTC_ARGCHK(prng != NULL);
175
176 if (*outlen < 32) {
177 *outlen = 32;
178 return CRYPT_BUFFER_OVERFLOW;
179 }
180
181 if (rc4_read(out, 32, prng) != 32) {
182 return CRYPT_ERROR_READPRNG;
183 }
184 *outlen = 32;
185
186 return CRYPT_OK;
187 }
188
189 /**
190 Import a PRNG state
191 @param in The PRNG state
192 @param inlen Size of the state
193 @param prng The PRNG to import
194 @return CRYPT_OK if successful
195 */
196 int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
197 {
198 int err;
199 LTC_ARGCHK(in != NULL);
200 LTC_ARGCHK(prng != NULL);
201
202 if (inlen != 32) {
203 return CRYPT_INVALID_ARG;
204 }
205
206 if ((err = rc4_start(prng)) != CRYPT_OK) {
207 return err;
208 }
209 return rc4_add_entropy(in, 32, prng);
210 }
211
212 /**
213 PRNG self-test
214 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
215 */
216 int rc4_test(void)
217 {
218 #if !defined(LTC_TEST) || defined(LTC_VALGRIND)
219 return CRYPT_NOP;
220 #else
221 static const struct {
222 unsigned char key[8], pt[8], ct[8];
223 } tests[] = {
224 {
225 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
226 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
227 { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 }
228 }
229 };
230 prng_state prng;
231 unsigned char dst[8];
232 int err, x;
233
234 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
235 if ((err = rc4_start(&prng)) != CRYPT_OK) {
236 return err;
237 }
238 if ((err = rc4_add_entropy(tests[x].key, 8, &prng)) != CRYPT_OK) {
239 return err;
240 }
241 if ((err = rc4_ready(&prng)) != CRYPT_OK) {
242 return err;
243 }
244 XMEMCPY(dst, tests[x].pt, 8);
245 if (rc4_read(dst, 8, &prng) != 8) {
246 return CRYPT_ERROR_READPRNG;
247 }
248 rc4_done(&prng);
249 if (XMEMCMP(dst, tests[x].ct, 8)) {
250 #if 0
251 int y;
252 printf("\n\nLTC_RC4 failed, I got:\n");
253 for (y = 0; y < 8; y++) printf("%02x ", dst[y]);
254 printf("\n");
255 #endif
256 return CRYPT_FAIL_TESTVECTOR;
257 }
258 }
259 return CRYPT_OK;
260 #endif
261 }
262
263 #endif
264
265
266 /* $Source$ */
267 /* $Revision$ */
268 /* $Date$ */
+0
-152
libtom-src/prngs/rng_get_bytes.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rng_get_bytes.c
14 portable way to get secure random bits to feed a PRNG (Tom St Denis)
15 */
16
17 #ifdef LTC_DEVRANDOM
18 /* on *NIX read /dev/random */
19 static unsigned long rng_nix(unsigned char *buf, unsigned long len,
20 void (*callback)(void))
21 {
22 #ifdef LTC_NO_FILE
23 return 0;
24 #else
25 FILE *f;
26 unsigned long x;
27 #ifdef TRY_URANDOM_FIRST
28 f = fopen("/dev/urandom", "rb");
29 if (f == NULL)
30 #endif /* TRY_URANDOM_FIRST */
31 f = fopen("/dev/random", "rb");
32
33 if (f == NULL) {
34 return 0;
35 }
36
37 /* disable buffering */
38 if (setvbuf(f, NULL, _IONBF, 0) != 0) {
39 fclose(f);
40 return 0;
41 }
42
43 x = (unsigned long)fread(buf, 1, (size_t)len, f);
44 fclose(f);
45 return x;
46 #endif /* LTC_NO_FILE */
47 }
48
49 #endif /* LTC_DEVRANDOM */
50
51 /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
52 #if defined(CLOCKS_PER_SEC) && !defined(WINCE)
53
54 #define ANSI_RNG
55
56 static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
57 void (*callback)(void))
58 {
59 clock_t t1;
60 int l, acc, bits, a, b;
61
62 if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
63 return 0;
64 }
65
66 l = len;
67 bits = 8;
68 acc = a = b = 0;
69 while (len--) {
70 if (callback != NULL) callback();
71 while (bits--) {
72 do {
73 t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
74 t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
75 } while (a == b);
76 acc = (acc << 1) | a;
77 }
78 *buf++ = acc;
79 acc = 0;
80 bits = 8;
81 }
82 acc = bits = a = b = 0;
83 return l;
84 }
85
86 #endif
87
88 /* Try the Microsoft CSP */
89 #if defined(WIN32) || defined(WINCE)
90 #ifndef _WIN32_WINNT
91 #define _WIN32_WINNT 0x0400
92 #endif
93 #ifdef WINCE
94 #define UNDER_CE
95 #define ARM
96 #endif
97
98 #define WIN32_LEAN_AND_MEAN
99 #include <windows.h>
100 #include <wincrypt.h>
101
102 static unsigned long rng_win32(unsigned char *buf, unsigned long len,
103 void (*callback)(void))
104 {
105 HCRYPTPROV hProv = 0;
106 if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
107 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
108 !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
109 CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
110 return 0;
111
112 if (CryptGenRandom(hProv, len, buf) == TRUE) {
113 CryptReleaseContext(hProv, 0);
114 return len;
115 } else {
116 CryptReleaseContext(hProv, 0);
117 return 0;
118 }
119 }
120
121 #endif /* WIN32 */
122
123 /**
124 Read the system RNG
125 @param out Destination
126 @param outlen Length desired (octets)
127 @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL
128 @return Number of octets read
129 */
130 unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen,
131 void (*callback)(void))
132 {
133 unsigned long x;
134
135 LTC_ARGCHK(out != NULL);
136
137 #if defined(LTC_DEVRANDOM)
138 x = rng_nix(out, outlen, callback); if (x != 0) { return x; }
139 #endif
140 #ifdef WIN32
141 x = rng_win32(out, outlen, callback); if (x != 0) { return x; }
142 #endif
143 #ifdef ANSI_RNG
144 x = rng_ansic(out, outlen, callback); if (x != 0) { return x; }
145 #endif
146 return 0;
147 }
148
149 /* $Source$ */
150 /* $Revision$ */
151 /* $Date$ */
+0
-69
libtom-src/prngs/rng_make_prng.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rng_make_prng.c
14 portable way to get secure random bits to feed a PRNG (Tom St Denis)
15 */
16
17 /**
18 Create a PRNG from a RNG
19 @param bits Number of bits of entropy desired (64 ... 1024)
20 @param wprng Index of which PRNG to setup
21 @param prng [out] PRNG state to initialize
22 @param callback A pointer to a void function for when the RNG is slow, this can be NULL
23 @return CRYPT_OK if successful
24 */
25 int rng_make_prng(int bits, int wprng, prng_state *prng,
26 void (*callback)(void))
27 {
28 unsigned char buf[256];
29 int err;
30
31 LTC_ARGCHK(prng != NULL);
32
33 /* check parameter */
34 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
35 return err;
36 }
37
38 if (bits < 64 || bits > 1024) {
39 return CRYPT_INVALID_PRNGSIZE;
40 }
41
42 if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) {
43 return err;
44 }
45
46 bits = ((bits/8)+((bits&7)!=0?1:0)) * 2;
47 if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) {
48 return CRYPT_ERROR_READPRNG;
49 }
50
51 if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) {
52 return err;
53 }
54
55 if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) {
56 return err;
57 }
58
59 #ifdef LTC_CLEAN_STACK
60 zeromem(buf, sizeof(buf));
61 #endif
62 return CRYPT_OK;
63 }
64
65
66 /* $Source$ */
67 /* $Revision$ */
68 /* $Date$ */
+0
-500
libtom-src/prngs/sober128.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file sober128.c
14 Implementation of SOBER-128 by Tom St Denis.
15 Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
16 */
17
18 #ifdef LTC_SOBER128
19
20 #include "sober128tab.c.inc"
21
22 const struct ltc_prng_descriptor sober128_desc =
23 {
24 "sober128", 64,
25 &sober128_start,
26 &sober128_add_entropy,
27 &sober128_ready,
28 &sober128_read,
29 &sober128_done,
30 &sober128_export,
31 &sober128_import,
32 &sober128_test
33 };
34
35 /* don't change these... */
36 #define N 17
37 #define FOLD N /* how many iterations of folding to do */
38 #define INITKONST 0x6996c53a /* value of KONST to use during key loading */
39 #define KEYP 15 /* where to insert key words */
40 #define FOLDP 4 /* where to insert non-linear feedback */
41
42 #define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF))
43
44 static ulong32 BYTE2WORD(unsigned char *b)
45 {
46 ulong32 t;
47 LOAD32L(t, b);
48 return t;
49 }
50
51 #define WORD2BYTE(w, b) STORE32L(b, w)
52
53 static void XORWORD(ulong32 w, unsigned char *b)
54 {
55 ulong32 t;
56 LOAD32L(t, b);
57 t ^= w;
58 STORE32L(t, b);
59 }
60
61 /* give correct offset for the current position of the register,
62 * where logically R[0] is at position "zero".
63 */
64 #define OFF(zero, i) (((zero)+(i)) % N)
65
66 /* step the LFSR */
67 /* After stepping, "zero" moves right one place */
68 #define STEP(R,z) \
69 R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
70
71 static void cycle(ulong32 *R)
72 {
73 ulong32 t;
74 int i;
75
76 STEP(R,0);
77 t = R[0];
78 for (i = 1; i < N; ++i) {
79 R[i-1] = R[i];
80 }
81 R[N-1] = t;
82 }
83
84 /* Return a non-linear function of some parts of the register.
85 */
86 #define NLFUNC(c,z) \
87 { \
88 t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \
89 t ^= Sbox[(t >> 24) & 0xFF]; \
90 t = RORc(t, 8); \
91 t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \
92 t ^= Sbox[(t >> 24) & 0xFF]; \
93 t = t + c->R[OFF(z,13)]; \
94 }
95
96 static ulong32 nltap(struct sober128_prng *c)
97 {
98 ulong32 t;
99 NLFUNC(c, 0);
100 return t;
101 }
102
103 /**
104 Start the PRNG
105 @param prng [out] The PRNG state to initialize
106 @return CRYPT_OK if successful
107 */
108 int sober128_start(prng_state *prng)
109 {
110 int i;
111 struct sober128_prng *c;
112
113 LTC_ARGCHK(prng != NULL);
114
115 c = &(prng->sober128);
116
117 /* Register initialised to Fibonacci numbers */
118 c->R[0] = 1;
119 c->R[1] = 1;
120 for (i = 2; i < N; ++i) {
121 c->R[i] = c->R[i-1] + c->R[i-2];
122 }
123 c->konst = INITKONST;
124
125 /* next add_entropy will be the key */
126 c->flag = 1;
127 c->set = 0;
128
129 return CRYPT_OK;
130 }
131
132 /* Save the current register state
133 */
134 static void s128_savestate(struct sober128_prng *c)
135 {
136 int i;
137 for (i = 0; i < N; ++i) {
138 c->initR[i] = c->R[i];
139 }
140 }
141
142 /* initialise to previously saved register state
143 */
144 static void s128_reloadstate(struct sober128_prng *c)
145 {
146 int i;
147
148 for (i = 0; i < N; ++i) {
149 c->R[i] = c->initR[i];
150 }
151 }
152
153 /* Initialise "konst"
154 */
155 static void s128_genkonst(struct sober128_prng *c)
156 {
157 ulong32 newkonst;
158
159 do {
160 cycle(c->R);
161 newkonst = nltap(c);
162 } while ((newkonst & 0xFF000000) == 0);
163 c->konst = newkonst;
164 }
165
166 /* Load key material into the register
167 */
168 #define ADDKEY(k) \
169 c->R[KEYP] += (k);
170
171 #define XORNL(nl) \
172 c->R[FOLDP] ^= (nl);
173
174 /* nonlinear diffusion of register for key */
175 #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t;
176 static void s128_diffuse(struct sober128_prng *c)
177 {
178 ulong32 t;
179 /* relies on FOLD == N == 17! */
180 DROUND(0);
181 DROUND(1);
182 DROUND(2);
183 DROUND(3);
184 DROUND(4);
185 DROUND(5);
186 DROUND(6);
187 DROUND(7);
188 DROUND(8);
189 DROUND(9);
190 DROUND(10);
191 DROUND(11);
192 DROUND(12);
193 DROUND(13);
194 DROUND(14);
195 DROUND(15);
196 DROUND(16);
197 }
198
199 /**
200 Add entropy to the PRNG state
201 @param in The data to add
202 @param inlen Length of the data to add
203 @param prng PRNG state to update
204 @return CRYPT_OK if successful
205 */
206 int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
207 {
208 struct sober128_prng *c;
209 ulong32 i, k;
210
211 LTC_ARGCHK(in != NULL);
212 LTC_ARGCHK(prng != NULL);
213 c = &(prng->sober128);
214
215 if (c->flag == 1) {
216 /* this is the first call to the add_entropy so this input is the key */
217 /* inlen must be multiple of 4 bytes */
218 if ((inlen & 3) != 0) {
219 return CRYPT_INVALID_KEYSIZE;
220 }
221
222 for (i = 0; i < inlen; i += 4) {
223 k = BYTE2WORD((unsigned char *)&in[i]);
224 ADDKEY(k);
225 cycle(c->R);
226 XORNL(nltap(c));
227 }
228
229 /* also fold in the length of the key */
230 ADDKEY(inlen);
231
232 /* now diffuse */
233 s128_diffuse(c);
234
235 s128_genkonst(c);
236 s128_savestate(c);
237 c->nbuf = 0;
238 c->flag = 0;
239 c->set = 1;
240 } else {
241 /* ok we are adding an IV then... */
242 s128_reloadstate(c);
243
244 /* inlen must be multiple of 4 bytes */
245 if ((inlen & 3) != 0) {
246 return CRYPT_INVALID_KEYSIZE;
247 }
248
249 for (i = 0; i < inlen; i += 4) {
250 k = BYTE2WORD((unsigned char *)&in[i]);
251 ADDKEY(k);
252 cycle(c->R);
253 XORNL(nltap(c));
254 }
255
256 /* also fold in the length of the key */
257 ADDKEY(inlen);
258
259 /* now diffuse */
260 s128_diffuse(c);
261 c->nbuf = 0;
262 }
263
264 return CRYPT_OK;
265 }
266
267 /**
268 Make the PRNG ready to read from
269 @param prng The PRNG to make active
270 @return CRYPT_OK if successful
271 */
272 int sober128_ready(prng_state *prng)
273 {
274 return prng->sober128.set == 1 ? CRYPT_OK : CRYPT_ERROR;
275 }
276
277 /* XOR pseudo-random bytes into buffer
278 */
279 #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, out+(z*4));
280
281 /**
282 Read from the PRNG
283 @param out Destination
284 @param outlen Length of output
285 @param prng The active PRNG to read from
286 @return Number of octets read
287 */
288 unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng)
289 {
290 struct sober128_prng *c;
291 ulong32 t, tlen;
292
293 LTC_ARGCHK(out != NULL);
294 LTC_ARGCHK(prng != NULL);
295
296 #ifdef LTC_VALGRIND
297 zeromem(out, outlen);
298 #endif
299
300 c = &(prng->sober128);
301 t = 0;
302 tlen = outlen;
303
304 /* handle any previously buffered bytes */
305 while (c->nbuf != 0 && outlen != 0) {
306 *out++ ^= c->sbuf & 0xFF;
307 c->sbuf >>= 8;
308 c->nbuf -= 8;
309 --outlen;
310 }
311
312 #ifndef LTC_SMALL_CODE
313 /* do lots at a time, if there's enough to do */
314 while (outlen >= N*4) {
315 SROUND(0);
316 SROUND(1);
317 SROUND(2);
318 SROUND(3);
319 SROUND(4);
320 SROUND(5);
321 SROUND(6);
322 SROUND(7);
323 SROUND(8);
324 SROUND(9);
325 SROUND(10);
326 SROUND(11);
327 SROUND(12);
328 SROUND(13);
329 SROUND(14);
330 SROUND(15);
331 SROUND(16);
332 out += 4*N;
333 outlen -= 4*N;
334 }
335 #endif
336
337 /* do small or odd size buffers the slow way */
338 while (4 <= outlen) {
339 cycle(c->R);
340 t = nltap(c);
341 XORWORD(t, out);
342 out += 4;
343 outlen -= 4;
344 }
345
346 /* handle any trailing bytes */
347 if (outlen != 0) {
348 cycle(c->R);
349 c->sbuf = nltap(c);
350 c->nbuf = 32;
351 while (c->nbuf != 0 && outlen != 0) {
352 *out++ ^= c->sbuf & 0xFF;
353 c->sbuf >>= 8;
354 c->nbuf -= 8;
355 --outlen;
356 }
357 }
358
359 return tlen;
360 }
361
362 /**
363 Terminate the PRNG
364 @param prng The PRNG to terminate
365 @return CRYPT_OK if successful
366 */
367 int sober128_done(prng_state *prng)
368 {
369 LTC_ARGCHK(prng != NULL);
370 return CRYPT_OK;
371 }
372
373 /**
374 Export the PRNG state
375 @param out [out] Destination
376 @param outlen [in/out] Max size and resulting size of the state
377 @param prng The PRNG to export
378 @return CRYPT_OK if successful
379 */
380 int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
381 {
382 LTC_ARGCHK(outlen != NULL);
383 LTC_ARGCHK(out != NULL);
384 LTC_ARGCHK(prng != NULL);
385
386 if (*outlen < 64) {
387 *outlen = 64;
388 return CRYPT_BUFFER_OVERFLOW;
389 }
390
391 if (sober128_read(out, 64, prng) != 64) {
392 return CRYPT_ERROR_READPRNG;
393 }
394 *outlen = 64;
395
396 return CRYPT_OK;
397 }
398
399 /**
400 Import a PRNG state
401 @param in The PRNG state
402 @param inlen Size of the state
403 @param prng The PRNG to import
404 @return CRYPT_OK if successful
405 */
406 int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
407 {
408 int err;
409 LTC_ARGCHK(in != NULL);
410 LTC_ARGCHK(prng != NULL);
411
412 if (inlen != 64) {
413 return CRYPT_INVALID_ARG;
414 }
415
416 if ((err = sober128_start(prng)) != CRYPT_OK) {
417 return err;
418 }
419 if ((err = sober128_add_entropy(in, 64, prng)) != CRYPT_OK) {
420 return err;
421 }
422 return sober128_ready(prng);
423 }
424
425 /**
426 PRNG self-test
427 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
428 */
429 int sober128_test(void)
430 {
431 #ifndef LTC_TEST
432 return CRYPT_NOP;
433 #else
434 static const struct {
435 int keylen, ivlen, len;
436 unsigned char key[16], iv[4], out[20];
437 } tests[] = {
438
439 {
440 16, 4, 20,
441
442 /* key */
443 { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79,
444 0x20, 0x31, 0x32, 0x38, 0x62, 0x69, 0x74, 0x73 },
445
446 /* IV */
447 { 0x00, 0x00, 0x00, 0x00 },
448
449 /* expected output */
450 { 0x43, 0x50, 0x0c, 0xcf, 0x89, 0x91, 0x9f, 0x1d,
451 0xaa, 0x37, 0x74, 0x95, 0xf4, 0xb4, 0x58, 0xc2,
452 0x40, 0x37, 0x8b, 0xbb }
453 }
454
455 };
456 prng_state prng;
457 unsigned char dst[20];
458 int err, x;
459
460 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
461 if ((err = sober128_start(&prng)) != CRYPT_OK) {
462 return err;
463 }
464 if ((err = sober128_add_entropy(tests[x].key, tests[x].keylen, &prng)) != CRYPT_OK) {
465 return err;
466 }
467 /* add IV */
468 if ((err = sober128_add_entropy(tests[x].iv, tests[x].ivlen, &prng)) != CRYPT_OK) {
469 return err;
470 }
471
472 /* ready up */
473 if ((err = sober128_ready(&prng)) != CRYPT_OK) {
474 return err;
475 }
476 XMEMSET(dst, 0, tests[x].len);
477 if (sober128_read(dst, tests[x].len, &prng) != (unsigned long)tests[x].len) {
478 return CRYPT_ERROR_READPRNG;
479 }
480 sober128_done(&prng);
481 if (XMEMCMP(dst, tests[x].out, tests[x].len)) {
482 #if 0
483 printf("\n\nLTC_SOBER128 failed, I got:\n");
484 for (y = 0; y < tests[x].len; y++) printf("%02x ", dst[y]);
485 printf("\n");
486 #endif
487 return CRYPT_FAIL_TESTVECTOR;
488 }
489 }
490 return CRYPT_OK;
491 #endif
492 }
493
494 #endif
495
496
497 /* $Source$ */
498 /* $Revision$ */
499 /* $Date$ */
+0
-162
libtom-src/prngs/sober128tab.c.inc less more
0 /**
1 @file sober128tab.c
2 SOBER-128 Tables
3 */
4 /* $ID$ */
5 /* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */
6 /* Multiplication table for Turing using 0xD02B4367 */
7 static const ulong32 Multab[256] = {
8 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9,
9 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478,
10 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746,
11 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697,
12 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A,
13 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB,
14 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5,
15 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04,
16 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2,
17 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613,
18 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D,
19 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC,
20 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51,
21 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80,
22 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE,
23 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F,
24 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F,
25 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE,
26 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90,
27 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41,
28 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC,
29 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D,
30 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703,
31 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2,
32 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14,
33 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5,
34 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB,
35 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A,
36 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787,
37 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656,
38 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568,
39 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9,
40 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748,
41 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699,
42 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7,
43 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476,
44 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB,
45 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A,
46 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34,
47 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5,
48 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523,
49 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2,
50 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC,
51 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D,
52 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0,
53 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61,
54 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F,
55 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E,
56 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E,
57 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F,
58 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71,
59 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0,
60 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D,
61 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC,
62 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2,
63 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433,
64 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5,
65 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24,
66 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A,
67 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB,
68 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566,
69 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7,
70 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789,
71 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658,
72 };
73
74 /* $ID$ */
75 /* Sbox for SOBER-128 */
76 /*
77 * This is really the combination of two SBoxes; the least significant
78 * 24 bits comes from:
79 * 8->32 Sbox generated by Millan et. al. at Queensland University of
80 * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter,
81 * "On the Design of 8*32 S-boxes". Unpublished report, by the
82 * Information Systems Research Centre,
83 * Queensland University of Technology, 1999.
84 *
85 * The most significant 8 bits are the Skipjack "F table", which can be
86 * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf .
87 * In this optimised table, though, the intent is to XOR the word from
88 * the table selected by the high byte with the input word. Thus, the
89 * high byte is actually the Skipjack F-table entry XORED with its
90 * table index.
91 */
92 static const ulong32 Sbox[256] = {
93 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4,
94 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae,
95 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c,
96 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35,
97 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e,
98 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b,
99 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f,
100 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1,
101 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd,
102 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3,
103 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f,
104 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36,
105 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf,
106 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816,
107 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d,
108 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af,
109 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6,
110 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418,
111 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0,
112 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd,
113 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088,
114 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759,
115 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895,
116 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66,
117 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc,
118 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1,
119 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911,
120 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e,
121 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515,
122 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133,
123 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226,
124 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084,
125 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb,
126 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184,
127 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420,
128 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02,
129 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655,
130 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c,
131 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418,
132 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473,
133 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a,
134 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0,
135 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21,
136 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36,
137 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5,
138 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6,
139 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0,
140 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795,
141 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0,
142 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78,
143 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da,
144 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a,
145 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118,
146 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed,
147 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd,
148 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b,
149 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921,
150 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e,
151 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5,
152 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8,
153 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376,
154 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a,
155 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8,
156 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40,
157 };
158
159 /* $Source$ */
160 /* $Revision$ */
161 /* $Date$ */
+0
-136
libtom-src/prngs/sprng.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file sprng.c
14 Secure PRNG, Tom St Denis
15 */
16
17 /* A secure PRNG using the RNG functions. Basically this is a
18 * wrapper that allows you to use a secure RNG as a PRNG
19 * in the various other functions.
20 */
21
22 #ifdef LTC_SPRNG
23
24 const struct ltc_prng_descriptor sprng_desc =
25 {
26 "sprng", 0,
27 &sprng_start,
28 &sprng_add_entropy,
29 &sprng_ready,
30 &sprng_read,
31 &sprng_done,
32 &sprng_export,
33 &sprng_import,
34 &sprng_test
35 };
36
37 /**
38 Start the PRNG
39 @param prng [out] The PRNG state to initialize
40 @return CRYPT_OK if successful
41 */
42 int sprng_start(prng_state *prng)
43 {
44 return CRYPT_OK;
45 }
46
47 /**
48 Add entropy to the PRNG state
49 @param in The data to add
50 @param inlen Length of the data to add
51 @param prng PRNG state to update
52 @return CRYPT_OK if successful
53 */
54 int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
55 {
56 return CRYPT_OK;
57 }
58
59 /**
60 Make the PRNG ready to read from
61 @param prng The PRNG to make active
62 @return CRYPT_OK if successful
63 */
64 int sprng_ready(prng_state *prng)
65 {
66 return CRYPT_OK;
67 }
68
69 /**
70 Read from the PRNG
71 @param out Destination
72 @param outlen Length of output
73 @param prng The active PRNG to read from
74 @return Number of octets read
75 */
76 unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
77 {
78 LTC_ARGCHK(out != NULL);
79 return rng_get_bytes(out, outlen, NULL);
80 }
81
82 /**
83 Terminate the PRNG
84 @param prng The PRNG to terminate
85 @return CRYPT_OK if successful
86 */
87 int sprng_done(prng_state *prng)
88 {
89 return CRYPT_OK;
90 }
91
92 /**
93 Export the PRNG state
94 @param out [out] Destination
95 @param outlen [in/out] Max size and resulting size of the state
96 @param prng The PRNG to export
97 @return CRYPT_OK if successful
98 */
99 int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
100 {
101 LTC_ARGCHK(outlen != NULL);
102
103 *outlen = 0;
104 return CRYPT_OK;
105 }
106
107 /**
108 Import a PRNG state
109 @param in The PRNG state
110 @param inlen Size of the state
111 @param prng The PRNG to import
112 @return CRYPT_OK if successful
113 */
114 int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
115 {
116 return CRYPT_OK;
117 }
118
119 /**
120 PRNG self-test
121 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
122 */
123 int sprng_test(void)
124 {
125 return CRYPT_OK;
126 }
127
128 #endif
129
130
131
132
133 /* $Source$ */
134 /* $Revision$ */
135 /* $Date$ */
+0
-364
libtom-src/prngs/yarrow.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file yarrow.c
14 Yarrow PRNG, Tom St Denis
15 */
16
17 #ifdef LTC_YARROW
18
19 const struct ltc_prng_descriptor yarrow_desc =
20 {
21 "yarrow", 64,
22 &yarrow_start,
23 &yarrow_add_entropy,
24 &yarrow_ready,
25 &yarrow_read,
26 &yarrow_done,
27 &yarrow_export,
28 &yarrow_import,
29 &yarrow_test
30 };
31
32 /**
33 Start the PRNG
34 @param prng [out] The PRNG state to initialize
35 @return CRYPT_OK if successful
36 */
37 int yarrow_start(prng_state *prng)
38 {
39 int err;
40
41 LTC_ARGCHK(prng != NULL);
42
43 /* these are the default hash/cipher combo used */
44 #ifdef LTC_RIJNDAEL
45 #if LTC_YARROW_AES==0
46 prng->yarrow.cipher = register_cipher(&rijndael_enc_desc);
47 #elif LTC_YARROW_AES==1
48 prng->yarrow.cipher = register_cipher(&aes_enc_desc);
49 #elif LTC_YARROW_AES==2
50 prng->yarrow.cipher = register_cipher(&rijndael_desc);
51 #elif LTC_YARROW_AES==3
52 prng->yarrow.cipher = register_cipher(&aes_desc);
53 #endif
54 #elif defined(LTC_BLOWFISH)
55 prng->yarrow.cipher = register_cipher(&blowfish_desc);
56 #elif defined(LTC_TWOFISH)
57 prng->yarrow.cipher = register_cipher(&twofish_desc);
58 #elif defined(LTC_RC6)
59 prng->yarrow.cipher = register_cipher(&rc6_desc);
60 #elif defined(LTC_RC5)
61 prng->yarrow.cipher = register_cipher(&rc5_desc);
62 #elif defined(LTC_SAFERP)
63 prng->yarrow.cipher = register_cipher(&saferp_desc);
64 #elif defined(LTC_RC2)
65 prng->yarrow.cipher = register_cipher(&rc2_desc);
66 #elif defined(LTC_NOEKEON)
67 prng->yarrow.cipher = register_cipher(&noekeon_desc);
68 #elif defined(LTC_ANUBIS)
69 prng->yarrow.cipher = register_cipher(&anubis_desc);
70 #elif defined(LTC_KSEED)
71 prng->yarrow.cipher = register_cipher(&kseed_desc);
72 #elif defined(LTC_KHAZAD)
73 prng->yarrow.cipher = register_cipher(&khazad_desc);
74 #elif defined(LTC_CAST5)
75 prng->yarrow.cipher = register_cipher(&cast5_desc);
76 #elif defined(LTC_XTEA)
77 prng->yarrow.cipher = register_cipher(&xtea_desc);
78 #elif defined(LTC_SAFER)
79 prng->yarrow.cipher = register_cipher(&safer_sk128_desc);
80 #elif defined(LTC_DES)
81 prng->yarrow.cipher = register_cipher(&des3_desc);
82 #else
83 #error LTC_YARROW needs at least one CIPHER
84 #endif
85 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
86 return err;
87 }
88
89 #ifdef LTC_SHA256
90 prng->yarrow.hash = register_hash(&sha256_desc);
91 #elif defined(LTC_SHA512)
92 prng->yarrow.hash = register_hash(&sha512_desc);
93 #elif defined(LTC_TIGER)
94 prng->yarrow.hash = register_hash(&tiger_desc);
95 #elif defined(LTC_SHA1)
96 prng->yarrow.hash = register_hash(&sha1_desc);
97 #elif defined(LTC_RIPEMD320)
98 prng->yarrow.hash = register_hash(&rmd320_desc);
99 #elif defined(LTC_RIPEMD256)
100 prng->yarrow.hash = register_hash(&rmd256_desc);
101 #elif defined(LTC_RIPEMD160)
102 prng->yarrow.hash = register_hash(&rmd160_desc);
103 #elif defined(LTC_RIPEMD128)
104 prng->yarrow.hash = register_hash(&rmd128_desc);
105 #elif defined(LTC_MD5)
106 prng->yarrow.hash = register_hash(&md5_desc);
107 #elif defined(LTC_MD4)
108 prng->yarrow.hash = register_hash(&md4_desc);
109 #elif defined(LTC_MD2)
110 prng->yarrow.hash = register_hash(&md2_desc);
111 #elif defined(LTC_WHIRLPOOL)
112 prng->yarrow.hash = register_hash(&whirlpool_desc);
113 #else
114 #error LTC_YARROW needs at least one HASH
115 #endif
116 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
117 return err;
118 }
119
120 /* zero the memory used */
121 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
122 LTC_MUTEX_INIT(&prng->yarrow.prng_lock)
123
124 return CRYPT_OK;
125 }
126
127 /**
128 Add entropy to the PRNG state
129 @param in The data to add
130 @param inlen Length of the data to add
131 @param prng PRNG state to update
132 @return CRYPT_OK if successful
133 */
134 int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
135 {
136 hash_state md;
137 int err;
138
139 LTC_ARGCHK(in != NULL);
140 LTC_ARGCHK(prng != NULL);
141
142 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
143
144 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
145 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
146 return err;
147 }
148
149 /* start the hash */
150 if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) {
151 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
152 return err;
153 }
154
155 /* hash the current pool */
156 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,
157 hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
158 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
159 return err;
160 }
161
162 /* add the new entropy */
163 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) {
164 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
165 return err;
166 }
167
168 /* store result */
169 if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
170 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
171 return err;
172 }
173
174 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
175 return CRYPT_OK;
176 }
177
178 /**
179 Make the PRNG ready to read from
180 @param prng The PRNG to make active
181 @return CRYPT_OK if successful
182 */
183 int yarrow_ready(prng_state *prng)
184 {
185 int ks, err;
186
187 LTC_ARGCHK(prng != NULL);
188 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
189
190 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
191 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
192 return err;
193 }
194
195 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
196 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
197 return err;
198 }
199
200 /* setup CTR mode using the "pool" as the key */
201 ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
202 if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
203 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
204 return err;
205 }
206
207 if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */
208 prng->yarrow.pool, /* IV */
209 prng->yarrow.pool, ks, /* KEY and key size */
210 0, /* number of rounds */
211 CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */
212 &prng->yarrow.ctr)) != CRYPT_OK) {
213 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
214 return err;
215 }
216 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
217 return CRYPT_OK;
218 }
219
220 /**
221 Read from the PRNG
222 @param out Destination
223 @param outlen Length of output
224 @param prng The active PRNG to read from
225 @return Number of octets read
226 */
227 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng)
228 {
229 LTC_ARGCHK(out != NULL);
230 LTC_ARGCHK(prng != NULL);
231
232 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
233
234 /* put out in predictable state first */
235 zeromem(out, outlen);
236
237 /* now randomize it */
238 if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) {
239 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
240 return 0;
241 }
242 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
243 return outlen;
244 }
245
246 /**
247 Terminate the PRNG
248 @param prng The PRNG to terminate
249 @return CRYPT_OK if successful
250 */
251 int yarrow_done(prng_state *prng)
252 {
253 int err;
254 LTC_ARGCHK(prng != NULL);
255
256 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
257
258 /* call cipher done when we invent one ;-) */
259
260 /* we invented one */
261 err = ctr_done(&prng->yarrow.ctr);
262
263 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
264 return err;
265 }
266
267 /**
268 Export the PRNG state
269 @param out [out] Destination
270 @param outlen [in/out] Max size and resulting size of the state
271 @param prng The PRNG to export
272 @return CRYPT_OK if successful
273 */
274 int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
275 {
276 LTC_ARGCHK(out != NULL);
277 LTC_ARGCHK(outlen != NULL);
278 LTC_ARGCHK(prng != NULL);
279
280 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
281
282 /* we'll write 64 bytes for s&g's */
283 if (*outlen < 64) {
284 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
285 *outlen = 64;
286 return CRYPT_BUFFER_OVERFLOW;
287 }
288
289 if (yarrow_read(out, 64, prng) != 64) {
290 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
291 return CRYPT_ERROR_READPRNG;
292 }
293 *outlen = 64;
294
295 return CRYPT_OK;
296 }
297
298 /**
299 Import a PRNG state
300 @param in The PRNG state
301 @param inlen Size of the state
302 @param prng The PRNG to import
303 @return CRYPT_OK if successful
304 */
305 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
306 {
307 int err;
308
309 LTC_ARGCHK(in != NULL);
310 LTC_ARGCHK(prng != NULL);
311
312 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
313
314 if (inlen != 64) {
315 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
316 return CRYPT_INVALID_ARG;
317 }
318
319 if ((err = yarrow_start(prng)) != CRYPT_OK) {
320 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
321 return err;
322 }
323 err = yarrow_add_entropy(in, 64, prng);
324 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
325 return err;
326 }
327
328 /**
329 PRNG self-test
330 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
331 */
332 int yarrow_test(void)
333 {
334 #ifndef LTC_TEST
335 return CRYPT_NOP;
336 #else
337 int err;
338 prng_state prng;
339
340 if ((err = yarrow_start(&prng)) != CRYPT_OK) {
341 return err;
342 }
343
344 /* now let's test the hash/cipher that was chosen */
345 if (cipher_descriptor[prng.yarrow.cipher].test &&
346 ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK)) {
347 return err;
348 }
349 if (hash_descriptor[prng.yarrow.hash].test &&
350 ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK)) {
351 return err;
352 }
353
354 return CRYPT_OK;
355 #endif
356 }
357
358 #endif
359
360
361 /* $Source$ */
362 /* $Revision$ */
363 /* $Date$ */
+0
-591
libtom-src/tommath.h less more
0 /* LibTomMath, multiple-precision integer library -- Tom St Denis
1 *
2 * LibTomMath is a library that provides multiple-precision
3 * integer arithmetic as well as number theoretic functionality.
4 *
5 * The library was designed directly after the MPI library by
6 * Michael Fromberger but has been written from scratch with
7 * additional optimizations in place.
8 *
9 * The library is free for all purposes without any express
10 * guarantee it works.
11 *
12 * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
13 */
14 #ifndef BN_H_
15 #define BN_H_
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <ctype.h>
21 #include <limits.h>
22
23 #include <tommath_class.h>
24
25 #ifndef MIN
26 #define MIN(x,y) ((x)<(y)?(x):(y))
27 #endif
28
29 #ifndef MAX
30 #define MAX(x,y) ((x)>(y)?(x):(y))
31 #endif
32
33 #ifdef __cplusplus
34 extern "C" {
35
36 /* C++ compilers don't like assigning void * to mp_digit * */
37 #define OPT_CAST(x) (x *)
38
39 #else
40
41 /* C on the other hand doesn't care */
42 #define OPT_CAST(x)
43
44 #endif
45
46
47 /* detect 64-bit mode if possible */
48 #if defined(__x86_64__)
49 #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
50 #define MP_64BIT
51 #endif
52 #endif
53
54 /* some default configurations.
55 *
56 * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
57 * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
58 *
59 * At the very least a mp_digit must be able to hold 7 bits
60 * [any size beyond that is ok provided it doesn't overflow the data type]
61 */
62 #ifdef MP_8BIT
63 typedef unsigned char mp_digit;
64 typedef unsigned short mp_word;
65 #elif defined(MP_16BIT)
66 typedef unsigned short mp_digit;
67 typedef unsigned long mp_word;
68 #elif defined(MP_64BIT)
69 /* for GCC only on supported platforms */
70 #ifndef CRYPT
71 typedef unsigned long long ulong64;
72 typedef signed long long long64;
73 #endif
74
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;
82 typedef unsigned long mp_word __attribute__ ((mode(TI)));
83 #define DIGIT_BIT 60
84 #endif
85
86
87 #else
88 /* this is the default case, 28-bit digits */
89
90 /* this is to make porting into LibTomCrypt easier :-) */
91 #ifndef CRYPT
92 #if defined(_MSC_VER) || defined(__BORLANDC__)
93 typedef unsigned __int64 ulong64;
94 typedef signed __int64 long64;
95 #else
96 typedef unsigned long long ulong64;
97 typedef signed long long long64;
98 #endif
99 #endif
100
101 typedef unsigned long mp_digit;
102 typedef ulong64 mp_word;
103
104 #ifdef MP_31BIT
105 /* this is an extension that uses 31-bit digits */
106 #define DIGIT_BIT 31
107 #else
108 /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
109 #define DIGIT_BIT 28
110 #define MP_28BIT
111 #endif
112 #endif
113
114 /* define heap macros */
115 #ifndef CRYPT
116 /* default to libc stuff */
117 #ifndef XMALLOC
118 #define XMALLOC malloc
119 #define XFREE free
120 #define XREALLOC realloc
121 #define XCALLOC calloc
122 #else
123 /* prototypes for our heap functions */
124 extern void *XMALLOC(size_t n);
125 extern void *XREALLOC(void *p, size_t n);
126 extern void *XCALLOC(size_t n, size_t s);
127 extern void XFREE(void *p);
128 #endif
129 #endif
130
131
132 /* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
133 #ifndef DIGIT_BIT
134 #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
135 #endif
136
137 #define MP_DIGIT_BIT DIGIT_BIT
138 #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
139 #define MP_DIGIT_MAX MP_MASK
140
141 /* equalities */
142 #define MP_LT -1 /* less than */
143 #define MP_EQ 0 /* equal to */
144 #define MP_GT 1 /* greater than */
145
146 #define MP_ZPOS 0 /* positive integer */
147 #define MP_NEG 1 /* negative */
148
149 #define MP_OKAY 0 /* ok result */
150 #define MP_MEM -2 /* out of mem */
151 #define MP_VAL -3 /* invalid input */
152 #define MP_RANGE MP_VAL
153
154 #define MP_YES 1 /* yes response */
155 #define MP_NO 0 /* no response */
156
157 /* Primality generation flags */
158 #define LTM_PRIME_BBS 0x0001 /* BBS style prime */
159 #define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
160 #define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
161
162 typedef int mp_err;
163
164 /* you'll have to tune these... */
165 extern int KARATSUBA_MUL_CUTOFF,
166 KARATSUBA_SQR_CUTOFF,
167 TOOM_MUL_CUTOFF,
168 TOOM_SQR_CUTOFF;
169
170 /* define this to use lower memory usage routines (exptmods mostly) */
171 /* #define MP_LOW_MEM */
172
173 /* default precision */
174 #ifndef MP_PREC
175 #ifndef MP_LOW_MEM
176 #define MP_PREC 32 /* default digits of precision */
177 #else
178 #define MP_PREC 8 /* default digits of precision */
179 #endif
180 #endif
181
182 /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
183 #define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
184
185 /* the infamous mp_int structure */
186 typedef struct {
187 int used, alloc, sign;
188 mp_digit *dp;
189 } mp_int;
190
191 /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
192 typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
193
194
195 #define USED(m) ((m)->used)
196 #define DIGIT(m,k) ((m)->dp[(k)])
197 #define SIGN(m) ((m)->sign)
198
199 /* error code to char* string */
200 const char *mp_error_to_string(int code);
201
202 /* ---> init and deinit bignum functions <--- */
203 /* init a bignum */
204 int mp_init(mp_int *a);
205
206 /* free a bignum */
207 void mp_clear(mp_int *a);
208
209 /* init a null terminated series of arguments */
210 int mp_init_multi(mp_int *mp, ...);
211
212 /* clear a null terminated series of arguments */
213 void mp_clear_multi(mp_int *mp, ...);
214
215 /* exchange two ints */
216 void mp_exch(mp_int *a, mp_int *b);
217
218 /* shrink ram required for a bignum */
219 int mp_shrink(mp_int *a);
220
221 /* grow an int to a given size */
222 int mp_grow(mp_int *a, int size);
223
224 /* init to a given number of digits */
225 int mp_init_size(mp_int *a, int size);
226
227 /* ---> Basic Manipulations <--- */
228 #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
229 #define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
230 #define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
231
232 /* set to zero */
233 void mp_zero(mp_int *a);
234
235 /* set to a digit */
236 void mp_set(mp_int *a, mp_digit b);
237
238 /* set a 32-bit const */
239 int mp_set_int(mp_int *a, unsigned long b);
240
241 /* get a 32-bit value */
242 unsigned long mp_get_int(mp_int * a);
243
244 /* initialize and set a digit */
245 int mp_init_set (mp_int * a, mp_digit b);
246
247 /* initialize and set 32-bit value */
248 int mp_init_set_int (mp_int * a, unsigned long b);
249
250 /* copy, b = a */
251 int mp_copy(mp_int *a, mp_int *b);
252
253 /* inits and copies, a = b */
254 int mp_init_copy(mp_int *a, mp_int *b);
255
256 /* trim unused digits */
257 void mp_clamp(mp_int *a);
258
259 /* ---> digit manipulation <--- */
260
261 /* right shift by "b" digits */
262 void mp_rshd(mp_int *a, int b);
263
264 /* left shift by "b" digits */
265 int mp_lshd(mp_int *a, int b);
266
267 /* c = a / 2**b */
268 int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
269
270 /* b = a/2 */
271 int mp_div_2(mp_int *a, mp_int *b);
272
273 /* c = a * 2**b */
274 int mp_mul_2d(mp_int *a, int b, mp_int *c);
275
276 /* b = a*2 */
277 int mp_mul_2(mp_int *a, mp_int *b);
278
279 /* c = a mod 2**d */
280 int mp_mod_2d(mp_int *a, int b, mp_int *c);
281
282 /* computes a = 2**b */
283 int mp_2expt(mp_int *a, int b);
284
285 /* Counts the number of lsbs which are zero before the first zero bit */
286 int mp_cnt_lsb(mp_int *a);
287
288 /* I Love Earth! */
289
290 /* makes a pseudo-random int of a given size */
291 int mp_rand(mp_int *a, int digits);
292
293 /* ---> binary operations <--- */
294 /* c = a XOR b */
295 int mp_xor(mp_int *a, mp_int *b, mp_int *c);
296
297 /* c = a OR b */
298 int mp_or(mp_int *a, mp_int *b, mp_int *c);
299
300 /* c = a AND b */
301 int mp_and(mp_int *a, mp_int *b, mp_int *c);
302
303 /* ---> Basic arithmetic <--- */
304
305 /* b = -a */
306 int mp_neg(mp_int *a, mp_int *b);
307
308 /* b = |a| */
309 int mp_abs(mp_int *a, mp_int *b);
310
311 /* compare a to b */
312 int mp_cmp(mp_int *a, mp_int *b);
313
314 /* compare |a| to |b| */
315 int mp_cmp_mag(mp_int *a, mp_int *b);
316
317 /* c = a + b */
318 int mp_add(mp_int *a, mp_int *b, mp_int *c);
319
320 /* c = a - b */
321 int mp_sub(mp_int *a, mp_int *b, mp_int *c);
322
323 /* c = a * b */
324 int mp_mul(mp_int *a, mp_int *b, mp_int *c);
325
326 /* b = a*a */
327 int mp_sqr(mp_int *a, mp_int *b);
328
329 /* a/b => cb + d == a */
330 int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
331
332 /* c = a mod b, 0 <= c < b */
333 int mp_mod(mp_int *a, mp_int *b, mp_int *c);
334
335 /* ---> single digit functions <--- */
336
337 /* compare against a single digit */
338 int mp_cmp_d(mp_int *a, mp_digit b);
339
340 /* c = a + b */
341 int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
342
343 /* c = a - b */
344 int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
345
346 /* c = a * b */
347 int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
348
349 /* a/b => cb + d == a */
350 int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
351
352 /* a/3 => 3c + d == a */
353 int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
354
355 /* c = a**b */
356 int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
357
358 /* c = a mod b, 0 <= c < b */
359 int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
360
361 /* ---> number theory <--- */
362
363 /* d = a + b (mod c) */
364 int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
365
366 /* d = a - b (mod c) */
367 int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
368
369 /* d = a * b (mod c) */
370 int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
371
372 /* c = a * a (mod b) */
373 int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
374
375 /* c = 1/a (mod b) */
376 int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
377
378 /* c = (a, b) */
379 int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
380
381 /* produces value such that U1*a + U2*b = U3 */
382 int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
383
384 /* c = [a, b] or (a*b)/(a, b) */
385 int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
386
387 /* finds one of the b'th root of a, such that |c|**b <= |a|
388 *
389 * returns error if a < 0 and b is even
390 */
391 int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
392
393 /* special sqrt algo */
394 int mp_sqrt(mp_int *arg, mp_int *ret);
395
396 /* is number a square? */
397 int mp_is_square(mp_int *arg, int *ret);
398
399 /* computes the jacobi c = (a | n) (or Legendre if b is prime) */
400 int mp_jacobi(mp_int *a, mp_int *n, int *c);
401
402 /* used to setup the Barrett reduction for a given modulus b */
403 int mp_reduce_setup(mp_int *a, mp_int *b);
404
405 /* Barrett Reduction, computes a (mod b) with a precomputed value c
406 *
407 * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
408 * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
409 */
410 int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
411
412 /* setups the montgomery reduction */
413 int mp_montgomery_setup(mp_int *a, mp_digit *mp);
414
415 /* computes a = B**n mod b without division or multiplication useful for
416 * normalizing numbers in a Montgomery system.
417 */
418 int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
419
420 /* computes x/R == x (mod N) via Montgomery Reduction */
421 int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
422
423 /* returns 1 if a is a valid DR modulus */
424 int mp_dr_is_modulus(mp_int *a);
425
426 /* sets the value of "d" required for mp_dr_reduce */
427 void mp_dr_setup(mp_int *a, mp_digit *d);
428
429 /* reduces a modulo b using the Diminished Radix method */
430 int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
431
432 /* returns true if a can be reduced with mp_reduce_2k */
433 int mp_reduce_is_2k(mp_int *a);
434
435 /* determines k value for 2k reduction */
436 int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
437
438 /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
439 int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
440
441 /* returns true if a can be reduced with mp_reduce_2k_l */
442 int mp_reduce_is_2k_l(mp_int *a);
443
444 /* determines k value for 2k reduction */
445 int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
446
447 /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
448 int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
449
450 /* d = a**b (mod c) */
451 int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
452
453 /* ---> Primes <--- */
454
455 /* number of primes */
456 #ifdef MP_8BIT
457 #define PRIME_SIZE 31
458 #else
459 #define PRIME_SIZE 256
460 #endif
461
462 /* table of first PRIME_SIZE primes */
463 extern const mp_digit ltm_prime_tab[];
464
465 /* result=1 if a is divisible by one of the first PRIME_SIZE primes */
466 int mp_prime_is_divisible(mp_int *a, int *result);
467
468 /* performs one Fermat test of "a" using base "b".
469 * Sets result to 0 if composite or 1 if probable prime
470 */
471 int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
472
473 /* performs one Miller-Rabin test of "a" using base "b".
474 * Sets result to 0 if composite or 1 if probable prime
475 */
476 int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
477
478 /* This gives [for a given bit size] the number of trials required
479 * such that Miller-Rabin gives a prob of failure lower than 2^-96
480 */
481 int mp_prime_rabin_miller_trials(int size);
482
483 /* performs t rounds of Miller-Rabin on "a" using the first
484 * t prime bases. Also performs an initial sieve of trial
485 * division. Determines if "a" is prime with probability
486 * of error no more than (1/4)**t.
487 *
488 * Sets result to 1 if probably prime, 0 otherwise
489 */
490 int mp_prime_is_prime(mp_int *a, int t, int *result);
491
492 /* finds the next prime after the number "a" using "t" trials
493 * of Miller-Rabin.
494 *
495 * bbs_style = 1 means the prime must be congruent to 3 mod 4
496 */
497 int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
498
499 /* makes a truly random prime of a given size (bytes),
500 * call with bbs = 1 if you want it to be congruent to 3 mod 4
501 *
502 * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
503 * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
504 * so it can be NULL
505 *
506 * The prime generated will be larger than 2^(8*size).
507 */
508 #define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
509
510 /* makes a truly random prime of a given size (bits),
511 *
512 * Flags are as follows:
513 *
514 * LTM_PRIME_BBS - make prime congruent to 3 mod 4
515 * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
516 * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
517 *
518 * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
519 * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
520 * so it can be NULL
521 *
522 */
523 int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
524
525 /* ---> radix conversion <--- */
526 int mp_count_bits(mp_int *a);
527
528 int mp_unsigned_bin_size(mp_int *a);
529 int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
530 int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
531 int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
532
533 int mp_signed_bin_size(mp_int *a);
534 int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
535 int mp_to_signed_bin(mp_int *a, unsigned char *b);
536 int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
537
538 int mp_read_radix(mp_int *a, const char *str, int radix);
539 int mp_toradix(mp_int *a, char *str, int radix);
540 int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
541 int mp_radix_size(mp_int *a, int radix, int *size);
542
543 int mp_fread(mp_int *a, int radix, FILE *stream);
544 int mp_fwrite(mp_int *a, int radix, FILE *stream);
545
546 #define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
547 #define mp_raw_size(mp) mp_signed_bin_size(mp)
548 #define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
549 #define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
550 #define mp_mag_size(mp) mp_unsigned_bin_size(mp)
551 #define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
552
553 #define mp_tobinary(M, S) mp_toradix((M), (S), 2)
554 #define mp_tooctal(M, S) mp_toradix((M), (S), 8)
555 #define mp_todecimal(M, S) mp_toradix((M), (S), 10)
556 #define mp_tohex(M, S) mp_toradix((M), (S), 16)
557
558 /* lowlevel functions, do not call! */
559 int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
560 int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
561 #define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
562 int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
563 int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
564 int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
565 int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
566 int fast_s_mp_sqr(mp_int *a, mp_int *b);
567 int s_mp_sqr(mp_int *a, mp_int *b);
568 int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
569 int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
570 int mp_karatsuba_sqr(mp_int *a, mp_int *b);
571 int mp_toom_sqr(mp_int *a, mp_int *b);
572 int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
573 int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
574 int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
575 int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
576 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
577 void bn_reverse(unsigned char *s, int len);
578
579 extern const char *mp_s_rmap;
580
581 #ifdef __cplusplus
582 }
583 #endif
584
585 #endif
586
587
588 /* $Source$ */
589 /* $Revision$ */
590 /* $Date$ */
+0
-999
libtom-src/tommath_class.h less more
0 #if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
1 #if defined(LTM2)
2 #define LTM3
3 #endif
4 #if defined(LTM1)
5 #define LTM2
6 #endif
7 #define LTM1
8
9 #if defined(LTM_ALL)
10 #define BN_ERROR_C
11 #define BN_FAST_MP_INVMOD_C
12 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
13 #define BN_FAST_S_MP_MUL_DIGS_C
14 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
15 #define BN_FAST_S_MP_SQR_C
16 #define BN_MP_2EXPT_C
17 #define BN_MP_ABS_C
18 #define BN_MP_ADD_C
19 #define BN_MP_ADD_D_C
20 #define BN_MP_ADDMOD_C
21 #define BN_MP_AND_C
22 #define BN_MP_CLAMP_C
23 #define BN_MP_CLEAR_C
24 #define BN_MP_CLEAR_MULTI_C
25 #define BN_MP_CMP_C
26 #define BN_MP_CMP_D_C
27 #define BN_MP_CMP_MAG_C
28 #define BN_MP_CNT_LSB_C
29 #define BN_MP_COPY_C
30 #define BN_MP_COUNT_BITS_C
31 #define BN_MP_DIV_C
32 #define BN_MP_DIV_2_C
33 #define BN_MP_DIV_2D_C
34 #define BN_MP_DIV_3_C
35 #define BN_MP_DIV_D_C
36 #define BN_MP_DR_IS_MODULUS_C
37 #define BN_MP_DR_REDUCE_C
38 #define BN_MP_DR_SETUP_C
39 #define BN_MP_EXCH_C
40 #define BN_MP_EXPT_D_C
41 #define BN_MP_EXPTMOD_C
42 #define BN_MP_EXPTMOD_FAST_C
43 #define BN_MP_EXTEUCLID_C
44 #define BN_MP_FREAD_C
45 #define BN_MP_FWRITE_C
46 #define BN_MP_GCD_C
47 #define BN_MP_GET_INT_C
48 #define BN_MP_GROW_C
49 #define BN_MP_INIT_C
50 #define BN_MP_INIT_COPY_C
51 #define BN_MP_INIT_MULTI_C
52 #define BN_MP_INIT_SET_C
53 #define BN_MP_INIT_SET_INT_C
54 #define BN_MP_INIT_SIZE_C
55 #define BN_MP_INVMOD_C
56 #define BN_MP_INVMOD_SLOW_C
57 #define BN_MP_IS_SQUARE_C
58 #define BN_MP_JACOBI_C
59 #define BN_MP_KARATSUBA_MUL_C
60 #define BN_MP_KARATSUBA_SQR_C
61 #define BN_MP_LCM_C
62 #define BN_MP_LSHD_C
63 #define BN_MP_MOD_C
64 #define BN_MP_MOD_2D_C
65 #define BN_MP_MOD_D_C
66 #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
67 #define BN_MP_MONTGOMERY_REDUCE_C
68 #define BN_MP_MONTGOMERY_SETUP_C
69 #define BN_MP_MUL_C
70 #define BN_MP_MUL_2_C
71 #define BN_MP_MUL_2D_C
72 #define BN_MP_MUL_D_C
73 #define BN_MP_MULMOD_C
74 #define BN_MP_N_ROOT_C
75 #define BN_MP_NEG_C
76 #define BN_MP_OR_C
77 #define BN_MP_PRIME_FERMAT_C
78 #define BN_MP_PRIME_IS_DIVISIBLE_C
79 #define BN_MP_PRIME_IS_PRIME_C
80 #define BN_MP_PRIME_MILLER_RABIN_C
81 #define BN_MP_PRIME_NEXT_PRIME_C
82 #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
83 #define BN_MP_PRIME_RANDOM_EX_C
84 #define BN_MP_RADIX_SIZE_C
85 #define BN_MP_RADIX_SMAP_C
86 #define BN_MP_RAND_C
87 #define BN_MP_READ_RADIX_C
88 #define BN_MP_READ_SIGNED_BIN_C
89 #define BN_MP_READ_UNSIGNED_BIN_C
90 #define BN_MP_REDUCE_C
91 #define BN_MP_REDUCE_2K_C
92 #define BN_MP_REDUCE_2K_L_C
93 #define BN_MP_REDUCE_2K_SETUP_C
94 #define BN_MP_REDUCE_2K_SETUP_L_C
95 #define BN_MP_REDUCE_IS_2K_C
96 #define BN_MP_REDUCE_IS_2K_L_C
97 #define BN_MP_REDUCE_SETUP_C
98 #define BN_MP_RSHD_C
99 #define BN_MP_SET_C
100 #define BN_MP_SET_INT_C
101 #define BN_MP_SHRINK_C
102 #define BN_MP_SIGNED_BIN_SIZE_C
103 #define BN_MP_SQR_C
104 #define BN_MP_SQRMOD_C
105 #define BN_MP_SQRT_C
106 #define BN_MP_SUB_C
107 #define BN_MP_SUB_D_C
108 #define BN_MP_SUBMOD_C
109 #define BN_MP_TO_SIGNED_BIN_C
110 #define BN_MP_TO_SIGNED_BIN_N_C
111 #define BN_MP_TO_UNSIGNED_BIN_C
112 #define BN_MP_TO_UNSIGNED_BIN_N_C
113 #define BN_MP_TOOM_MUL_C
114 #define BN_MP_TOOM_SQR_C
115 #define BN_MP_TORADIX_C
116 #define BN_MP_TORADIX_N_C
117 #define BN_MP_UNSIGNED_BIN_SIZE_C
118 #define BN_MP_XOR_C
119 #define BN_MP_ZERO_C
120 #define BN_PRIME_TAB_C
121 #define BN_REVERSE_C
122 #define BN_S_MP_ADD_C
123 #define BN_S_MP_EXPTMOD_C
124 #define BN_S_MP_MUL_DIGS_C
125 #define BN_S_MP_MUL_HIGH_DIGS_C
126 #define BN_S_MP_SQR_C
127 #define BN_S_MP_SUB_C
128 #define BNCORE_C
129 #endif
130
131 #if defined(BN_ERROR_C)
132 #define BN_MP_ERROR_TO_STRING_C
133 #endif
134
135 #if defined(BN_FAST_MP_INVMOD_C)
136 #define BN_MP_ISEVEN_C
137 #define BN_MP_INIT_MULTI_C
138 #define BN_MP_COPY_C
139 #define BN_MP_MOD_C
140 #define BN_MP_SET_C
141 #define BN_MP_DIV_2_C
142 #define BN_MP_ISODD_C
143 #define BN_MP_SUB_C
144 #define BN_MP_CMP_C
145 #define BN_MP_ISZERO_C
146 #define BN_MP_CMP_D_C
147 #define BN_MP_ADD_C
148 #define BN_MP_EXCH_C
149 #define BN_MP_CLEAR_MULTI_C
150 #endif
151
152 #if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
153 #define BN_MP_GROW_C
154 #define BN_MP_RSHD_C
155 #define BN_MP_CLAMP_C
156 #define BN_MP_CMP_MAG_C
157 #define BN_S_MP_SUB_C
158 #endif
159
160 #if defined(BN_FAST_S_MP_MUL_DIGS_C)
161 #define BN_MP_GROW_C
162 #define BN_MP_CLAMP_C
163 #endif
164
165 #if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
166 #define BN_MP_GROW_C
167 #define BN_MP_CLAMP_C
168 #endif
169
170 #if defined(BN_FAST_S_MP_SQR_C)
171 #define BN_MP_GROW_C
172 #define BN_MP_CLAMP_C
173 #endif
174
175 #if defined(BN_MP_2EXPT_C)
176 #define BN_MP_ZERO_C
177 #define BN_MP_GROW_C
178 #endif
179
180 #if defined(BN_MP_ABS_C)
181 #define BN_MP_COPY_C
182 #endif
183
184 #if defined(BN_MP_ADD_C)
185 #define BN_S_MP_ADD_C
186 #define BN_MP_CMP_MAG_C
187 #define BN_S_MP_SUB_C
188 #endif
189
190 #if defined(BN_MP_ADD_D_C)
191 #define BN_MP_GROW_C
192 #define BN_MP_SUB_D_C
193 #define BN_MP_CLAMP_C
194 #endif
195
196 #if defined(BN_MP_ADDMOD_C)
197 #define BN_MP_INIT_C
198 #define BN_MP_ADD_C
199 #define BN_MP_CLEAR_C
200 #define BN_MP_MOD_C
201 #endif
202
203 #if defined(BN_MP_AND_C)
204 #define BN_MP_INIT_COPY_C
205 #define BN_MP_CLAMP_C
206 #define BN_MP_EXCH_C
207 #define BN_MP_CLEAR_C
208 #endif
209
210 #if defined(BN_MP_CLAMP_C)
211 #endif
212
213 #if defined(BN_MP_CLEAR_C)
214 #endif
215
216 #if defined(BN_MP_CLEAR_MULTI_C)
217 #define BN_MP_CLEAR_C
218 #endif
219
220 #if defined(BN_MP_CMP_C)
221 #define BN_MP_CMP_MAG_C
222 #endif
223
224 #if defined(BN_MP_CMP_D_C)
225 #endif
226
227 #if defined(BN_MP_CMP_MAG_C)
228 #endif
229
230 #if defined(BN_MP_CNT_LSB_C)
231 #define BN_MP_ISZERO_C
232 #endif
233
234 #if defined(BN_MP_COPY_C)
235 #define BN_MP_GROW_C
236 #endif
237
238 #if defined(BN_MP_COUNT_BITS_C)
239 #endif
240
241 #if defined(BN_MP_DIV_C)
242 #define BN_MP_ISZERO_C
243 #define BN_MP_CMP_MAG_C
244 #define BN_MP_COPY_C
245 #define BN_MP_ZERO_C
246 #define BN_MP_INIT_MULTI_C
247 #define BN_MP_SET_C
248 #define BN_MP_COUNT_BITS_C
249 #define BN_MP_ABS_C
250 #define BN_MP_MUL_2D_C
251 #define BN_MP_CMP_C
252 #define BN_MP_SUB_C
253 #define BN_MP_ADD_C
254 #define BN_MP_DIV_2D_C
255 #define BN_MP_EXCH_C
256 #define BN_MP_CLEAR_MULTI_C
257 #define BN_MP_INIT_SIZE_C
258 #define BN_MP_INIT_C
259 #define BN_MP_INIT_COPY_C
260 #define BN_MP_LSHD_C
261 #define BN_MP_RSHD_C
262 #define BN_MP_MUL_D_C
263 #define BN_MP_CLAMP_C
264 #define BN_MP_CLEAR_C
265 #endif
266
267 #if defined(BN_MP_DIV_2_C)
268 #define BN_MP_GROW_C
269 #define BN_MP_CLAMP_C
270 #endif
271
272 #if defined(BN_MP_DIV_2D_C)
273 #define BN_MP_COPY_C
274 #define BN_MP_ZERO_C
275 #define BN_MP_INIT_C
276 #define BN_MP_MOD_2D_C
277 #define BN_MP_CLEAR_C
278 #define BN_MP_RSHD_C
279 #define BN_MP_CLAMP_C
280 #define BN_MP_EXCH_C
281 #endif
282
283 #if defined(BN_MP_DIV_3_C)
284 #define BN_MP_INIT_SIZE_C
285 #define BN_MP_CLAMP_C
286 #define BN_MP_EXCH_C
287 #define BN_MP_CLEAR_C
288 #endif
289
290 #if defined(BN_MP_DIV_D_C)
291 #define BN_MP_ISZERO_C
292 #define BN_MP_COPY_C
293 #define BN_MP_DIV_2D_C
294 #define BN_MP_DIV_3_C
295 #define BN_MP_INIT_SIZE_C
296 #define BN_MP_CLAMP_C
297 #define BN_MP_EXCH_C
298 #define BN_MP_CLEAR_C
299 #endif
300
301 #if defined(BN_MP_DR_IS_MODULUS_C)
302 #endif
303
304 #if defined(BN_MP_DR_REDUCE_C)
305 #define BN_MP_GROW_C
306 #define BN_MP_CLAMP_C
307 #define BN_MP_CMP_MAG_C
308 #define BN_S_MP_SUB_C
309 #endif
310
311 #if defined(BN_MP_DR_SETUP_C)
312 #endif
313
314 #if defined(BN_MP_EXCH_C)
315 #endif
316
317 #if defined(BN_MP_EXPT_D_C)
318 #define BN_MP_INIT_COPY_C
319 #define BN_MP_SET_C
320 #define BN_MP_SQR_C
321 #define BN_MP_CLEAR_C
322 #define BN_MP_MUL_C
323 #endif
324
325 #if defined(BN_MP_EXPTMOD_C)
326 #define BN_MP_INIT_C
327 #define BN_MP_INVMOD_C
328 #define BN_MP_CLEAR_C
329 #define BN_MP_ABS_C
330 #define BN_MP_CLEAR_MULTI_C
331 #define BN_MP_REDUCE_IS_2K_L_C
332 #define BN_S_MP_EXPTMOD_C
333 #define BN_MP_DR_IS_MODULUS_C
334 #define BN_MP_REDUCE_IS_2K_C
335 #define BN_MP_ISODD_C
336 #define BN_MP_EXPTMOD_FAST_C
337 #endif
338
339 #if defined(BN_MP_EXPTMOD_FAST_C)
340 #define BN_MP_COUNT_BITS_C
341 #define BN_MP_INIT_C
342 #define BN_MP_CLEAR_C
343 #define BN_MP_MONTGOMERY_SETUP_C
344 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
345 #define BN_MP_MONTGOMERY_REDUCE_C
346 #define BN_MP_DR_SETUP_C
347 #define BN_MP_DR_REDUCE_C
348 #define BN_MP_REDUCE_2K_SETUP_C
349 #define BN_MP_REDUCE_2K_C
350 #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
351 #define BN_MP_MULMOD_C
352 #define BN_MP_SET_C
353 #define BN_MP_MOD_C
354 #define BN_MP_COPY_C
355 #define BN_MP_SQR_C
356 #define BN_MP_MUL_C
357 #define BN_MP_EXCH_C
358 #endif
359
360 #if defined(BN_MP_EXTEUCLID_C)
361 #define BN_MP_INIT_MULTI_C
362 #define BN_MP_SET_C
363 #define BN_MP_COPY_C
364 #define BN_MP_ISZERO_C
365 #define BN_MP_DIV_C
366 #define BN_MP_MUL_C
367 #define BN_MP_SUB_C
368 #define BN_MP_NEG_C
369 #define BN_MP_EXCH_C
370 #define BN_MP_CLEAR_MULTI_C
371 #endif
372
373 #if defined(BN_MP_FREAD_C)
374 #define BN_MP_ZERO_C
375 #define BN_MP_S_RMAP_C
376 #define BN_MP_MUL_D_C
377 #define BN_MP_ADD_D_C
378 #define BN_MP_CMP_D_C
379 #endif
380
381 #if defined(BN_MP_FWRITE_C)
382 #define BN_MP_RADIX_SIZE_C
383 #define BN_MP_TORADIX_C
384 #endif
385
386 #if defined(BN_MP_GCD_C)
387 #define BN_MP_ISZERO_C
388 #define BN_MP_ABS_C
389 #define BN_MP_ZERO_C
390 #define BN_MP_INIT_COPY_C
391 #define BN_MP_CNT_LSB_C
392 #define BN_MP_DIV_2D_C
393 #define BN_MP_CMP_MAG_C
394 #define BN_MP_EXCH_C
395 #define BN_S_MP_SUB_C
396 #define BN_MP_MUL_2D_C
397 #define BN_MP_CLEAR_C
398 #endif
399
400 #if defined(BN_MP_GET_INT_C)
401 #endif
402
403 #if defined(BN_MP_GROW_C)
404 #endif
405
406 #if defined(BN_MP_INIT_C)
407 #endif
408
409 #if defined(BN_MP_INIT_COPY_C)
410 #define BN_MP_COPY_C
411 #endif
412
413 #if defined(BN_MP_INIT_MULTI_C)
414 #define BN_MP_ERR_C
415 #define BN_MP_INIT_C
416 #define BN_MP_CLEAR_C
417 #endif
418
419 #if defined(BN_MP_INIT_SET_C)
420 #define BN_MP_INIT_C
421 #define BN_MP_SET_C
422 #endif
423
424 #if defined(BN_MP_INIT_SET_INT_C)
425 #define BN_MP_INIT_C
426 #define BN_MP_SET_INT_C
427 #endif
428
429 #if defined(BN_MP_INIT_SIZE_C)
430 #define BN_MP_INIT_C
431 #endif
432
433 #if defined(BN_MP_INVMOD_C)
434 #define BN_MP_ISZERO_C
435 #define BN_MP_ISODD_C
436 #define BN_FAST_MP_INVMOD_C
437 #define BN_MP_INVMOD_SLOW_C
438 #endif
439
440 #if defined(BN_MP_INVMOD_SLOW_C)
441 #define BN_MP_ISZERO_C
442 #define BN_MP_INIT_MULTI_C
443 #define BN_MP_MOD_C
444 #define BN_MP_COPY_C
445 #define BN_MP_ISEVEN_C
446 #define BN_MP_SET_C
447 #define BN_MP_DIV_2_C
448 #define BN_MP_ISODD_C
449 #define BN_MP_ADD_C
450 #define BN_MP_SUB_C
451 #define BN_MP_CMP_C
452 #define BN_MP_CMP_D_C
453 #define BN_MP_CMP_MAG_C
454 #define BN_MP_EXCH_C
455 #define BN_MP_CLEAR_MULTI_C
456 #endif
457
458 #if defined(BN_MP_IS_SQUARE_C)
459 #define BN_MP_MOD_D_C
460 #define BN_MP_INIT_SET_INT_C
461 #define BN_MP_MOD_C
462 #define BN_MP_GET_INT_C
463 #define BN_MP_SQRT_C
464 #define BN_MP_SQR_C
465 #define BN_MP_CMP_MAG_C
466 #define BN_MP_CLEAR_C
467 #endif
468
469 #if defined(BN_MP_JACOBI_C)
470 #define BN_MP_CMP_D_C
471 #define BN_MP_ISZERO_C
472 #define BN_MP_INIT_COPY_C
473 #define BN_MP_CNT_LSB_C
474 #define BN_MP_DIV_2D_C
475 #define BN_MP_MOD_C
476 #define BN_MP_CLEAR_C
477 #endif
478
479 #if defined(BN_MP_KARATSUBA_MUL_C)
480 #define BN_MP_MUL_C
481 #define BN_MP_INIT_SIZE_C
482 #define BN_MP_CLAMP_C
483 #define BN_MP_SUB_C
484 #define BN_MP_ADD_C
485 #define BN_MP_LSHD_C
486 #define BN_MP_CLEAR_C
487 #endif
488
489 #if defined(BN_MP_KARATSUBA_SQR_C)
490 #define BN_MP_INIT_SIZE_C
491 #define BN_MP_CLAMP_C
492 #define BN_MP_SQR_C
493 #define BN_MP_SUB_C
494 #define BN_S_MP_ADD_C
495 #define BN_MP_LSHD_C
496 #define BN_MP_ADD_C
497 #define BN_MP_CLEAR_C
498 #endif
499
500 #if defined(BN_MP_LCM_C)
501 #define BN_MP_INIT_MULTI_C
502 #define BN_MP_GCD_C
503 #define BN_MP_CMP_MAG_C
504 #define BN_MP_DIV_C
505 #define BN_MP_MUL_C
506 #define BN_MP_CLEAR_MULTI_C
507 #endif
508
509 #if defined(BN_MP_LSHD_C)
510 #define BN_MP_GROW_C
511 #define BN_MP_RSHD_C
512 #endif
513
514 #if defined(BN_MP_MOD_C)
515 #define BN_MP_INIT_C
516 #define BN_MP_DIV_C
517 #define BN_MP_CLEAR_C
518 #define BN_MP_ADD_C
519 #define BN_MP_EXCH_C
520 #endif
521
522 #if defined(BN_MP_MOD_2D_C)
523 #define BN_MP_ZERO_C
524 #define BN_MP_COPY_C
525 #define BN_MP_CLAMP_C
526 #endif
527
528 #if defined(BN_MP_MOD_D_C)
529 #define BN_MP_DIV_D_C
530 #endif
531
532 #if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
533 #define BN_MP_COUNT_BITS_C
534 #define BN_MP_2EXPT_C
535 #define BN_MP_SET_C
536 #define BN_MP_MUL_2_C
537 #define BN_MP_CMP_MAG_C
538 #define BN_S_MP_SUB_C
539 #endif
540
541 #if defined(BN_MP_MONTGOMERY_REDUCE_C)
542 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
543 #define BN_MP_GROW_C
544 #define BN_MP_CLAMP_C
545 #define BN_MP_RSHD_C
546 #define BN_MP_CMP_MAG_C
547 #define BN_S_MP_SUB_C
548 #endif
549
550 #if defined(BN_MP_MONTGOMERY_SETUP_C)
551 #endif
552
553 #if defined(BN_MP_MUL_C)
554 #define BN_MP_TOOM_MUL_C
555 #define BN_MP_KARATSUBA_MUL_C
556 #define BN_FAST_S_MP_MUL_DIGS_C
557 #define BN_S_MP_MUL_C
558 #define BN_S_MP_MUL_DIGS_C
559 #endif
560
561 #if defined(BN_MP_MUL_2_C)
562 #define BN_MP_GROW_C
563 #endif
564
565 #if defined(BN_MP_MUL_2D_C)
566 #define BN_MP_COPY_C
567 #define BN_MP_GROW_C
568 #define BN_MP_LSHD_C
569 #define BN_MP_CLAMP_C
570 #endif
571
572 #if defined(BN_MP_MUL_D_C)
573 #define BN_MP_GROW_C
574 #define BN_MP_CLAMP_C
575 #endif
576
577 #if defined(BN_MP_MULMOD_C)
578 #define BN_MP_INIT_C
579 #define BN_MP_MUL_C
580 #define BN_MP_CLEAR_C
581 #define BN_MP_MOD_C
582 #endif
583
584 #if defined(BN_MP_N_ROOT_C)
585 #define BN_MP_INIT_C
586 #define BN_MP_SET_C
587 #define BN_MP_COPY_C
588 #define BN_MP_EXPT_D_C
589 #define BN_MP_MUL_C
590 #define BN_MP_SUB_C
591 #define BN_MP_MUL_D_C
592 #define BN_MP_DIV_C
593 #define BN_MP_CMP_C
594 #define BN_MP_SUB_D_C
595 #define BN_MP_EXCH_C
596 #define BN_MP_CLEAR_C
597 #endif
598
599 #if defined(BN_MP_NEG_C)
600 #define BN_MP_COPY_C
601 #define BN_MP_ISZERO_C
602 #endif
603
604 #if defined(BN_MP_OR_C)
605 #define BN_MP_INIT_COPY_C
606 #define BN_MP_CLAMP_C
607 #define BN_MP_EXCH_C
608 #define BN_MP_CLEAR_C
609 #endif
610
611 #if defined(BN_MP_PRIME_FERMAT_C)
612 #define BN_MP_CMP_D_C
613 #define BN_MP_INIT_C
614 #define BN_MP_EXPTMOD_C
615 #define BN_MP_CMP_C
616 #define BN_MP_CLEAR_C
617 #endif
618
619 #if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
620 #define BN_MP_MOD_D_C
621 #endif
622
623 #if defined(BN_MP_PRIME_IS_PRIME_C)
624 #define BN_MP_CMP_D_C
625 #define BN_MP_PRIME_IS_DIVISIBLE_C
626 #define BN_MP_INIT_C
627 #define BN_MP_SET_C
628 #define BN_MP_PRIME_MILLER_RABIN_C
629 #define BN_MP_CLEAR_C
630 #endif
631
632 #if defined(BN_MP_PRIME_MILLER_RABIN_C)
633 #define BN_MP_CMP_D_C
634 #define BN_MP_INIT_COPY_C
635 #define BN_MP_SUB_D_C
636 #define BN_MP_CNT_LSB_C
637 #define BN_MP_DIV_2D_C
638 #define BN_MP_EXPTMOD_C
639 #define BN_MP_CMP_C
640 #define BN_MP_SQRMOD_C
641 #define BN_MP_CLEAR_C
642 #endif
643
644 #if defined(BN_MP_PRIME_NEXT_PRIME_C)
645 #define BN_MP_CMP_D_C
646 #define BN_MP_SET_C
647 #define BN_MP_SUB_D_C
648 #define BN_MP_ISEVEN_C
649 #define BN_MP_MOD_D_C
650 #define BN_MP_INIT_C
651 #define BN_MP_ADD_D_C
652 #define BN_MP_PRIME_MILLER_RABIN_C
653 #define BN_MP_CLEAR_C
654 #endif
655
656 #if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
657 #endif
658
659 #if defined(BN_MP_PRIME_RANDOM_EX_C)
660 #define BN_MP_READ_UNSIGNED_BIN_C
661 #define BN_MP_PRIME_IS_PRIME_C
662 #define BN_MP_SUB_D_C
663 #define BN_MP_DIV_2_C
664 #define BN_MP_MUL_2_C
665 #define BN_MP_ADD_D_C
666 #endif
667
668 #if defined(BN_MP_RADIX_SIZE_C)
669 #define BN_MP_COUNT_BITS_C
670 #define BN_MP_INIT_COPY_C
671 #define BN_MP_ISZERO_C
672 #define BN_MP_DIV_D_C
673 #define BN_MP_CLEAR_C
674 #endif
675
676 #if defined(BN_MP_RADIX_SMAP_C)
677 #define BN_MP_S_RMAP_C
678 #endif
679
680 #if defined(BN_MP_RAND_C)
681 #define BN_MP_ZERO_C
682 #define BN_MP_ADD_D_C
683 #define BN_MP_LSHD_C
684 #endif
685
686 #if defined(BN_MP_READ_RADIX_C)
687 #define BN_MP_ZERO_C
688 #define BN_MP_S_RMAP_C
689 #define BN_MP_RADIX_SMAP_C
690 #define BN_MP_MUL_D_C
691 #define BN_MP_ADD_D_C
692 #define BN_MP_ISZERO_C
693 #endif
694
695 #if defined(BN_MP_READ_SIGNED_BIN_C)
696 #define BN_MP_READ_UNSIGNED_BIN_C
697 #endif
698
699 #if defined(BN_MP_READ_UNSIGNED_BIN_C)
700 #define BN_MP_GROW_C
701 #define BN_MP_ZERO_C
702 #define BN_MP_MUL_2D_C
703 #define BN_MP_CLAMP_C
704 #endif
705
706 #if defined(BN_MP_REDUCE_C)
707 #define BN_MP_REDUCE_SETUP_C
708 #define BN_MP_INIT_COPY_C
709 #define BN_MP_RSHD_C
710 #define BN_MP_MUL_C
711 #define BN_S_MP_MUL_HIGH_DIGS_C
712 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
713 #define BN_MP_MOD_2D_C
714 #define BN_S_MP_MUL_DIGS_C
715 #define BN_MP_SUB_C
716 #define BN_MP_CMP_D_C
717 #define BN_MP_SET_C
718 #define BN_MP_LSHD_C
719 #define BN_MP_ADD_C
720 #define BN_MP_CMP_C
721 #define BN_S_MP_SUB_C
722 #define BN_MP_CLEAR_C
723 #endif
724
725 #if defined(BN_MP_REDUCE_2K_C)
726 #define BN_MP_INIT_C
727 #define BN_MP_COUNT_BITS_C
728 #define BN_MP_DIV_2D_C
729 #define BN_MP_MUL_D_C
730 #define BN_S_MP_ADD_C
731 #define BN_MP_CMP_MAG_C
732 #define BN_S_MP_SUB_C
733 #define BN_MP_CLEAR_C
734 #endif
735
736 #if defined(BN_MP_REDUCE_2K_L_C)
737 #define BN_MP_INIT_C
738 #define BN_MP_COUNT_BITS_C
739 #define BN_MP_DIV_2D_C
740 #define BN_MP_MUL_C
741 #define BN_S_MP_ADD_C
742 #define BN_MP_CMP_MAG_C
743 #define BN_S_MP_SUB_C
744 #define BN_MP_CLEAR_C
745 #endif
746
747 #if defined(BN_MP_REDUCE_2K_SETUP_C)
748 #define BN_MP_INIT_C
749 #define BN_MP_COUNT_BITS_C
750 #define BN_MP_2EXPT_C
751 #define BN_MP_CLEAR_C
752 #define BN_S_MP_SUB_C
753 #endif
754
755 #if defined(BN_MP_REDUCE_2K_SETUP_L_C)
756 #define BN_MP_INIT_C
757 #define BN_MP_2EXPT_C
758 #define BN_MP_COUNT_BITS_C
759 #define BN_S_MP_SUB_C
760 #define BN_MP_CLEAR_C
761 #endif
762
763 #if defined(BN_MP_REDUCE_IS_2K_C)
764 #define BN_MP_REDUCE_2K_C
765 #define BN_MP_COUNT_BITS_C
766 #endif
767
768 #if defined(BN_MP_REDUCE_IS_2K_L_C)
769 #endif
770
771 #if defined(BN_MP_REDUCE_SETUP_C)
772 #define BN_MP_2EXPT_C
773 #define BN_MP_DIV_C
774 #endif
775
776 #if defined(BN_MP_RSHD_C)
777 #define BN_MP_ZERO_C
778 #endif
779
780 #if defined(BN_MP_SET_C)
781 #define BN_MP_ZERO_C
782 #endif
783
784 #if defined(BN_MP_SET_INT_C)
785 #define BN_MP_ZERO_C
786 #define BN_MP_MUL_2D_C
787 #define BN_MP_CLAMP_C
788 #endif
789
790 #if defined(BN_MP_SHRINK_C)
791 #endif
792
793 #if defined(BN_MP_SIGNED_BIN_SIZE_C)
794 #define BN_MP_UNSIGNED_BIN_SIZE_C
795 #endif
796
797 #if defined(BN_MP_SQR_C)
798 #define BN_MP_TOOM_SQR_C
799 #define BN_MP_KARATSUBA_SQR_C
800 #define BN_FAST_S_MP_SQR_C
801 #define BN_S_MP_SQR_C
802 #endif
803
804 #if defined(BN_MP_SQRMOD_C)
805 #define BN_MP_INIT_C
806 #define BN_MP_SQR_C
807 #define BN_MP_CLEAR_C
808 #define BN_MP_MOD_C
809 #endif
810
811 #if defined(BN_MP_SQRT_C)
812 #define BN_MP_N_ROOT_C
813 #define BN_MP_ISZERO_C
814 #define BN_MP_ZERO_C
815 #define BN_MP_INIT_COPY_C
816 #define BN_MP_RSHD_C
817 #define BN_MP_DIV_C
818 #define BN_MP_ADD_C
819 #define BN_MP_DIV_2_C
820 #define BN_MP_CMP_MAG_C
821 #define BN_MP_EXCH_C
822 #define BN_MP_CLEAR_C
823 #endif
824
825 #if defined(BN_MP_SUB_C)
826 #define BN_S_MP_ADD_C
827 #define BN_MP_CMP_MAG_C
828 #define BN_S_MP_SUB_C
829 #endif
830
831 #if defined(BN_MP_SUB_D_C)
832 #define BN_MP_GROW_C
833 #define BN_MP_ADD_D_C
834 #define BN_MP_CLAMP_C
835 #endif
836
837 #if defined(BN_MP_SUBMOD_C)
838 #define BN_MP_INIT_C
839 #define BN_MP_SUB_C
840 #define BN_MP_CLEAR_C
841 #define BN_MP_MOD_C
842 #endif
843
844 #if defined(BN_MP_TO_SIGNED_BIN_C)
845 #define BN_MP_TO_UNSIGNED_BIN_C
846 #endif
847
848 #if defined(BN_MP_TO_SIGNED_BIN_N_C)
849 #define BN_MP_SIGNED_BIN_SIZE_C
850 #define BN_MP_TO_SIGNED_BIN_C
851 #endif
852
853 #if defined(BN_MP_TO_UNSIGNED_BIN_C)
854 #define BN_MP_INIT_COPY_C
855 #define BN_MP_ISZERO_C
856 #define BN_MP_DIV_2D_C
857 #define BN_MP_CLEAR_C
858 #endif
859
860 #if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
861 #define BN_MP_UNSIGNED_BIN_SIZE_C
862 #define BN_MP_TO_UNSIGNED_BIN_C
863 #endif
864
865 #if defined(BN_MP_TOOM_MUL_C)
866 #define BN_MP_INIT_MULTI_C
867 #define BN_MP_MOD_2D_C
868 #define BN_MP_COPY_C
869 #define BN_MP_RSHD_C
870 #define BN_MP_MUL_C
871 #define BN_MP_MUL_2_C
872 #define BN_MP_ADD_C
873 #define BN_MP_SUB_C
874 #define BN_MP_DIV_2_C
875 #define BN_MP_MUL_2D_C
876 #define BN_MP_MUL_D_C
877 #define BN_MP_DIV_3_C
878 #define BN_MP_LSHD_C
879 #define BN_MP_CLEAR_MULTI_C
880 #endif
881
882 #if defined(BN_MP_TOOM_SQR_C)
883 #define BN_MP_INIT_MULTI_C
884 #define BN_MP_MOD_2D_C
885 #define BN_MP_COPY_C
886 #define BN_MP_RSHD_C
887 #define BN_MP_SQR_C
888 #define BN_MP_MUL_2_C
889 #define BN_MP_ADD_C
890 #define BN_MP_SUB_C
891 #define BN_MP_DIV_2_C
892 #define BN_MP_MUL_2D_C
893 #define BN_MP_MUL_D_C
894 #define BN_MP_DIV_3_C
895 #define BN_MP_LSHD_C
896 #define BN_MP_CLEAR_MULTI_C
897 #endif
898
899 #if defined(BN_MP_TORADIX_C)
900 #define BN_MP_ISZERO_C
901 #define BN_MP_INIT_COPY_C
902 #define BN_MP_DIV_D_C
903 #define BN_MP_CLEAR_C
904 #define BN_MP_S_RMAP_C
905 #endif
906
907 #if defined(BN_MP_TORADIX_N_C)
908 #define BN_MP_ISZERO_C
909 #define BN_MP_INIT_COPY_C
910 #define BN_MP_DIV_D_C
911 #define BN_MP_CLEAR_C
912 #define BN_MP_S_RMAP_C
913 #endif
914
915 #if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
916 #define BN_MP_COUNT_BITS_C
917 #endif
918
919 #if defined(BN_MP_XOR_C)
920 #define BN_MP_INIT_COPY_C
921 #define BN_MP_CLAMP_C
922 #define BN_MP_EXCH_C
923 #define BN_MP_CLEAR_C
924 #endif
925
926 #if defined(BN_MP_ZERO_C)
927 #endif
928
929 #if defined(BN_PRIME_TAB_C)
930 #endif
931
932 #if defined(BN_REVERSE_C)
933 #endif
934
935 #if defined(BN_S_MP_ADD_C)
936 #define BN_MP_GROW_C
937 #define BN_MP_CLAMP_C
938 #endif
939
940 #if defined(BN_S_MP_EXPTMOD_C)
941 #define BN_MP_COUNT_BITS_C
942 #define BN_MP_INIT_C
943 #define BN_MP_CLEAR_C
944 #define BN_MP_REDUCE_SETUP_C
945 #define BN_MP_REDUCE_C
946 #define BN_MP_REDUCE_2K_SETUP_L_C
947 #define BN_MP_REDUCE_2K_L_C
948 #define BN_MP_MOD_C
949 #define BN_MP_COPY_C
950 #define BN_MP_SQR_C
951 #define BN_MP_MUL_C
952 #define BN_MP_SET_C
953 #define BN_MP_EXCH_C
954 #endif
955
956 #if defined(BN_S_MP_MUL_DIGS_C)
957 #define BN_FAST_S_MP_MUL_DIGS_C
958 #define BN_MP_INIT_SIZE_C
959 #define BN_MP_CLAMP_C
960 #define BN_MP_EXCH_C
961 #define BN_MP_CLEAR_C
962 #endif
963
964 #if defined(BN_S_MP_MUL_HIGH_DIGS_C)
965 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
966 #define BN_MP_INIT_SIZE_C
967 #define BN_MP_CLAMP_C
968 #define BN_MP_EXCH_C
969 #define BN_MP_CLEAR_C
970 #endif
971
972 #if defined(BN_S_MP_SQR_C)
973 #define BN_MP_INIT_SIZE_C
974 #define BN_MP_CLAMP_C
975 #define BN_MP_EXCH_C
976 #define BN_MP_CLEAR_C
977 #endif
978
979 #if defined(BN_S_MP_SUB_C)
980 #define BN_MP_GROW_C
981 #define BN_MP_CLAMP_C
982 #endif
983
984 #if defined(BNCORE_C)
985 #endif
986
987 #ifdef LTM3
988 #define LTM_LAST
989 #endif
990 #include <tommath_superclass.h>
991 #include <tommath_class.h>
992 #else
993 #define LTM_LAST
994 #endif
995
996 /* $Source$ */
997 /* $Revision$ */
998 /* $Date$ */
+0
-76
libtom-src/tommath_superclass.h less more
0 /* super class file for PK algos */
1
2 /* default ... include all MPI */
3 #define LTM_ALL
4
5 /* RSA only (does not support DH/DSA/ECC) */
6 /* #define SC_RSA_1 */
7
8 /* For reference.... On an Athlon64 optimizing for speed...
9
10 LTM's mpi.o with all functions [striped] is 142KiB in size.
11
12 */
13
14 /* Works for RSA only, mpi.o is 68KiB */
15 #ifdef SC_RSA_1
16 #define BN_MP_SHRINK_C
17 #define BN_MP_LCM_C
18 #define BN_MP_PRIME_RANDOM_EX_C
19 #define BN_MP_INVMOD_C
20 #define BN_MP_GCD_C
21 #define BN_MP_MOD_C
22 #define BN_MP_MULMOD_C
23 #define BN_MP_ADDMOD_C
24 #define BN_MP_EXPTMOD_C
25 #define BN_MP_SET_INT_C
26 #define BN_MP_INIT_MULTI_C
27 #define BN_MP_CLEAR_MULTI_C
28 #define BN_MP_UNSIGNED_BIN_SIZE_C
29 #define BN_MP_TO_UNSIGNED_BIN_C
30 #define BN_MP_MOD_D_C
31 #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
32 #define BN_REVERSE_C
33 #define BN_PRIME_TAB_C
34
35 /* other modifiers */
36 #define BN_MP_DIV_SMALL /* Slower division, not critical */
37
38 /* here we are on the last pass so we turn things off. The functions classes are still there
39 * but we remove them specifically from the build. This also invokes tweaks in functions
40 * like removing support for even moduli, etc...
41 */
42 #ifdef LTM_LAST
43 #undef BN_MP_TOOM_MUL_C
44 #undef BN_MP_TOOM_SQR_C
45 #undef BN_MP_KARATSUBA_MUL_C
46 #undef BN_MP_KARATSUBA_SQR_C
47 #undef BN_MP_REDUCE_C
48 #undef BN_MP_REDUCE_SETUP_C
49 #undef BN_MP_DR_IS_MODULUS_C
50 #undef BN_MP_DR_SETUP_C
51 #undef BN_MP_DR_REDUCE_C
52 #undef BN_MP_REDUCE_IS_2K_C
53 #undef BN_MP_REDUCE_2K_SETUP_C
54 #undef BN_MP_REDUCE_2K_C
55 #undef BN_S_MP_EXPTMOD_C
56 #undef BN_MP_DIV_3_C
57 #undef BN_S_MP_MUL_HIGH_DIGS_C
58 #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
59 #undef BN_FAST_MP_INVMOD_C
60
61 /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
62 * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
63 * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
64 * trouble.
65 */
66 #undef BN_S_MP_MUL_DIGS_C
67 #undef BN_S_MP_SQR_C
68 #undef BN_MP_MONTGOMERY_REDUCE_C
69 #endif
70
71 #endif
72
73 /* $Source$ */
74 /* $Revision$ */
75 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* AES implementation by Tom St Denis
12 *
13 * Derived from the Public Domain source code by
14
15 ---
16 * rijndael-alg-fst.c
17 *
18 * @version 3.0 (December 2000)
19 *
20 * Optimised ANSI C code for the Rijndael cipher (now AES)
21 *
22 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
23 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
24 * @author Paulo Barreto <paulo.barreto@terra.com.br>
25 ---
26 */
27 /**
28 @file aes.c
29 Implementation of AES
30 */
31
32 #include "tomcrypt.h"
33
34 #ifdef LTC_RIJNDAEL
35
36 #ifndef ENCRYPT_ONLY
37
38 #define SETUP rijndael_setup
39 #define ECB_ENC rijndael_ecb_encrypt
40 #define ECB_DEC rijndael_ecb_decrypt
41 #define ECB_DONE rijndael_done
42 #define ECB_TEST rijndael_test
43 #define ECB_KS rijndael_keysize
44
45 const struct ltc_cipher_descriptor rijndael_desc =
46 {
47 "rijndael",
48 6,
49 16, 32, 16, 10,
50 SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
51 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
52 };
53
54 const struct ltc_cipher_descriptor aes_desc =
55 {
56 "aes",
57 6,
58 16, 32, 16, 10,
59 SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
60 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
61 };
62
63 #else
64
65 #define SETUP rijndael_enc_setup
66 #define ECB_ENC rijndael_enc_ecb_encrypt
67 #define ECB_KS rijndael_enc_keysize
68 #define ECB_DONE rijndael_enc_done
69
70 const struct ltc_cipher_descriptor rijndael_enc_desc =
71 {
72 "rijndael",
73 6,
74 16, 32, 16, 10,
75 SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
76 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
77 };
78
79 const struct ltc_cipher_descriptor aes_enc_desc =
80 {
81 "aes",
82 6,
83 16, 32, 16, 10,
84 SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
85 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
86 };
87
88 #endif
89
90 #include "aes_tab.c.inc"
91
92 static ulong32 setup_mix(ulong32 temp)
93 {
94 return (Te4_3[byte(temp, 2)]) ^
95 (Te4_2[byte(temp, 1)]) ^
96 (Te4_1[byte(temp, 0)]) ^
97 (Te4_0[byte(temp, 3)]);
98 }
99
100 #ifndef ENCRYPT_ONLY
101 #ifdef LTC_SMALL_CODE
102 static ulong32 setup_mix2(ulong32 temp)
103 {
104 return Td0(255 & Te4[byte(temp, 3)]) ^
105 Td1(255 & Te4[byte(temp, 2)]) ^
106 Td2(255 & Te4[byte(temp, 1)]) ^
107 Td3(255 & Te4[byte(temp, 0)]);
108 }
109 #endif
110 #endif
111
112 /**
113 Initialize the AES (Rijndael) block cipher
114 @param key The symmetric key you wish to pass
115 @param keylen The key length in bytes
116 @param num_rounds The number of rounds desired (0 for default)
117 @param skey The key in as scheduled by this function.
118 @return CRYPT_OK if successful
119 */
120 int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
121 {
122 int i, j;
123 ulong32 temp, *rk;
124 #ifndef ENCRYPT_ONLY
125 ulong32 *rrk;
126 #endif
127 LTC_ARGCHK(key != NULL);
128 LTC_ARGCHK(skey != NULL);
129
130 if (keylen != 16 && keylen != 24 && keylen != 32) {
131 return CRYPT_INVALID_KEYSIZE;
132 }
133
134 if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) {
135 return CRYPT_INVALID_ROUNDS;
136 }
137
138 skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
139
140 /* setup the forward key */
141 i = 0;
142 rk = skey->rijndael.eK;
143 LOAD32H(rk[0], key );
144 LOAD32H(rk[1], key + 4);
145 LOAD32H(rk[2], key + 8);
146 LOAD32H(rk[3], key + 12);
147 if (keylen == 16) {
148 j = 44;
149 for (;;) {
150 temp = rk[3];
151 rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
152 rk[5] = rk[1] ^ rk[4];
153 rk[6] = rk[2] ^ rk[5];
154 rk[7] = rk[3] ^ rk[6];
155 if (++i == 10) {
156 break;
157 }
158 rk += 4;
159 }
160 } else if (keylen == 24) {
161 j = 52;
162 LOAD32H(rk[4], key + 16);
163 LOAD32H(rk[5], key + 20);
164 for (;;) {
165 #ifdef _MSC_VER
166 temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
167 #else
168 temp = rk[5];
169 #endif
170 rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
171 rk[ 7] = rk[ 1] ^ rk[ 6];
172 rk[ 8] = rk[ 2] ^ rk[ 7];
173 rk[ 9] = rk[ 3] ^ rk[ 8];
174 if (++i == 8) {
175 break;
176 }
177 rk[10] = rk[ 4] ^ rk[ 9];
178 rk[11] = rk[ 5] ^ rk[10];
179 rk += 6;
180 }
181 } else if (keylen == 32) {
182 j = 60;
183 LOAD32H(rk[4], key + 16);
184 LOAD32H(rk[5], key + 20);
185 LOAD32H(rk[6], key + 24);
186 LOAD32H(rk[7], key + 28);
187 for (;;) {
188 #ifdef _MSC_VER
189 temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
190 #else
191 temp = rk[7];
192 #endif
193 rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
194 rk[ 9] = rk[ 1] ^ rk[ 8];
195 rk[10] = rk[ 2] ^ rk[ 9];
196 rk[11] = rk[ 3] ^ rk[10];
197 if (++i == 7) {
198 break;
199 }
200 temp = rk[11];
201 rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8));
202 rk[13] = rk[ 5] ^ rk[12];
203 rk[14] = rk[ 6] ^ rk[13];
204 rk[15] = rk[ 7] ^ rk[14];
205 rk += 8;
206 }
207 } else {
208 /* this can't happen */
209 return CRYPT_ERROR;
210 }
211
212 #ifndef ENCRYPT_ONLY
213 /* setup the inverse key now */
214 rk = skey->rijndael.dK;
215 rrk = skey->rijndael.eK + j - 4;
216
217 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
218 /* copy first */
219 *rk++ = *rrk++;
220 *rk++ = *rrk++;
221 *rk++ = *rrk++;
222 *rk = *rrk;
223 rk -= 3; rrk -= 3;
224
225 for (i = 1; i < skey->rijndael.Nr; i++) {
226 rrk -= 4;
227 rk += 4;
228 #ifdef LTC_SMALL_CODE
229 temp = rrk[0];
230 rk[0] = setup_mix2(temp);
231 temp = rrk[1];
232 rk[1] = setup_mix2(temp);
233 temp = rrk[2];
234 rk[2] = setup_mix2(temp);
235 temp = rrk[3];
236 rk[3] = setup_mix2(temp);
237 #else
238 temp = rrk[0];
239 rk[0] =
240 Tks0[byte(temp, 3)] ^
241 Tks1[byte(temp, 2)] ^
242 Tks2[byte(temp, 1)] ^
243 Tks3[byte(temp, 0)];
244 temp = rrk[1];
245 rk[1] =
246 Tks0[byte(temp, 3)] ^
247 Tks1[byte(temp, 2)] ^
248 Tks2[byte(temp, 1)] ^
249 Tks3[byte(temp, 0)];
250 temp = rrk[2];
251 rk[2] =
252 Tks0[byte(temp, 3)] ^
253 Tks1[byte(temp, 2)] ^
254 Tks2[byte(temp, 1)] ^
255 Tks3[byte(temp, 0)];
256 temp = rrk[3];
257 rk[3] =
258 Tks0[byte(temp, 3)] ^
259 Tks1[byte(temp, 2)] ^
260 Tks2[byte(temp, 1)] ^
261 Tks3[byte(temp, 0)];
262 #endif
263
264 }
265
266 /* copy last */
267 rrk -= 4;
268 rk += 4;
269 *rk++ = *rrk++;
270 *rk++ = *rrk++;
271 *rk++ = *rrk++;
272 *rk = *rrk;
273 #endif /* ENCRYPT_ONLY */
274
275 return CRYPT_OK;
276 }
277
278 /**
279 Encrypts a block of text with AES
280 @param pt The input plaintext (16 bytes)
281 @param ct The output ciphertext (16 bytes)
282 @param skey The key as scheduled
283 @return CRYPT_OK if successful
284 */
285 #ifdef LTC_CLEAN_STACK
286 static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
287 #else
288 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
289 #endif
290 {
291 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
292 int Nr, r;
293
294 LTC_ARGCHK(pt != NULL);
295 LTC_ARGCHK(ct != NULL);
296 LTC_ARGCHK(skey != NULL);
297
298 Nr = skey->rijndael.Nr;
299 rk = skey->rijndael.eK;
300
301 /*
302 * map byte array block to cipher state
303 * and add initial round key:
304 */
305 LOAD32H(s0, pt ); s0 ^= rk[0];
306 LOAD32H(s1, pt + 4); s1 ^= rk[1];
307 LOAD32H(s2, pt + 8); s2 ^= rk[2];
308 LOAD32H(s3, pt + 12); s3 ^= rk[3];
309
310 #ifdef LTC_SMALL_CODE
311
312 for (r = 0; ; r++) {
313 rk += 4;
314 t0 =
315 Te0(byte(s0, 3)) ^
316 Te1(byte(s1, 2)) ^
317 Te2(byte(s2, 1)) ^
318 Te3(byte(s3, 0)) ^
319 rk[0];
320 t1 =
321 Te0(byte(s1, 3)) ^
322 Te1(byte(s2, 2)) ^
323 Te2(byte(s3, 1)) ^
324 Te3(byte(s0, 0)) ^
325 rk[1];
326 t2 =
327 Te0(byte(s2, 3)) ^
328 Te1(byte(s3, 2)) ^
329 Te2(byte(s0, 1)) ^
330 Te3(byte(s1, 0)) ^
331 rk[2];
332 t3 =
333 Te0(byte(s3, 3)) ^
334 Te1(byte(s0, 2)) ^
335 Te2(byte(s1, 1)) ^
336 Te3(byte(s2, 0)) ^
337 rk[3];
338 if (r == Nr-2) {
339 break;
340 }
341 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
342 }
343 rk += 4;
344
345 #else
346
347 /*
348 * Nr - 1 full rounds:
349 */
350 r = Nr >> 1;
351 for (;;) {
352 t0 =
353 Te0(byte(s0, 3)) ^
354 Te1(byte(s1, 2)) ^
355 Te2(byte(s2, 1)) ^
356 Te3(byte(s3, 0)) ^
357 rk[4];
358 t1 =
359 Te0(byte(s1, 3)) ^
360 Te1(byte(s2, 2)) ^
361 Te2(byte(s3, 1)) ^
362 Te3(byte(s0, 0)) ^
363 rk[5];
364 t2 =
365 Te0(byte(s2, 3)) ^
366 Te1(byte(s3, 2)) ^
367 Te2(byte(s0, 1)) ^
368 Te3(byte(s1, 0)) ^
369 rk[6];
370 t3 =
371 Te0(byte(s3, 3)) ^
372 Te1(byte(s0, 2)) ^
373 Te2(byte(s1, 1)) ^
374 Te3(byte(s2, 0)) ^
375 rk[7];
376
377 rk += 8;
378 if (--r == 0) {
379 break;
380 }
381
382 s0 =
383 Te0(byte(t0, 3)) ^
384 Te1(byte(t1, 2)) ^
385 Te2(byte(t2, 1)) ^
386 Te3(byte(t3, 0)) ^
387 rk[0];
388 s1 =
389 Te0(byte(t1, 3)) ^
390 Te1(byte(t2, 2)) ^
391 Te2(byte(t3, 1)) ^
392 Te3(byte(t0, 0)) ^
393 rk[1];
394 s2 =
395 Te0(byte(t2, 3)) ^
396 Te1(byte(t3, 2)) ^
397 Te2(byte(t0, 1)) ^
398 Te3(byte(t1, 0)) ^
399 rk[2];
400 s3 =
401 Te0(byte(t3, 3)) ^
402 Te1(byte(t0, 2)) ^
403 Te2(byte(t1, 1)) ^
404 Te3(byte(t2, 0)) ^
405 rk[3];
406 }
407
408 #endif
409
410 /*
411 * apply last round and
412 * map cipher state to byte array block:
413 */
414 s0 =
415 (Te4_3[byte(t0, 3)]) ^
416 (Te4_2[byte(t1, 2)]) ^
417 (Te4_1[byte(t2, 1)]) ^
418 (Te4_0[byte(t3, 0)]) ^
419 rk[0];
420 STORE32H(s0, ct);
421 s1 =
422 (Te4_3[byte(t1, 3)]) ^
423 (Te4_2[byte(t2, 2)]) ^
424 (Te4_1[byte(t3, 1)]) ^
425 (Te4_0[byte(t0, 0)]) ^
426 rk[1];
427 STORE32H(s1, ct+4);
428 s2 =
429 (Te4_3[byte(t2, 3)]) ^
430 (Te4_2[byte(t3, 2)]) ^
431 (Te4_1[byte(t0, 1)]) ^
432 (Te4_0[byte(t1, 0)]) ^
433 rk[2];
434 STORE32H(s2, ct+8);
435 s3 =
436 (Te4_3[byte(t3, 3)]) ^
437 (Te4_2[byte(t0, 2)]) ^
438 (Te4_1[byte(t1, 1)]) ^
439 (Te4_0[byte(t2, 0)]) ^
440 rk[3];
441 STORE32H(s3, ct+12);
442
443 return CRYPT_OK;
444 }
445
446 #ifdef LTC_CLEAN_STACK
447 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
448 {
449 int err = _rijndael_ecb_encrypt(pt, ct, skey);
450 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
451 return err;
452 }
453 #endif
454
455 #ifndef ENCRYPT_ONLY
456
457 /**
458 Decrypts a block of text with AES
459 @param ct The input ciphertext (16 bytes)
460 @param pt The output plaintext (16 bytes)
461 @param skey The key as scheduled
462 @return CRYPT_OK if successful
463 */
464 #ifdef LTC_CLEAN_STACK
465 static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
466 #else
467 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
468 #endif
469 {
470 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
471 int Nr, r;
472
473 LTC_ARGCHK(pt != NULL);
474 LTC_ARGCHK(ct != NULL);
475 LTC_ARGCHK(skey != NULL);
476
477 Nr = skey->rijndael.Nr;
478 rk = skey->rijndael.dK;
479
480 /*
481 * map byte array block to cipher state
482 * and add initial round key:
483 */
484 LOAD32H(s0, ct ); s0 ^= rk[0];
485 LOAD32H(s1, ct + 4); s1 ^= rk[1];
486 LOAD32H(s2, ct + 8); s2 ^= rk[2];
487 LOAD32H(s3, ct + 12); s3 ^= rk[3];
488
489 #ifdef LTC_SMALL_CODE
490 for (r = 0; ; r++) {
491 rk += 4;
492 t0 =
493 Td0(byte(s0, 3)) ^
494 Td1(byte(s3, 2)) ^
495 Td2(byte(s2, 1)) ^
496 Td3(byte(s1, 0)) ^
497 rk[0];
498 t1 =
499 Td0(byte(s1, 3)) ^
500 Td1(byte(s0, 2)) ^
501 Td2(byte(s3, 1)) ^
502 Td3(byte(s2, 0)) ^
503 rk[1];
504 t2 =
505 Td0(byte(s2, 3)) ^
506 Td1(byte(s1, 2)) ^
507 Td2(byte(s0, 1)) ^
508 Td3(byte(s3, 0)) ^
509 rk[2];
510 t3 =
511 Td0(byte(s3, 3)) ^
512 Td1(byte(s2, 2)) ^
513 Td2(byte(s1, 1)) ^
514 Td3(byte(s0, 0)) ^
515 rk[3];
516 if (r == Nr-2) {
517 break;
518 }
519 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
520 }
521 rk += 4;
522
523 #else
524
525 /*
526 * Nr - 1 full rounds:
527 */
528 r = Nr >> 1;
529 for (;;) {
530
531 t0 =
532 Td0(byte(s0, 3)) ^
533 Td1(byte(s3, 2)) ^
534 Td2(byte(s2, 1)) ^
535 Td3(byte(s1, 0)) ^
536 rk[4];
537 t1 =
538 Td0(byte(s1, 3)) ^
539 Td1(byte(s0, 2)) ^
540 Td2(byte(s3, 1)) ^
541 Td3(byte(s2, 0)) ^
542 rk[5];
543 t2 =
544 Td0(byte(s2, 3)) ^
545 Td1(byte(s1, 2)) ^
546 Td2(byte(s0, 1)) ^
547 Td3(byte(s3, 0)) ^
548 rk[6];
549 t3 =
550 Td0(byte(s3, 3)) ^
551 Td1(byte(s2, 2)) ^
552 Td2(byte(s1, 1)) ^
553 Td3(byte(s0, 0)) ^
554 rk[7];
555
556 rk += 8;
557 if (--r == 0) {
558 break;
559 }
560
561
562 s0 =
563 Td0(byte(t0, 3)) ^
564 Td1(byte(t3, 2)) ^
565 Td2(byte(t2, 1)) ^
566 Td3(byte(t1, 0)) ^
567 rk[0];
568 s1 =
569 Td0(byte(t1, 3)) ^
570 Td1(byte(t0, 2)) ^
571 Td2(byte(t3, 1)) ^
572 Td3(byte(t2, 0)) ^
573 rk[1];
574 s2 =
575 Td0(byte(t2, 3)) ^
576 Td1(byte(t1, 2)) ^
577 Td2(byte(t0, 1)) ^
578 Td3(byte(t3, 0)) ^
579 rk[2];
580 s3 =
581 Td0(byte(t3, 3)) ^
582 Td1(byte(t2, 2)) ^
583 Td2(byte(t1, 1)) ^
584 Td3(byte(t0, 0)) ^
585 rk[3];
586 }
587 #endif
588
589 /*
590 * apply last round and
591 * map cipher state to byte array block:
592 */
593 s0 =
594 (Td4[byte(t0, 3)] & 0xff000000) ^
595 (Td4[byte(t3, 2)] & 0x00ff0000) ^
596 (Td4[byte(t2, 1)] & 0x0000ff00) ^
597 (Td4[byte(t1, 0)] & 0x000000ff) ^
598 rk[0];
599 STORE32H(s0, pt);
600 s1 =
601 (Td4[byte(t1, 3)] & 0xff000000) ^
602 (Td4[byte(t0, 2)] & 0x00ff0000) ^
603 (Td4[byte(t3, 1)] & 0x0000ff00) ^
604 (Td4[byte(t2, 0)] & 0x000000ff) ^
605 rk[1];
606 STORE32H(s1, pt+4);
607 s2 =
608 (Td4[byte(t2, 3)] & 0xff000000) ^
609 (Td4[byte(t1, 2)] & 0x00ff0000) ^
610 (Td4[byte(t0, 1)] & 0x0000ff00) ^
611 (Td4[byte(t3, 0)] & 0x000000ff) ^
612 rk[2];
613 STORE32H(s2, pt+8);
614 s3 =
615 (Td4[byte(t3, 3)] & 0xff000000) ^
616 (Td4[byte(t2, 2)] & 0x00ff0000) ^
617 (Td4[byte(t1, 1)] & 0x0000ff00) ^
618 (Td4[byte(t0, 0)] & 0x000000ff) ^
619 rk[3];
620 STORE32H(s3, pt+12);
621
622 return CRYPT_OK;
623 }
624
625
626 #ifdef LTC_CLEAN_STACK
627 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
628 {
629 int err = _rijndael_ecb_decrypt(ct, pt, skey);
630 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
631 return err;
632 }
633 #endif
634
635 /**
636 Performs a self-test of the AES block cipher
637 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
638 */
639 int ECB_TEST(void)
640 {
641 #ifndef LTC_TEST
642 return CRYPT_NOP;
643 #else
644 int err;
645 static const struct {
646 int keylen;
647 unsigned char key[32], pt[16], ct[16];
648 } tests[] = {
649 { 16,
650 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
651 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
652 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
653 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
654 { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
655 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
656 }, {
657 24,
658 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
659 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
660 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
661 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
662 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
663 { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
664 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
665 }, {
666 32,
667 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
668 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
669 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
670 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
671 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
672 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
673 { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
674 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
675 }
676 };
677
678 symmetric_key key;
679 unsigned char tmp[2][16];
680 int i, y;
681
682 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
683 zeromem(&key, sizeof(key));
684 if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
685 return err;
686 }
687
688 rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
689 rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
690 if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
691 #if 0
692 printf("\n\nTest %d failed\n", i);
693 if (XMEMCMP(tmp[0], tests[i].ct, 16)) {
694 printf("CT: ");
695 for (i = 0; i < 16; i++) {
696 printf("%02x ", tmp[0][i]);
697 }
698 printf("\n");
699 } else {
700 printf("PT: ");
701 for (i = 0; i < 16; i++) {
702 printf("%02x ", tmp[1][i]);
703 }
704 printf("\n");
705 }
706 #endif
707 return CRYPT_FAIL_TESTVECTOR;
708 }
709
710 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
711 for (y = 0; y < 16; y++) tmp[0][y] = 0;
712 for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
713 for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
714 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
715 }
716 return CRYPT_OK;
717 #endif
718 }
719
720 #endif /* ENCRYPT_ONLY */
721
722
723 /** Terminate the context
724 @param skey The scheduled key
725 */
726 void ECB_DONE(symmetric_key *skey)
727 {
728 }
729
730
731 /**
732 Gets suitable key size
733 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
734 @return CRYPT_OK if the input key size is acceptable.
735 */
736 int ECB_KS(int *keysize)
737 {
738 LTC_ARGCHK(keysize != NULL);
739
740 if (*keysize < 16)
741 return CRYPT_INVALID_KEYSIZE;
742 if (*keysize < 24) {
743 *keysize = 16;
744 return CRYPT_OK;
745 } else if (*keysize < 32) {
746 *keysize = 24;
747 return CRYPT_OK;
748 } else {
749 *keysize = 32;
750 return CRYPT_OK;
751 }
752 }
753
754 #endif
755
756
757 /* $Source$ */
758 /* $Revision$ */
759 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /* The precomputed tables for AES */
11 /*
12 Te0[x] = S [x].[02, 01, 01, 03];
13 Te1[x] = S [x].[03, 02, 01, 01];
14 Te2[x] = S [x].[01, 03, 02, 01];
15 Te3[x] = S [x].[01, 01, 03, 02];
16 Te4[x] = S [x].[01, 01, 01, 01];
17
18 Td0[x] = Si[x].[0e, 09, 0d, 0b];
19 Td1[x] = Si[x].[0b, 0e, 09, 0d];
20 Td2[x] = Si[x].[0d, 0b, 0e, 09];
21 Td3[x] = Si[x].[09, 0d, 0b, 0e];
22 Td4[x] = Si[x].[01, 01, 01, 01];
23 */
24
25 /**
26 @file aes_tab.c
27 AES tables
28 */
29 static const ulong32 TE0[256] = {
30 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
31 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
32 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
33 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
34 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL,
35 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
36 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL,
37 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
38 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL,
39 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
40 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL,
41 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
42 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL,
43 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
44 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL,
45 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
46 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL,
47 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
48 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL,
49 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
50 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL,
51 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
52 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL,
53 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
54 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL,
55 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
56 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL,
57 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
58 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL,
59 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
60 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL,
61 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
62 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL,
63 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
64 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL,
65 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
66 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL,
67 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
68 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL,
69 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
70 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL,
71 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
72 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL,
73 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
74 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL,
75 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
76 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL,
77 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
78 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL,
79 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
80 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL,
81 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
82 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL,
83 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
84 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL,
85 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
86 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL,
87 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
88 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL,
89 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
90 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL,
91 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
92 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL,
93 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL,
94 };
95
96 #ifndef PELI_TAB
97 static const ulong32 Te4[256] = {
98 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL,
99 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL,
100 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL,
101 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL,
102 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL,
103 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL,
104 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL,
105 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL,
106 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL,
107 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL,
108 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL,
109 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL,
110 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL,
111 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL,
112 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL,
113 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL,
114 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL,
115 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL,
116 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL,
117 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL,
118 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL,
119 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL,
120 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL,
121 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL,
122 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL,
123 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL,
124 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL,
125 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL,
126 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL,
127 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL,
128 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL,
129 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL,
130 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL,
131 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL,
132 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL,
133 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL,
134 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL,
135 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL,
136 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL,
137 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL,
138 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL,
139 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL,
140 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL,
141 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL,
142 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL,
143 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL,
144 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL,
145 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL,
146 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL,
147 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL,
148 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL,
149 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL,
150 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL,
151 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL,
152 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL,
153 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL,
154 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL,
155 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL,
156 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL,
157 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL,
158 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL,
159 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL,
160 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL,
161 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL,
162 };
163 #endif
164
165 #ifndef ENCRYPT_ONLY
166
167 static const ulong32 TD0[256] = {
168 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
169 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
170 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL,
171 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL,
172 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL,
173 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL,
174 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL,
175 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL,
176 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL,
177 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL,
178 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL,
179 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL,
180 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL,
181 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL,
182 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL,
183 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL,
184 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL,
185 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL,
186 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL,
187 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL,
188 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL,
189 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL,
190 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL,
191 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL,
192 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL,
193 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL,
194 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL,
195 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL,
196 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL,
197 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL,
198 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL,
199 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL,
200 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL,
201 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL,
202 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL,
203 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL,
204 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL,
205 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL,
206 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL,
207 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL,
208 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL,
209 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL,
210 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL,
211 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL,
212 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL,
213 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL,
214 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL,
215 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL,
216 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL,
217 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL,
218 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL,
219 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL,
220 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL,
221 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL,
222 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL,
223 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL,
224 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL,
225 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL,
226 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL,
227 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL,
228 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL,
229 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL,
230 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL,
231 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL,
232 };
233
234 static const ulong32 Td4[256] = {
235 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL,
236 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL,
237 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL,
238 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL,
239 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL,
240 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL,
241 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL,
242 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL,
243 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL,
244 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL,
245 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL,
246 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL,
247 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL,
248 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL,
249 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL,
250 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL,
251 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL,
252 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL,
253 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL,
254 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL,
255 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL,
256 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL,
257 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL,
258 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL,
259 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL,
260 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL,
261 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL,
262 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL,
263 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL,
264 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL,
265 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL,
266 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL,
267 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL,
268 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL,
269 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL,
270 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL,
271 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL,
272 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL,
273 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL,
274 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL,
275 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL,
276 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL,
277 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL,
278 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL,
279 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL,
280 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL,
281 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL,
282 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL,
283 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL,
284 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL,
285 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL,
286 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL,
287 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL,
288 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL,
289 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL,
290 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL,
291 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL,
292 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL,
293 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL,
294 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL,
295 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL,
296 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL,
297 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL,
298 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL,
299 };
300
301 #endif /* ENCRYPT_ONLY */
302
303 #ifdef LTC_SMALL_CODE
304
305 #define Te0(x) TE0[x]
306 #define Te1(x) RORc(TE0[x], 8)
307 #define Te2(x) RORc(TE0[x], 16)
308 #define Te3(x) RORc(TE0[x], 24)
309
310 #define Td0(x) TD0[x]
311 #define Td1(x) RORc(TD0[x], 8)
312 #define Td2(x) RORc(TD0[x], 16)
313 #define Td3(x) RORc(TD0[x], 24)
314
315 #define Te4_0 0x000000FF & Te4
316 #define Te4_1 0x0000FF00 & Te4
317 #define Te4_2 0x00FF0000 & Te4
318 #define Te4_3 0xFF000000 & Te4
319
320 #else
321
322 #define Te0(x) TE0[x]
323 #define Te1(x) TE1[x]
324 #define Te2(x) TE2[x]
325 #define Te3(x) TE3[x]
326
327 #define Td0(x) TD0[x]
328 #define Td1(x) TD1[x]
329 #define Td2(x) TD2[x]
330 #define Td3(x) TD3[x]
331
332 static const ulong32 TE1[256] = {
333 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL,
334 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL,
335 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL,
336 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL,
337 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL,
338 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL,
339 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL,
340 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL,
341 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL,
342 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL,
343 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL,
344 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL,
345 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL,
346 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL,
347 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL,
348 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL,
349 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL,
350 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL,
351 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL,
352 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL,
353 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL,
354 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL,
355 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL,
356 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL,
357 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL,
358 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL,
359 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL,
360 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL,
361 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL,
362 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL,
363 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL,
364 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL,
365 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL,
366 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL,
367 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL,
368 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL,
369 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL,
370 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL,
371 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL,
372 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL,
373 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL,
374 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL,
375 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL,
376 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL,
377 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL,
378 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL,
379 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL,
380 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL,
381 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL,
382 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL,
383 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL,
384 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL,
385 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL,
386 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL,
387 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL,
388 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL,
389 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL,
390 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL,
391 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL,
392 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL,
393 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL,
394 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL,
395 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL,
396 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL,
397 };
398 static const ulong32 TE2[256] = {
399 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL,
400 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL,
401 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL,
402 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL,
403 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL,
404 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL,
405 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL,
406 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL,
407 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL,
408 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL,
409 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL,
410 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL,
411 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL,
412 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL,
413 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL,
414 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL,
415 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL,
416 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL,
417 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL,
418 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL,
419 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL,
420 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL,
421 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL,
422 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL,
423 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL,
424 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL,
425 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL,
426 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL,
427 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL,
428 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL,
429 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL,
430 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL,
431 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL,
432 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL,
433 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL,
434 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL,
435 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL,
436 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL,
437 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL,
438 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL,
439 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL,
440 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL,
441 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL,
442 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL,
443 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL,
444 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL,
445 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL,
446 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL,
447 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL,
448 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL,
449 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL,
450 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL,
451 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL,
452 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL,
453 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL,
454 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL,
455 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL,
456 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL,
457 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL,
458 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL,
459 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL,
460 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL,
461 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL,
462 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL,
463 };
464 static const ulong32 TE3[256] = {
465
466 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL,
467 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL,
468 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL,
469 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL,
470 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL,
471 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL,
472 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL,
473 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL,
474 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL,
475 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL,
476 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL,
477 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL,
478 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL,
479 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL,
480 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL,
481 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL,
482 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL,
483 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL,
484 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL,
485 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL,
486 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL,
487 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL,
488 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL,
489 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL,
490 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL,
491 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL,
492 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL,
493 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL,
494 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL,
495 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL,
496 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL,
497 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL,
498 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL,
499 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL,
500 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL,
501 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL,
502 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL,
503 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL,
504 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL,
505 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL,
506 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL,
507 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL,
508 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL,
509 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL,
510 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL,
511 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL,
512 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL,
513 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL,
514 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL,
515 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL,
516 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL,
517 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL,
518 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL,
519 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL,
520 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL,
521 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL,
522 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL,
523 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL,
524 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL,
525 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL,
526 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL,
527 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL,
528 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL,
529 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL,
530 };
531
532 #ifndef PELI_TAB
533 static const ulong32 Te4_0[] = {
534 0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL, 0x0000006bUL, 0x0000006fUL, 0x000000c5UL,
535 0x00000030UL, 0x00000001UL, 0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL, 0x00000076UL,
536 0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL, 0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL,
537 0x000000adUL, 0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL, 0x00000072UL, 0x000000c0UL,
538 0x000000b7UL, 0x000000fdUL, 0x00000093UL, 0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL,
539 0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL, 0x000000d8UL, 0x00000031UL, 0x00000015UL,
540 0x00000004UL, 0x000000c7UL, 0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL, 0x0000009aUL,
541 0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL, 0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL,
542 0x00000009UL, 0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL, 0x0000005aUL, 0x000000a0UL,
543 0x00000052UL, 0x0000003bUL, 0x000000d6UL, 0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL,
544 0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL, 0x000000fcUL, 0x000000b1UL, 0x0000005bUL,
545 0x0000006aUL, 0x000000cbUL, 0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL, 0x000000cfUL,
546 0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL, 0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL,
547 0x00000045UL, 0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL, 0x0000009fUL, 0x000000a8UL,
548 0x00000051UL, 0x000000a3UL, 0x00000040UL, 0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL,
549 0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL, 0x000000ffUL, 0x000000f3UL, 0x000000d2UL,
550 0x000000cdUL, 0x0000000cUL, 0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL, 0x00000017UL,
551 0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL, 0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL,
552 0x00000060UL, 0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL, 0x00000090UL, 0x00000088UL,
553 0x00000046UL, 0x000000eeUL, 0x000000b8UL, 0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL,
554 0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL, 0x00000006UL, 0x00000024UL, 0x0000005cUL,
555 0x000000c2UL, 0x000000d3UL, 0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL, 0x00000079UL,
556 0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL, 0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL,
557 0x0000006cUL, 0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL, 0x000000aeUL, 0x00000008UL,
558 0x000000baUL, 0x00000078UL, 0x00000025UL, 0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL,
559 0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL, 0x000000bdUL, 0x0000008bUL, 0x0000008aUL,
560 0x00000070UL, 0x0000003eUL, 0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL, 0x0000000eUL,
561 0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL, 0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL,
562 0x000000e1UL, 0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL, 0x0000008eUL, 0x00000094UL,
563 0x0000009bUL, 0x0000001eUL, 0x00000087UL, 0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL,
564 0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL, 0x000000e6UL, 0x00000042UL, 0x00000068UL,
565 0x00000041UL, 0x00000099UL, 0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL, 0x00000016UL
566 };
567
568 static const ulong32 Te4_1[] = {
569 0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL, 0x00006b00UL, 0x00006f00UL, 0x0000c500UL,
570 0x00003000UL, 0x00000100UL, 0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL, 0x00007600UL,
571 0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL, 0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL,
572 0x0000ad00UL, 0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL, 0x00007200UL, 0x0000c000UL,
573 0x0000b700UL, 0x0000fd00UL, 0x00009300UL, 0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL,
574 0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL, 0x0000d800UL, 0x00003100UL, 0x00001500UL,
575 0x00000400UL, 0x0000c700UL, 0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL, 0x00009a00UL,
576 0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL, 0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL,
577 0x00000900UL, 0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL, 0x00005a00UL, 0x0000a000UL,
578 0x00005200UL, 0x00003b00UL, 0x0000d600UL, 0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL,
579 0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL, 0x0000fc00UL, 0x0000b100UL, 0x00005b00UL,
580 0x00006a00UL, 0x0000cb00UL, 0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL, 0x0000cf00UL,
581 0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL, 0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL,
582 0x00004500UL, 0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL, 0x00009f00UL, 0x0000a800UL,
583 0x00005100UL, 0x0000a300UL, 0x00004000UL, 0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL,
584 0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL, 0x0000ff00UL, 0x0000f300UL, 0x0000d200UL,
585 0x0000cd00UL, 0x00000c00UL, 0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL, 0x00001700UL,
586 0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL, 0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL,
587 0x00006000UL, 0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL, 0x00009000UL, 0x00008800UL,
588 0x00004600UL, 0x0000ee00UL, 0x0000b800UL, 0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL,
589 0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL, 0x00000600UL, 0x00002400UL, 0x00005c00UL,
590 0x0000c200UL, 0x0000d300UL, 0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL, 0x00007900UL,
591 0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL, 0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL,
592 0x00006c00UL, 0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL, 0x0000ae00UL, 0x00000800UL,
593 0x0000ba00UL, 0x00007800UL, 0x00002500UL, 0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL,
594 0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL, 0x0000bd00UL, 0x00008b00UL, 0x00008a00UL,
595 0x00007000UL, 0x00003e00UL, 0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL, 0x00000e00UL,
596 0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL, 0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL,
597 0x0000e100UL, 0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL, 0x00008e00UL, 0x00009400UL,
598 0x00009b00UL, 0x00001e00UL, 0x00008700UL, 0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL,
599 0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL, 0x0000e600UL, 0x00004200UL, 0x00006800UL,
600 0x00004100UL, 0x00009900UL, 0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL, 0x00001600UL
601 };
602
603 static const ulong32 Te4_2[] = {
604 0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL, 0x006b0000UL, 0x006f0000UL, 0x00c50000UL,
605 0x00300000UL, 0x00010000UL, 0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL, 0x00760000UL,
606 0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL, 0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL,
607 0x00ad0000UL, 0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL, 0x00720000UL, 0x00c00000UL,
608 0x00b70000UL, 0x00fd0000UL, 0x00930000UL, 0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL,
609 0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL, 0x00d80000UL, 0x00310000UL, 0x00150000UL,
610 0x00040000UL, 0x00c70000UL, 0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL, 0x009a0000UL,
611 0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL, 0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL,
612 0x00090000UL, 0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL, 0x005a0000UL, 0x00a00000UL,
613 0x00520000UL, 0x003b0000UL, 0x00d60000UL, 0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL,
614 0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL, 0x00fc0000UL, 0x00b10000UL, 0x005b0000UL,
615 0x006a0000UL, 0x00cb0000UL, 0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL, 0x00cf0000UL,
616 0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL, 0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL,
617 0x00450000UL, 0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL, 0x009f0000UL, 0x00a80000UL,
618 0x00510000UL, 0x00a30000UL, 0x00400000UL, 0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL,
619 0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL, 0x00ff0000UL, 0x00f30000UL, 0x00d20000UL,
620 0x00cd0000UL, 0x000c0000UL, 0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL, 0x00170000UL,
621 0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL, 0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL,
622 0x00600000UL, 0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL, 0x00900000UL, 0x00880000UL,
623 0x00460000UL, 0x00ee0000UL, 0x00b80000UL, 0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL,
624 0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL, 0x00060000UL, 0x00240000UL, 0x005c0000UL,
625 0x00c20000UL, 0x00d30000UL, 0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL, 0x00790000UL,
626 0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL, 0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL,
627 0x006c0000UL, 0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL, 0x00ae0000UL, 0x00080000UL,
628 0x00ba0000UL, 0x00780000UL, 0x00250000UL, 0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL,
629 0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL, 0x00bd0000UL, 0x008b0000UL, 0x008a0000UL,
630 0x00700000UL, 0x003e0000UL, 0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL, 0x000e0000UL,
631 0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL, 0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL,
632 0x00e10000UL, 0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL, 0x008e0000UL, 0x00940000UL,
633 0x009b0000UL, 0x001e0000UL, 0x00870000UL, 0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL,
634 0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL, 0x00e60000UL, 0x00420000UL, 0x00680000UL,
635 0x00410000UL, 0x00990000UL, 0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL, 0x00160000UL
636 };
637
638 static const ulong32 Te4_3[] = {
639 0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL, 0x6b000000UL, 0x6f000000UL, 0xc5000000UL,
640 0x30000000UL, 0x01000000UL, 0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL, 0x76000000UL,
641 0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL, 0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL,
642 0xad000000UL, 0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL, 0x72000000UL, 0xc0000000UL,
643 0xb7000000UL, 0xfd000000UL, 0x93000000UL, 0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL,
644 0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL, 0xd8000000UL, 0x31000000UL, 0x15000000UL,
645 0x04000000UL, 0xc7000000UL, 0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL, 0x9a000000UL,
646 0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL, 0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL,
647 0x09000000UL, 0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL, 0x5a000000UL, 0xa0000000UL,
648 0x52000000UL, 0x3b000000UL, 0xd6000000UL, 0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL,
649 0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL, 0xfc000000UL, 0xb1000000UL, 0x5b000000UL,
650 0x6a000000UL, 0xcb000000UL, 0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL, 0xcf000000UL,
651 0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL, 0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL,
652 0x45000000UL, 0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL, 0x9f000000UL, 0xa8000000UL,
653 0x51000000UL, 0xa3000000UL, 0x40000000UL, 0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL,
654 0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL, 0xff000000UL, 0xf3000000UL, 0xd2000000UL,
655 0xcd000000UL, 0x0c000000UL, 0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL, 0x17000000UL,
656 0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL, 0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL,
657 0x60000000UL, 0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL, 0x90000000UL, 0x88000000UL,
658 0x46000000UL, 0xee000000UL, 0xb8000000UL, 0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL,
659 0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL, 0x06000000UL, 0x24000000UL, 0x5c000000UL,
660 0xc2000000UL, 0xd3000000UL, 0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL, 0x79000000UL,
661 0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL, 0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL,
662 0x6c000000UL, 0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL, 0xae000000UL, 0x08000000UL,
663 0xba000000UL, 0x78000000UL, 0x25000000UL, 0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL,
664 0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL, 0xbd000000UL, 0x8b000000UL, 0x8a000000UL,
665 0x70000000UL, 0x3e000000UL, 0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL, 0x0e000000UL,
666 0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL, 0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL,
667 0xe1000000UL, 0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL, 0x8e000000UL, 0x94000000UL,
668 0x9b000000UL, 0x1e000000UL, 0x87000000UL, 0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL,
669 0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL, 0xe6000000UL, 0x42000000UL, 0x68000000UL,
670 0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL
671 };
672 #endif /* pelimac */
673
674 #ifndef ENCRYPT_ONLY
675
676 static const ulong32 TD1[256] = {
677 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
678 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
679 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL,
680 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL,
681 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL,
682 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL,
683 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL,
684 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL,
685 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL,
686 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL,
687 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL,
688 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL,
689 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL,
690 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL,
691 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL,
692 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL,
693 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL,
694 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL,
695 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL,
696 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL,
697 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL,
698 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL,
699 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL,
700 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL,
701 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL,
702 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL,
703 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL,
704 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL,
705 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL,
706 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL,
707 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL,
708 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL,
709 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL,
710 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL,
711 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL,
712 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL,
713 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL,
714 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL,
715 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL,
716 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL,
717 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL,
718 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL,
719 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL,
720 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL,
721 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL,
722 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL,
723 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL,
724 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL,
725 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL,
726 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL,
727 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL,
728 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL,
729 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL,
730 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL,
731 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL,
732 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL,
733 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL,
734 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL,
735 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL,
736 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL,
737 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL,
738 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL,
739 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL,
740 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL,
741 };
742 static const ulong32 TD2[256] = {
743 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL,
744 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL,
745 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL,
746 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL,
747 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL,
748 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL,
749 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL,
750 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL,
751 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL,
752 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL,
753 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL,
754 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL,
755 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL,
756 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL,
757 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL,
758 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL,
759 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL,
760 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL,
761 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL,
762 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL,
763 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL,
764 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL,
765 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL,
766 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL,
767 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL,
768 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL,
769 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL,
770 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL,
771 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL,
772 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL,
773 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL,
774 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL,
775 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL,
776 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL,
777 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL,
778 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL,
779 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL,
780 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL,
781 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL,
782 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL,
783 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL,
784 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL,
785 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL,
786 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL,
787 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL,
788 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL,
789 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL,
790 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL,
791 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL,
792 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL,
793 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL,
794 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL,
795 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL,
796 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL,
797 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL,
798 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL,
799 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL,
800 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL,
801 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL,
802 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL,
803 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL,
804 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL,
805 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL,
806 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL,
807 };
808 static const ulong32 TD3[256] = {
809 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL,
810 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL,
811 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL,
812 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL,
813 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL,
814 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL,
815 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL,
816 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL,
817 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL,
818 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL,
819 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL,
820 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL,
821 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL,
822 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL,
823 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL,
824 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL,
825 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL,
826 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL,
827 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL,
828 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL,
829 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL,
830 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL,
831 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL,
832 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL,
833 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL,
834 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL,
835 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL,
836 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL,
837 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL,
838 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL,
839 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL,
840 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL,
841 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL,
842 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL,
843 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL,
844 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL,
845 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL,
846 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL,
847 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL,
848 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL,
849 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL,
850 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL,
851 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL,
852 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL,
853 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL,
854 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL,
855 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL,
856 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL,
857 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL,
858 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL,
859 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL,
860 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL,
861 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL,
862 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL,
863 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL,
864 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL,
865 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL,
866 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL,
867 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL,
868 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL,
869 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL,
870 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL,
871 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL,
872 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL,
873 };
874
875 static const ulong32 Tks0[] = {
876 0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL, 0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL,
877 0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL, 0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL,
878 0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL, 0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL,
879 0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL, 0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL,
880 0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL, 0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL,
881 0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL, 0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL,
882 0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL, 0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL,
883 0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL, 0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL,
884 0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL, 0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL,
885 0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL, 0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL,
886 0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL, 0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL,
887 0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL, 0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL,
888 0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL, 0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL,
889 0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL, 0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL,
890 0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL, 0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL,
891 0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL, 0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL,
892 0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL, 0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL,
893 0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL, 0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL,
894 0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL, 0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL,
895 0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL, 0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL,
896 0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL, 0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL,
897 0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL, 0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL,
898 0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL, 0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL,
899 0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL, 0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL,
900 0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL, 0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL,
901 0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL, 0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL,
902 0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL, 0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL,
903 0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL, 0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL,
904 0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL, 0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL,
905 0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL, 0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL,
906 0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL, 0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL,
907 0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL, 0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL
908 };
909
910 static const ulong32 Tks1[] = {
911 0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL, 0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL,
912 0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL, 0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL,
913 0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL, 0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL,
914 0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL, 0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL,
915 0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL, 0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL,
916 0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL, 0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL,
917 0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL, 0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL,
918 0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL, 0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL,
919 0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL, 0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL,
920 0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL, 0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL,
921 0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL, 0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL,
922 0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL, 0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL,
923 0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL, 0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL,
924 0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL, 0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL,
925 0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL, 0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL,
926 0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL, 0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL,
927 0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL, 0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL,
928 0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL, 0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL,
929 0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL, 0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL,
930 0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL, 0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL,
931 0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL, 0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL,
932 0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL, 0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL,
933 0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL, 0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL,
934 0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL, 0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL,
935 0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL, 0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL,
936 0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL, 0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL,
937 0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL, 0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL,
938 0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL, 0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL,
939 0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL, 0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL,
940 0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL, 0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL,
941 0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL, 0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL,
942 0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL, 0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL
943 };
944
945 static const ulong32 Tks2[] = {
946 0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL, 0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL,
947 0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL, 0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL,
948 0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL, 0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL,
949 0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL, 0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL,
950 0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL, 0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL,
951 0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL, 0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL,
952 0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL, 0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL,
953 0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL, 0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL,
954 0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL, 0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL,
955 0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL, 0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL,
956 0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL, 0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL,
957 0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL, 0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL,
958 0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL, 0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL,
959 0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL, 0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL,
960 0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL, 0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL,
961 0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL, 0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL,
962 0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL, 0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL,
963 0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL, 0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL,
964 0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL, 0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL,
965 0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL, 0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL,
966 0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL, 0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL,
967 0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL, 0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL,
968 0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL, 0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL,
969 0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL, 0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL,
970 0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL, 0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL,
971 0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL, 0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL,
972 0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL, 0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL,
973 0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL, 0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL,
974 0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL, 0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL,
975 0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL, 0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL,
976 0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL, 0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL,
977 0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL, 0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL
978 };
979
980 static const ulong32 Tks3[] = {
981 0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL,
982 0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL,
983 0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL,
984 0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL,
985 0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL,
986 0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL,
987 0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL,
988 0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL,
989 0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL,
990 0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL,
991 0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL,
992 0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL,
993 0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL,
994 0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL,
995 0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL,
996 0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL,
997 0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL,
998 0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL,
999 0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL,
1000 0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL,
1001 0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL,
1002 0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL,
1003 0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL,
1004 0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL,
1005 0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL,
1006 0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL,
1007 0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL,
1008 0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL,
1009 0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL,
1010 0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL,
1011 0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL,
1012 0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL
1013 };
1014
1015 #endif /* ENCRYPT_ONLY */
1016
1017 #endif /* SMALL CODE */
1018
1019 static const ulong32 rcon[] = {
1020 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
1021 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
1022 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1023 };
1024
1025 /* $Source$ */
1026 /* $Revision$ */
1027 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file anubis.c
13 Anubis implementation derived from public domain source
14 Authors: Paulo S.L.M. Barreto and Vincent Rijmen.
15 */
16
17 #include "tomcrypt.h"
18
19 #ifdef LTC_ANUBIS
20
21 const struct ltc_cipher_descriptor anubis_desc = {
22 "anubis",
23 19,
24 16, 40, 16, 12,
25 &anubis_setup,
26 &anubis_ecb_encrypt,
27 &anubis_ecb_decrypt,
28 &anubis_test,
29 &anubis_done,
30 &anubis_keysize,
31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
32 };
33
34 #define MIN_N 4
35 #define MAX_N 10
36 #define MIN_ROUNDS (8 + MIN_N)
37 #define MAX_ROUNDS (8 + MAX_N)
38 #define MIN_KEYSIZEB (4*MIN_N)
39 #define MAX_KEYSIZEB (4*MAX_N)
40 #define BLOCKSIZE 128
41 #define BLOCKSIZEB (BLOCKSIZE/8)
42
43
44 /*
45 * Though Anubis is endianness-neutral, the encryption tables are listed
46 * in BIG-ENDIAN format, which is adopted throughout this implementation
47 * (but little-endian notation would be equally suitable if consistently
48 * employed).
49 */
50 #if defined(LTC_ANUBIS_TWEAK)
51
52 static const ulong32 T0[256] = {
53 0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U,
54 0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U,
55 0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U,
56 0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U,
57 0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU,
58 0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U,
59 0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U,
60 0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U,
61 0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU,
62 0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U,
63 0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U,
64 0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU,
65 0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U,
66 0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U,
67 0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U,
68 0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U,
69 0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U,
70 0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U,
71 0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U,
72 0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U,
73 0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U,
74 0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U,
75 0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U,
76 0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U,
77 0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU,
78 0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU,
79 0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU,
80 0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U,
81 0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU,
82 0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU,
83 0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U,
84 0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U,
85 0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U,
86 0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U,
87 0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U,
88 0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U,
89 0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU,
90 0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU,
91 0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU,
92 0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU,
93 0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU,
94 0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU,
95 0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU,
96 0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U,
97 0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU,
98 0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U,
99 0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU,
100 0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU,
101 0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U,
102 0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U,
103 0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U,
104 0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU,
105 0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU,
106 0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U,
107 0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U,
108 0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U,
109 0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U,
110 0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU,
111 0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU,
112 0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U,
113 0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU,
114 0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU,
115 0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU,
116 0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U,
117 };
118
119 static const ulong32 T1[256] = {
120 0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU,
121 0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U,
122 0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U,
123 0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU,
124 0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U,
125 0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U,
126 0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU,
127 0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U,
128 0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U,
129 0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U,
130 0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU,
131 0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U,
132 0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U,
133 0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U,
134 0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U,
135 0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU,
136 0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U,
137 0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U,
138 0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU,
139 0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU,
140 0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U,
141 0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U,
142 0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U,
143 0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U,
144 0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U,
145 0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU,
146 0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U,
147 0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U,
148 0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U,
149 0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU,
150 0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U,
151 0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U,
152 0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU,
153 0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U,
154 0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU,
155 0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU,
156 0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU,
157 0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U,
158 0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU,
159 0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU,
160 0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU,
161 0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U,
162 0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U,
163 0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U,
164 0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U,
165 0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U,
166 0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U,
167 0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU,
168 0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U,
169 0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U,
170 0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U,
171 0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U,
172 0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U,
173 0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU,
174 0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U,
175 0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U,
176 0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U,
177 0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U,
178 0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU,
179 0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU,
180 0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U,
181 0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU,
182 0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U,
183 0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U,
184 };
185
186 static const ulong32 T2[256] = {
187 0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U,
188 0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU,
189 0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U,
190 0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U,
191 0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU,
192 0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U,
193 0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU,
194 0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U,
195 0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU,
196 0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU,
197 0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U,
198 0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U,
199 0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U,
200 0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU,
201 0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U,
202 0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U,
203 0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U,
204 0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U,
205 0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU,
206 0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU,
207 0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U,
208 0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU,
209 0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU,
210 0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U,
211 0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU,
212 0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U,
213 0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U,
214 0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU,
215 0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U,
216 0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U,
217 0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU,
218 0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U,
219 0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU,
220 0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U,
221 0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU,
222 0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U,
223 0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U,
224 0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U,
225 0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U,
226 0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U,
227 0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U,
228 0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U,
229 0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U,
230 0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU,
231 0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU,
232 0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU,
233 0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU,
234 0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U,
235 0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U,
236 0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U,
237 0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U,
238 0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU,
239 0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU,
240 0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U,
241 0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U,
242 0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU,
243 0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U,
244 0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU,
245 0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U,
246 0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U,
247 0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU,
248 0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U,
249 0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU,
250 0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U,
251 };
252
253 static const ulong32 T3[256] = {
254 0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U,
255 0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU,
256 0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU,
257 0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU,
258 0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U,
259 0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U,
260 0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U,
261 0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU,
262 0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU,
263 0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU,
264 0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U,
265 0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U,
266 0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U,
267 0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU,
268 0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU,
269 0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU,
270 0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU,
271 0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU,
272 0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U,
273 0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU,
274 0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U,
275 0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U,
276 0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U,
277 0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U,
278 0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U,
279 0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU,
280 0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU,
281 0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U,
282 0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U,
283 0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U,
284 0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U,
285 0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU,
286 0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U,
287 0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU,
288 0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U,
289 0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U,
290 0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU,
291 0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U,
292 0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U,
293 0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU,
294 0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U,
295 0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U,
296 0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU,
297 0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU,
298 0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U,
299 0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU,
300 0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U,
301 0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU,
302 0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U,
303 0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U,
304 0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U,
305 0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U,
306 0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U,
307 0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU,
308 0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU,
309 0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U,
310 0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U,
311 0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U,
312 0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U,
313 0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U,
314 0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU,
315 0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U,
316 0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU,
317 0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U,
318 };
319
320 static const ulong32 T4[256] = {
321 0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U,
322 0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU,
323 0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU,
324 0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU,
325 0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U,
326 0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U,
327 0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U,
328 0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU,
329 0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU,
330 0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU,
331 0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U,
332 0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U,
333 0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U,
334 0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU,
335 0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU,
336 0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU,
337 0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU,
338 0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU,
339 0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U,
340 0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU,
341 0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U,
342 0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U,
343 0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U,
344 0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U,
345 0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U,
346 0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU,
347 0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU,
348 0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U,
349 0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U,
350 0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U,
351 0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U,
352 0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU,
353 0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U,
354 0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU,
355 0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U,
356 0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U,
357 0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU,
358 0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U,
359 0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U,
360 0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU,
361 0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U,
362 0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U,
363 0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU,
364 0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU,
365 0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U,
366 0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU,
367 0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U,
368 0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU,
369 0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U,
370 0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U,
371 0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U,
372 0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U,
373 0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U,
374 0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU,
375 0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU,
376 0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U,
377 0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U,
378 0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U,
379 0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U,
380 0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U,
381 0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU,
382 0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U,
383 0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU,
384 0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U,
385 };
386
387 static const ulong32 T5[256] = {
388 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U,
389 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U,
390 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U,
391 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U,
392 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U,
393 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U,
394 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U,
395 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U,
396 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U,
397 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U,
398 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U,
399 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U,
400 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U,
401 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U,
402 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U,
403 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U,
404 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U,
405 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U,
406 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U,
407 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U,
408 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U,
409 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U,
410 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U,
411 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U,
412 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU,
413 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU,
414 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU,
415 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU,
416 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU,
417 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU,
418 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU,
419 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU,
420 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU,
421 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU,
422 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU,
423 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU,
424 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU,
425 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU,
426 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU,
427 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU,
428 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U,
429 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U,
430 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U,
431 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U,
432 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U,
433 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U,
434 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U,
435 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U,
436 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U,
437 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U,
438 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U,
439 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U,
440 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U,
441 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U,
442 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U,
443 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U,
444 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU,
445 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU,
446 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU,
447 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU,
448 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU,
449 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU,
450 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU,
451 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU,
452 };
453
454 /**
455 * The round constants.
456 */
457 static const ulong32 rc[] = {
458 0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU,
459 0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU,
460 0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U,
461 0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU,
462 0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U,
463 };
464
465
466
467 #else
468
469
470 static const ulong32 T0[256] = {
471 0xa753a6f5U, 0xd3bb6bd0U, 0xe6d1bf6eU, 0x71e2d93bU,
472 0xd0bd67daU, 0xac458acfU, 0x4d9a29b3U, 0x79f2f90bU,
473 0x3a74e89cU, 0xc98f038cU, 0x913f7e41U, 0xfce5d732U,
474 0x1e3c7844U, 0x478e018fU, 0x54a84de5U, 0xbd67cea9U,
475 0x8c050a0fU, 0xa557aef9U, 0x7af4f501U, 0xfbebcb20U,
476 0x63c69157U, 0xb86ddab7U, 0xdda753f4U, 0xd4b577c2U,
477 0xe5d7b364U, 0xb37bf68dU, 0xc59733a4U, 0xbe61c2a3U,
478 0xa94f9ed1U, 0x880d1a17U, 0x0c183028U, 0xa259b2ebU,
479 0x3972e496U, 0xdfa35bf8U, 0x2952a4f6U, 0xdaa94fe6U,
480 0x2b56acfaU, 0xa84d9ad7U, 0xcb8b0b80U, 0x4c982db5U,
481 0x4b9631a7U, 0x224488ccU, 0xaa4992dbU, 0x244890d8U,
482 0x4182199bU, 0x70e0dd3dU, 0xa651a2f3U, 0xf9efc32cU,
483 0x5ab475c1U, 0xe2d9af76U, 0xb07dfa87U, 0x366cd8b4U,
484 0x7dfae913U, 0xe4d5b762U, 0x3366ccaaU, 0xffe3db38U,
485 0x60c09d5dU, 0x204080c0U, 0x08102030U, 0x8b0b161dU,
486 0x5ebc65d9U, 0xab4b96ddU, 0x7ffee11fU, 0x78f0fd0dU,
487 0x7cf8ed15U, 0x2c58b0e8U, 0x57ae41efU, 0xd2b96fd6U,
488 0xdca557f2U, 0x6ddaa973U, 0x7efce519U, 0x0d1a342eU,
489 0x53a651f7U, 0x94356a5fU, 0xc39b2bb0U, 0x2850a0f0U,
490 0x274e9cd2U, 0x060c1814U, 0x5fbe61dfU, 0xad478ec9U,
491 0x67ce814fU, 0x5cb86dd5U, 0x55aa49e3U, 0x48903dadU,
492 0x0e1c3824U, 0x52a455f1U, 0xeac98f46U, 0x42841591U,
493 0x5bb671c7U, 0x5dba69d3U, 0x3060c0a0U, 0x58b07dcdU,
494 0x51a259fbU, 0x59b279cbU, 0x3c78f088U, 0x4e9c25b9U,
495 0x3870e090U, 0x8a09121bU, 0x72e4d531U, 0x14285078U,
496 0xe7d3bb68U, 0xc6913faeU, 0xdea15ffeU, 0x50a05dfdU,
497 0x8e010203U, 0x9239724bU, 0xd1bf63dcU, 0x77eec12fU,
498 0x933b764dU, 0x458a0983U, 0x9a29527bU, 0xce811f9eU,
499 0x2d5ab4eeU, 0x03060c0aU, 0x62c49551U, 0xb671e293U,
500 0xb96fdeb1U, 0xbf63c6a5U, 0x96316253U, 0x6bd6b167U,
501 0x3f7efc82U, 0x070e1c12U, 0x1224486cU, 0xae4182c3U,
502 0x40801d9dU, 0x3468d0b8U, 0x468c0589U, 0x3e7cf884U,
503 0xdbab4be0U, 0xcf831b98U, 0xecc59752U, 0xcc851792U,
504 0xc19f23bcU, 0xa15fbee1U, 0xc09d27baU, 0xd6b17fceU,
505 0x1d3a744eU, 0xf4f5f702U, 0x61c2995bU, 0x3b76ec9aU,
506 0x10204060U, 0xd8ad47eaU, 0x68d0bd6dU, 0xa05dbae7U,
507 0xb17ffe81U, 0x0a14283cU, 0x69d2b96bU, 0x6cd8ad75U,
508 0x499239abU, 0xfae9cf26U, 0x76ecc529U, 0xc49537a2U,
509 0x9e214263U, 0x9b2b567dU, 0x6edca579U, 0x992f5e71U,
510 0xc2992fb6U, 0xb773e695U, 0x982d5a77U, 0xbc65caafU,
511 0x8f030605U, 0x85172e39U, 0x1f3e7c42U, 0xb475ea9fU,
512 0xf8edc72aU, 0x11224466U, 0x2e5cb8e4U, 0x00000000U,
513 0x254a94deU, 0x1c387048U, 0x2a54a8fcU, 0x3d7af48eU,
514 0x050a141eU, 0x4f9e21bfU, 0x7bf6f107U, 0xb279f28bU,
515 0x3264c8acU, 0x903d7a47U, 0xaf4386c5U, 0x19326456U,
516 0xa35bb6edU, 0xf7f3fb08U, 0x73e6d137U, 0x9d274e69U,
517 0x152a547eU, 0x74e8cd25U, 0xeec19f5eU, 0xca890f86U,
518 0x9f234665U, 0x0f1e3c22U, 0x1b366c5aU, 0x75eac923U,
519 0x86112233U, 0x84152a3fU, 0x9c254a6fU, 0x4a9435a1U,
520 0x97336655U, 0x1a34685cU, 0x65ca8943U, 0xf6f1ff0eU,
521 0xedc79354U, 0x09122436U, 0xbb6bd6bdU, 0x264c98d4U,
522 0x831b362dU, 0xebcb8b40U, 0x6fdea17fU, 0x811f3e21U,
523 0x04081018U, 0x6ad4b561U, 0x43861197U, 0x01020406U,
524 0x172e5c72U, 0xe1dfa37cU, 0x87132635U, 0xf5f7f304U,
525 0x8d070e09U, 0xe3dbab70U, 0x23468ccaU, 0x801d3a27U,
526 0x44880d85U, 0x162c5874U, 0x66cc8549U, 0x214284c6U,
527 0xfee1df3eU, 0xd5b773c4U, 0x3162c4a6U, 0xd9af43ecU,
528 0x356ad4beU, 0x18306050U, 0x0204080cU, 0x64c88d45U,
529 0xf2f9ef16U, 0xf1ffe31cU, 0x56ac45e9U, 0xcd871394U,
530 0x8219322bU, 0xc88d078aU, 0xba69d2bbU, 0xf0fde71aU,
531 0xefc39b58U, 0xe9cf834cU, 0xe8cd874aU, 0xfde7d334U,
532 0x890f1e11U, 0xd7b37bc8U, 0xc7933ba8U, 0xb577ee99U,
533 0xa455aaffU, 0x2f5ebce2U, 0x95376e59U, 0x13264c6aU,
534 0x0b162c3aU, 0xf3fbeb10U, 0xe0dda77aU, 0x376edcb2U,
535 };
536
537 static const ulong32 T1[256] = {
538 0x53a7f5a6U, 0xbbd3d06bU, 0xd1e66ebfU, 0xe2713bd9U,
539 0xbdd0da67U, 0x45accf8aU, 0x9a4db329U, 0xf2790bf9U,
540 0x743a9ce8U, 0x8fc98c03U, 0x3f91417eU, 0xe5fc32d7U,
541 0x3c1e4478U, 0x8e478f01U, 0xa854e54dU, 0x67bda9ceU,
542 0x058c0f0aU, 0x57a5f9aeU, 0xf47a01f5U, 0xebfb20cbU,
543 0xc6635791U, 0x6db8b7daU, 0xa7ddf453U, 0xb5d4c277U,
544 0xd7e564b3U, 0x7bb38df6U, 0x97c5a433U, 0x61bea3c2U,
545 0x4fa9d19eU, 0x0d88171aU, 0x180c2830U, 0x59a2ebb2U,
546 0x723996e4U, 0xa3dff85bU, 0x5229f6a4U, 0xa9dae64fU,
547 0x562bfaacU, 0x4da8d79aU, 0x8bcb800bU, 0x984cb52dU,
548 0x964ba731U, 0x4422cc88U, 0x49aadb92U, 0x4824d890U,
549 0x82419b19U, 0xe0703dddU, 0x51a6f3a2U, 0xeff92cc3U,
550 0xb45ac175U, 0xd9e276afU, 0x7db087faU, 0x6c36b4d8U,
551 0xfa7d13e9U, 0xd5e462b7U, 0x6633aaccU, 0xe3ff38dbU,
552 0xc0605d9dU, 0x4020c080U, 0x10083020U, 0x0b8b1d16U,
553 0xbc5ed965U, 0x4babdd96U, 0xfe7f1fe1U, 0xf0780dfdU,
554 0xf87c15edU, 0x582ce8b0U, 0xae57ef41U, 0xb9d2d66fU,
555 0xa5dcf257U, 0xda6d73a9U, 0xfc7e19e5U, 0x1a0d2e34U,
556 0xa653f751U, 0x35945f6aU, 0x9bc3b02bU, 0x5028f0a0U,
557 0x4e27d29cU, 0x0c061418U, 0xbe5fdf61U, 0x47adc98eU,
558 0xce674f81U, 0xb85cd56dU, 0xaa55e349U, 0x9048ad3dU,
559 0x1c0e2438U, 0xa452f155U, 0xc9ea468fU, 0x84429115U,
560 0xb65bc771U, 0xba5dd369U, 0x6030a0c0U, 0xb058cd7dU,
561 0xa251fb59U, 0xb259cb79U, 0x783c88f0U, 0x9c4eb925U,
562 0x703890e0U, 0x098a1b12U, 0xe47231d5U, 0x28147850U,
563 0xd3e768bbU, 0x91c6ae3fU, 0xa1defe5fU, 0xa050fd5dU,
564 0x018e0302U, 0x39924b72U, 0xbfd1dc63U, 0xee772fc1U,
565 0x3b934d76U, 0x8a458309U, 0x299a7b52U, 0x81ce9e1fU,
566 0x5a2deeb4U, 0x06030a0cU, 0xc4625195U, 0x71b693e2U,
567 0x6fb9b1deU, 0x63bfa5c6U, 0x31965362U, 0xd66b67b1U,
568 0x7e3f82fcU, 0x0e07121cU, 0x24126c48U, 0x41aec382U,
569 0x80409d1dU, 0x6834b8d0U, 0x8c468905U, 0x7c3e84f8U,
570 0xabdbe04bU, 0x83cf981bU, 0xc5ec5297U, 0x85cc9217U,
571 0x9fc1bc23U, 0x5fa1e1beU, 0x9dc0ba27U, 0xb1d6ce7fU,
572 0x3a1d4e74U, 0xf5f402f7U, 0xc2615b99U, 0x763b9aecU,
573 0x20106040U, 0xadd8ea47U, 0xd0686dbdU, 0x5da0e7baU,
574 0x7fb181feU, 0x140a3c28U, 0xd2696bb9U, 0xd86c75adU,
575 0x9249ab39U, 0xe9fa26cfU, 0xec7629c5U, 0x95c4a237U,
576 0x219e6342U, 0x2b9b7d56U, 0xdc6e79a5U, 0x2f99715eU,
577 0x99c2b62fU, 0x73b795e6U, 0x2d98775aU, 0x65bcafcaU,
578 0x038f0506U, 0x1785392eU, 0x3e1f427cU, 0x75b49feaU,
579 0xedf82ac7U, 0x22116644U, 0x5c2ee4b8U, 0x00000000U,
580 0x4a25de94U, 0x381c4870U, 0x542afca8U, 0x7a3d8ef4U,
581 0x0a051e14U, 0x9e4fbf21U, 0xf67b07f1U, 0x79b28bf2U,
582 0x6432acc8U, 0x3d90477aU, 0x43afc586U, 0x32195664U,
583 0x5ba3edb6U, 0xf3f708fbU, 0xe67337d1U, 0x279d694eU,
584 0x2a157e54U, 0xe87425cdU, 0xc1ee5e9fU, 0x89ca860fU,
585 0x239f6546U, 0x1e0f223cU, 0x361b5a6cU, 0xea7523c9U,
586 0x11863322U, 0x15843f2aU, 0x259c6f4aU, 0x944aa135U,
587 0x33975566U, 0x341a5c68U, 0xca654389U, 0xf1f60effU,
588 0xc7ed5493U, 0x12093624U, 0x6bbbbdd6U, 0x4c26d498U,
589 0x1b832d36U, 0xcbeb408bU, 0xde6f7fa1U, 0x1f81213eU,
590 0x08041810U, 0xd46a61b5U, 0x86439711U, 0x02010604U,
591 0x2e17725cU, 0xdfe17ca3U, 0x13873526U, 0xf7f504f3U,
592 0x078d090eU, 0xdbe370abU, 0x4623ca8cU, 0x1d80273aU,
593 0x8844850dU, 0x2c167458U, 0xcc664985U, 0x4221c684U,
594 0xe1fe3edfU, 0xb7d5c473U, 0x6231a6c4U, 0xafd9ec43U,
595 0x6a35bed4U, 0x30185060U, 0x04020c08U, 0xc864458dU,
596 0xf9f216efU, 0xfff11ce3U, 0xac56e945U, 0x87cd9413U,
597 0x19822b32U, 0x8dc88a07U, 0x69babbd2U, 0xfdf01ae7U,
598 0xc3ef589bU, 0xcfe94c83U, 0xcde84a87U, 0xe7fd34d3U,
599 0x0f89111eU, 0xb3d7c87bU, 0x93c7a83bU, 0x77b599eeU,
600 0x55a4ffaaU, 0x5e2fe2bcU, 0x3795596eU, 0x26136a4cU,
601 0x160b3a2cU, 0xfbf310ebU, 0xdde07aa7U, 0x6e37b2dcU,
602 };
603
604 static const ulong32 T2[256] = {
605 0xa6f5a753U, 0x6bd0d3bbU, 0xbf6ee6d1U, 0xd93b71e2U,
606 0x67dad0bdU, 0x8acfac45U, 0x29b34d9aU, 0xf90b79f2U,
607 0xe89c3a74U, 0x038cc98fU, 0x7e41913fU, 0xd732fce5U,
608 0x78441e3cU, 0x018f478eU, 0x4de554a8U, 0xcea9bd67U,
609 0x0a0f8c05U, 0xaef9a557U, 0xf5017af4U, 0xcb20fbebU,
610 0x915763c6U, 0xdab7b86dU, 0x53f4dda7U, 0x77c2d4b5U,
611 0xb364e5d7U, 0xf68db37bU, 0x33a4c597U, 0xc2a3be61U,
612 0x9ed1a94fU, 0x1a17880dU, 0x30280c18U, 0xb2eba259U,
613 0xe4963972U, 0x5bf8dfa3U, 0xa4f62952U, 0x4fe6daa9U,
614 0xacfa2b56U, 0x9ad7a84dU, 0x0b80cb8bU, 0x2db54c98U,
615 0x31a74b96U, 0x88cc2244U, 0x92dbaa49U, 0x90d82448U,
616 0x199b4182U, 0xdd3d70e0U, 0xa2f3a651U, 0xc32cf9efU,
617 0x75c15ab4U, 0xaf76e2d9U, 0xfa87b07dU, 0xd8b4366cU,
618 0xe9137dfaU, 0xb762e4d5U, 0xccaa3366U, 0xdb38ffe3U,
619 0x9d5d60c0U, 0x80c02040U, 0x20300810U, 0x161d8b0bU,
620 0x65d95ebcU, 0x96ddab4bU, 0xe11f7ffeU, 0xfd0d78f0U,
621 0xed157cf8U, 0xb0e82c58U, 0x41ef57aeU, 0x6fd6d2b9U,
622 0x57f2dca5U, 0xa9736ddaU, 0xe5197efcU, 0x342e0d1aU,
623 0x51f753a6U, 0x6a5f9435U, 0x2bb0c39bU, 0xa0f02850U,
624 0x9cd2274eU, 0x1814060cU, 0x61df5fbeU, 0x8ec9ad47U,
625 0x814f67ceU, 0x6dd55cb8U, 0x49e355aaU, 0x3dad4890U,
626 0x38240e1cU, 0x55f152a4U, 0x8f46eac9U, 0x15914284U,
627 0x71c75bb6U, 0x69d35dbaU, 0xc0a03060U, 0x7dcd58b0U,
628 0x59fb51a2U, 0x79cb59b2U, 0xf0883c78U, 0x25b94e9cU,
629 0xe0903870U, 0x121b8a09U, 0xd53172e4U, 0x50781428U,
630 0xbb68e7d3U, 0x3faec691U, 0x5ffedea1U, 0x5dfd50a0U,
631 0x02038e01U, 0x724b9239U, 0x63dcd1bfU, 0xc12f77eeU,
632 0x764d933bU, 0x0983458aU, 0x527b9a29U, 0x1f9ece81U,
633 0xb4ee2d5aU, 0x0c0a0306U, 0x955162c4U, 0xe293b671U,
634 0xdeb1b96fU, 0xc6a5bf63U, 0x62539631U, 0xb1676bd6U,
635 0xfc823f7eU, 0x1c12070eU, 0x486c1224U, 0x82c3ae41U,
636 0x1d9d4080U, 0xd0b83468U, 0x0589468cU, 0xf8843e7cU,
637 0x4be0dbabU, 0x1b98cf83U, 0x9752ecc5U, 0x1792cc85U,
638 0x23bcc19fU, 0xbee1a15fU, 0x27bac09dU, 0x7fced6b1U,
639 0x744e1d3aU, 0xf702f4f5U, 0x995b61c2U, 0xec9a3b76U,
640 0x40601020U, 0x47ead8adU, 0xbd6d68d0U, 0xbae7a05dU,
641 0xfe81b17fU, 0x283c0a14U, 0xb96b69d2U, 0xad756cd8U,
642 0x39ab4992U, 0xcf26fae9U, 0xc52976ecU, 0x37a2c495U,
643 0x42639e21U, 0x567d9b2bU, 0xa5796edcU, 0x5e71992fU,
644 0x2fb6c299U, 0xe695b773U, 0x5a77982dU, 0xcaafbc65U,
645 0x06058f03U, 0x2e398517U, 0x7c421f3eU, 0xea9fb475U,
646 0xc72af8edU, 0x44661122U, 0xb8e42e5cU, 0x00000000U,
647 0x94de254aU, 0x70481c38U, 0xa8fc2a54U, 0xf48e3d7aU,
648 0x141e050aU, 0x21bf4f9eU, 0xf1077bf6U, 0xf28bb279U,
649 0xc8ac3264U, 0x7a47903dU, 0x86c5af43U, 0x64561932U,
650 0xb6eda35bU, 0xfb08f7f3U, 0xd13773e6U, 0x4e699d27U,
651 0x547e152aU, 0xcd2574e8U, 0x9f5eeec1U, 0x0f86ca89U,
652 0x46659f23U, 0x3c220f1eU, 0x6c5a1b36U, 0xc92375eaU,
653 0x22338611U, 0x2a3f8415U, 0x4a6f9c25U, 0x35a14a94U,
654 0x66559733U, 0x685c1a34U, 0x894365caU, 0xff0ef6f1U,
655 0x9354edc7U, 0x24360912U, 0xd6bdbb6bU, 0x98d4264cU,
656 0x362d831bU, 0x8b40ebcbU, 0xa17f6fdeU, 0x3e21811fU,
657 0x10180408U, 0xb5616ad4U, 0x11974386U, 0x04060102U,
658 0x5c72172eU, 0xa37ce1dfU, 0x26358713U, 0xf304f5f7U,
659 0x0e098d07U, 0xab70e3dbU, 0x8cca2346U, 0x3a27801dU,
660 0x0d854488U, 0x5874162cU, 0x854966ccU, 0x84c62142U,
661 0xdf3efee1U, 0x73c4d5b7U, 0xc4a63162U, 0x43ecd9afU,
662 0xd4be356aU, 0x60501830U, 0x080c0204U, 0x8d4564c8U,
663 0xef16f2f9U, 0xe31cf1ffU, 0x45e956acU, 0x1394cd87U,
664 0x322b8219U, 0x078ac88dU, 0xd2bbba69U, 0xe71af0fdU,
665 0x9b58efc3U, 0x834ce9cfU, 0x874ae8cdU, 0xd334fde7U,
666 0x1e11890fU, 0x7bc8d7b3U, 0x3ba8c793U, 0xee99b577U,
667 0xaaffa455U, 0xbce22f5eU, 0x6e599537U, 0x4c6a1326U,
668 0x2c3a0b16U, 0xeb10f3fbU, 0xa77ae0ddU, 0xdcb2376eU,
669 };
670
671 static const ulong32 T3[256] = {
672 0xf5a653a7U, 0xd06bbbd3U, 0x6ebfd1e6U, 0x3bd9e271U,
673 0xda67bdd0U, 0xcf8a45acU, 0xb3299a4dU, 0x0bf9f279U,
674 0x9ce8743aU, 0x8c038fc9U, 0x417e3f91U, 0x32d7e5fcU,
675 0x44783c1eU, 0x8f018e47U, 0xe54da854U, 0xa9ce67bdU,
676 0x0f0a058cU, 0xf9ae57a5U, 0x01f5f47aU, 0x20cbebfbU,
677 0x5791c663U, 0xb7da6db8U, 0xf453a7ddU, 0xc277b5d4U,
678 0x64b3d7e5U, 0x8df67bb3U, 0xa43397c5U, 0xa3c261beU,
679 0xd19e4fa9U, 0x171a0d88U, 0x2830180cU, 0xebb259a2U,
680 0x96e47239U, 0xf85ba3dfU, 0xf6a45229U, 0xe64fa9daU,
681 0xfaac562bU, 0xd79a4da8U, 0x800b8bcbU, 0xb52d984cU,
682 0xa731964bU, 0xcc884422U, 0xdb9249aaU, 0xd8904824U,
683 0x9b198241U, 0x3ddde070U, 0xf3a251a6U, 0x2cc3eff9U,
684 0xc175b45aU, 0x76afd9e2U, 0x87fa7db0U, 0xb4d86c36U,
685 0x13e9fa7dU, 0x62b7d5e4U, 0xaacc6633U, 0x38dbe3ffU,
686 0x5d9dc060U, 0xc0804020U, 0x30201008U, 0x1d160b8bU,
687 0xd965bc5eU, 0xdd964babU, 0x1fe1fe7fU, 0x0dfdf078U,
688 0x15edf87cU, 0xe8b0582cU, 0xef41ae57U, 0xd66fb9d2U,
689 0xf257a5dcU, 0x73a9da6dU, 0x19e5fc7eU, 0x2e341a0dU,
690 0xf751a653U, 0x5f6a3594U, 0xb02b9bc3U, 0xf0a05028U,
691 0xd29c4e27U, 0x14180c06U, 0xdf61be5fU, 0xc98e47adU,
692 0x4f81ce67U, 0xd56db85cU, 0xe349aa55U, 0xad3d9048U,
693 0x24381c0eU, 0xf155a452U, 0x468fc9eaU, 0x91158442U,
694 0xc771b65bU, 0xd369ba5dU, 0xa0c06030U, 0xcd7db058U,
695 0xfb59a251U, 0xcb79b259U, 0x88f0783cU, 0xb9259c4eU,
696 0x90e07038U, 0x1b12098aU, 0x31d5e472U, 0x78502814U,
697 0x68bbd3e7U, 0xae3f91c6U, 0xfe5fa1deU, 0xfd5da050U,
698 0x0302018eU, 0x4b723992U, 0xdc63bfd1U, 0x2fc1ee77U,
699 0x4d763b93U, 0x83098a45U, 0x7b52299aU, 0x9e1f81ceU,
700 0xeeb45a2dU, 0x0a0c0603U, 0x5195c462U, 0x93e271b6U,
701 0xb1de6fb9U, 0xa5c663bfU, 0x53623196U, 0x67b1d66bU,
702 0x82fc7e3fU, 0x121c0e07U, 0x6c482412U, 0xc38241aeU,
703 0x9d1d8040U, 0xb8d06834U, 0x89058c46U, 0x84f87c3eU,
704 0xe04babdbU, 0x981b83cfU, 0x5297c5ecU, 0x921785ccU,
705 0xbc239fc1U, 0xe1be5fa1U, 0xba279dc0U, 0xce7fb1d6U,
706 0x4e743a1dU, 0x02f7f5f4U, 0x5b99c261U, 0x9aec763bU,
707 0x60402010U, 0xea47add8U, 0x6dbdd068U, 0xe7ba5da0U,
708 0x81fe7fb1U, 0x3c28140aU, 0x6bb9d269U, 0x75add86cU,
709 0xab399249U, 0x26cfe9faU, 0x29c5ec76U, 0xa23795c4U,
710 0x6342219eU, 0x7d562b9bU, 0x79a5dc6eU, 0x715e2f99U,
711 0xb62f99c2U, 0x95e673b7U, 0x775a2d98U, 0xafca65bcU,
712 0x0506038fU, 0x392e1785U, 0x427c3e1fU, 0x9fea75b4U,
713 0x2ac7edf8U, 0x66442211U, 0xe4b85c2eU, 0x00000000U,
714 0xde944a25U, 0x4870381cU, 0xfca8542aU, 0x8ef47a3dU,
715 0x1e140a05U, 0xbf219e4fU, 0x07f1f67bU, 0x8bf279b2U,
716 0xacc86432U, 0x477a3d90U, 0xc58643afU, 0x56643219U,
717 0xedb65ba3U, 0x08fbf3f7U, 0x37d1e673U, 0x694e279dU,
718 0x7e542a15U, 0x25cde874U, 0x5e9fc1eeU, 0x860f89caU,
719 0x6546239fU, 0x223c1e0fU, 0x5a6c361bU, 0x23c9ea75U,
720 0x33221186U, 0x3f2a1584U, 0x6f4a259cU, 0xa135944aU,
721 0x55663397U, 0x5c68341aU, 0x4389ca65U, 0x0efff1f6U,
722 0x5493c7edU, 0x36241209U, 0xbdd66bbbU, 0xd4984c26U,
723 0x2d361b83U, 0x408bcbebU, 0x7fa1de6fU, 0x213e1f81U,
724 0x18100804U, 0x61b5d46aU, 0x97118643U, 0x06040201U,
725 0x725c2e17U, 0x7ca3dfe1U, 0x35261387U, 0x04f3f7f5U,
726 0x090e078dU, 0x70abdbe3U, 0xca8c4623U, 0x273a1d80U,
727 0x850d8844U, 0x74582c16U, 0x4985cc66U, 0xc6844221U,
728 0x3edfe1feU, 0xc473b7d5U, 0xa6c46231U, 0xec43afd9U,
729 0xbed46a35U, 0x50603018U, 0x0c080402U, 0x458dc864U,
730 0x16eff9f2U, 0x1ce3fff1U, 0xe945ac56U, 0x941387cdU,
731 0x2b321982U, 0x8a078dc8U, 0xbbd269baU, 0x1ae7fdf0U,
732 0x589bc3efU, 0x4c83cfe9U, 0x4a87cde8U, 0x34d3e7fdU,
733 0x111e0f89U, 0xc87bb3d7U, 0xa83b93c7U, 0x99ee77b5U,
734 0xffaa55a4U, 0xe2bc5e2fU, 0x596e3795U, 0x6a4c2613U,
735 0x3a2c160bU, 0x10ebfbf3U, 0x7aa7dde0U, 0xb2dc6e37U,
736 };
737
738 static const ulong32 T4[256] = {
739 0xa7a7a7a7U, 0xd3d3d3d3U, 0xe6e6e6e6U, 0x71717171U,
740 0xd0d0d0d0U, 0xacacacacU, 0x4d4d4d4dU, 0x79797979U,
741 0x3a3a3a3aU, 0xc9c9c9c9U, 0x91919191U, 0xfcfcfcfcU,
742 0x1e1e1e1eU, 0x47474747U, 0x54545454U, 0xbdbdbdbdU,
743 0x8c8c8c8cU, 0xa5a5a5a5U, 0x7a7a7a7aU, 0xfbfbfbfbU,
744 0x63636363U, 0xb8b8b8b8U, 0xddddddddU, 0xd4d4d4d4U,
745 0xe5e5e5e5U, 0xb3b3b3b3U, 0xc5c5c5c5U, 0xbebebebeU,
746 0xa9a9a9a9U, 0x88888888U, 0x0c0c0c0cU, 0xa2a2a2a2U,
747 0x39393939U, 0xdfdfdfdfU, 0x29292929U, 0xdadadadaU,
748 0x2b2b2b2bU, 0xa8a8a8a8U, 0xcbcbcbcbU, 0x4c4c4c4cU,
749 0x4b4b4b4bU, 0x22222222U, 0xaaaaaaaaU, 0x24242424U,
750 0x41414141U, 0x70707070U, 0xa6a6a6a6U, 0xf9f9f9f9U,
751 0x5a5a5a5aU, 0xe2e2e2e2U, 0xb0b0b0b0U, 0x36363636U,
752 0x7d7d7d7dU, 0xe4e4e4e4U, 0x33333333U, 0xffffffffU,
753 0x60606060U, 0x20202020U, 0x08080808U, 0x8b8b8b8bU,
754 0x5e5e5e5eU, 0xababababU, 0x7f7f7f7fU, 0x78787878U,
755 0x7c7c7c7cU, 0x2c2c2c2cU, 0x57575757U, 0xd2d2d2d2U,
756 0xdcdcdcdcU, 0x6d6d6d6dU, 0x7e7e7e7eU, 0x0d0d0d0dU,
757 0x53535353U, 0x94949494U, 0xc3c3c3c3U, 0x28282828U,
758 0x27272727U, 0x06060606U, 0x5f5f5f5fU, 0xadadadadU,
759 0x67676767U, 0x5c5c5c5cU, 0x55555555U, 0x48484848U,
760 0x0e0e0e0eU, 0x52525252U, 0xeaeaeaeaU, 0x42424242U,
761 0x5b5b5b5bU, 0x5d5d5d5dU, 0x30303030U, 0x58585858U,
762 0x51515151U, 0x59595959U, 0x3c3c3c3cU, 0x4e4e4e4eU,
763 0x38383838U, 0x8a8a8a8aU, 0x72727272U, 0x14141414U,
764 0xe7e7e7e7U, 0xc6c6c6c6U, 0xdedededeU, 0x50505050U,
765 0x8e8e8e8eU, 0x92929292U, 0xd1d1d1d1U, 0x77777777U,
766 0x93939393U, 0x45454545U, 0x9a9a9a9aU, 0xcecececeU,
767 0x2d2d2d2dU, 0x03030303U, 0x62626262U, 0xb6b6b6b6U,
768 0xb9b9b9b9U, 0xbfbfbfbfU, 0x96969696U, 0x6b6b6b6bU,
769 0x3f3f3f3fU, 0x07070707U, 0x12121212U, 0xaeaeaeaeU,
770 0x40404040U, 0x34343434U, 0x46464646U, 0x3e3e3e3eU,
771 0xdbdbdbdbU, 0xcfcfcfcfU, 0xececececU, 0xccccccccU,
772 0xc1c1c1c1U, 0xa1a1a1a1U, 0xc0c0c0c0U, 0xd6d6d6d6U,
773 0x1d1d1d1dU, 0xf4f4f4f4U, 0x61616161U, 0x3b3b3b3bU,
774 0x10101010U, 0xd8d8d8d8U, 0x68686868U, 0xa0a0a0a0U,
775 0xb1b1b1b1U, 0x0a0a0a0aU, 0x69696969U, 0x6c6c6c6cU,
776 0x49494949U, 0xfafafafaU, 0x76767676U, 0xc4c4c4c4U,
777 0x9e9e9e9eU, 0x9b9b9b9bU, 0x6e6e6e6eU, 0x99999999U,
778 0xc2c2c2c2U, 0xb7b7b7b7U, 0x98989898U, 0xbcbcbcbcU,
779 0x8f8f8f8fU, 0x85858585U, 0x1f1f1f1fU, 0xb4b4b4b4U,
780 0xf8f8f8f8U, 0x11111111U, 0x2e2e2e2eU, 0x00000000U,
781 0x25252525U, 0x1c1c1c1cU, 0x2a2a2a2aU, 0x3d3d3d3dU,
782 0x05050505U, 0x4f4f4f4fU, 0x7b7b7b7bU, 0xb2b2b2b2U,
783 0x32323232U, 0x90909090U, 0xafafafafU, 0x19191919U,
784 0xa3a3a3a3U, 0xf7f7f7f7U, 0x73737373U, 0x9d9d9d9dU,
785 0x15151515U, 0x74747474U, 0xeeeeeeeeU, 0xcacacacaU,
786 0x9f9f9f9fU, 0x0f0f0f0fU, 0x1b1b1b1bU, 0x75757575U,
787 0x86868686U, 0x84848484U, 0x9c9c9c9cU, 0x4a4a4a4aU,
788 0x97979797U, 0x1a1a1a1aU, 0x65656565U, 0xf6f6f6f6U,
789 0xededededU, 0x09090909U, 0xbbbbbbbbU, 0x26262626U,
790 0x83838383U, 0xebebebebU, 0x6f6f6f6fU, 0x81818181U,
791 0x04040404U, 0x6a6a6a6aU, 0x43434343U, 0x01010101U,
792 0x17171717U, 0xe1e1e1e1U, 0x87878787U, 0xf5f5f5f5U,
793 0x8d8d8d8dU, 0xe3e3e3e3U, 0x23232323U, 0x80808080U,
794 0x44444444U, 0x16161616U, 0x66666666U, 0x21212121U,
795 0xfefefefeU, 0xd5d5d5d5U, 0x31313131U, 0xd9d9d9d9U,
796 0x35353535U, 0x18181818U, 0x02020202U, 0x64646464U,
797 0xf2f2f2f2U, 0xf1f1f1f1U, 0x56565656U, 0xcdcdcdcdU,
798 0x82828282U, 0xc8c8c8c8U, 0xbabababaU, 0xf0f0f0f0U,
799 0xefefefefU, 0xe9e9e9e9U, 0xe8e8e8e8U, 0xfdfdfdfdU,
800 0x89898989U, 0xd7d7d7d7U, 0xc7c7c7c7U, 0xb5b5b5b5U,
801 0xa4a4a4a4U, 0x2f2f2f2fU, 0x95959595U, 0x13131313U,
802 0x0b0b0b0bU, 0xf3f3f3f3U, 0xe0e0e0e0U, 0x37373737U,
803 };
804
805 static const ulong32 T5[256] = {
806 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U,
807 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U,
808 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U,
809 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U,
810 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U,
811 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U,
812 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U,
813 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U,
814 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U,
815 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U,
816 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U,
817 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U,
818 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U,
819 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U,
820 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U,
821 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U,
822 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U,
823 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U,
824 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U,
825 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U,
826 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U,
827 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U,
828 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U,
829 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U,
830 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU,
831 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU,
832 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU,
833 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU,
834 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU,
835 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU,
836 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU,
837 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU,
838 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU,
839 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU,
840 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU,
841 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU,
842 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU,
843 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU,
844 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU,
845 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU,
846 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U,
847 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U,
848 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U,
849 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U,
850 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U,
851 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U,
852 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U,
853 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U,
854 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U,
855 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U,
856 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U,
857 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U,
858 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U,
859 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U,
860 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U,
861 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U,
862 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU,
863 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU,
864 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU,
865 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU,
866 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU,
867 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU,
868 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU,
869 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU,
870 };
871
872 /**
873 * The round constants.
874 */
875 static const ulong32 rc[] = {
876 0xa7d3e671U, 0xd0ac4d79U, 0x3ac991fcU, 0x1e4754bdU,
877 0x8ca57afbU, 0x63b8ddd4U, 0xe5b3c5beU, 0xa9880ca2U,
878 0x39df29daU, 0x2ba8cb4cU, 0x4b22aa24U, 0x4170a6f9U,
879 0x5ae2b036U, 0x7de433ffU, 0x6020088bU, 0x5eab7f78U,
880 0x7c2c57d2U, 0xdc6d7e0dU, 0x5394c328U,
881 };
882
883 #endif
884
885 /**
886 Initialize the Anubis block cipher
887 @param key The symmetric key you wish to pass
888 @param keylen The key length in bytes
889 @param num_rounds The number of rounds desired (0 for default)
890 @param skey The key in as scheduled by this function.
891 @return CRYPT_OK if successful
892 */
893 #ifdef LTC_CLEAN_STACK
894 static int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
895 #else
896 int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
897 #endif
898 {
899 int N, R, i, pos, r;
900 ulong32 kappa[MAX_N];
901 ulong32 inter[MAX_N];
902 ulong32 v, K0, K1, K2, K3;
903
904 LTC_ARGCHK(key != NULL);
905 LTC_ARGCHK(skey != NULL);
906
907 /* Valid sizes (in bytes) are 16, 20, 24, 28, 32, 36, and 40. */
908 if ((keylen & 3) || (keylen < 16) || (keylen > 40)) {
909 return CRYPT_INVALID_KEYSIZE;
910 }
911 skey->anubis.keyBits = keylen*8;
912
913 /*
914 * determine the N length parameter:
915 * (N.B. it is assumed that the key length is valid!)
916 */
917 N = skey->anubis.keyBits >> 5;
918
919 /*
920 * determine number of rounds from key size:
921 */
922 skey->anubis.R = R = 8 + N;
923
924 if (num_rounds != 0 && num_rounds != skey->anubis.R) {
925 return CRYPT_INVALID_ROUNDS;
926 }
927
928 /*
929 * map cipher key to initial key state (mu):
930 */
931 for (i = 0, pos = 0; i < N; i++, pos += 4) {
932 kappa[i] =
933 (key[pos ] << 24) ^
934 (key[pos + 1] << 16) ^
935 (key[pos + 2] << 8) ^
936 (key[pos + 3] );
937 }
938
939 /*
940 * generate R + 1 round keys:
941 */
942 for (r = 0; r <= R; r++) {
943 /*
944 * generate r-th round key K^r:
945 */
946 K0 = T4[(kappa[N - 1] >> 24) & 0xff];
947 K1 = T4[(kappa[N - 1] >> 16) & 0xff];
948 K2 = T4[(kappa[N - 1] >> 8) & 0xff];
949 K3 = T4[(kappa[N - 1] ) & 0xff];
950 for (i = N - 2; i >= 0; i--) {
951 K0 = T4[(kappa[i] >> 24) & 0xff] ^
952 (T5[(K0 >> 24) & 0xff] & 0xff000000U) ^
953 (T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^
954 (T5[(K0 >> 8) & 0xff] & 0x0000ff00U) ^
955 (T5[(K0 ) & 0xff] & 0x000000ffU);
956 K1 = T4[(kappa[i] >> 16) & 0xff] ^
957 (T5[(K1 >> 24) & 0xff] & 0xff000000U) ^
958 (T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^
959 (T5[(K1 >> 8) & 0xff] & 0x0000ff00U) ^
960 (T5[(K1 ) & 0xff] & 0x000000ffU);
961 K2 = T4[(kappa[i] >> 8) & 0xff] ^
962 (T5[(K2 >> 24) & 0xff] & 0xff000000U) ^
963 (T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^
964 (T5[(K2 >> 8) & 0xff] & 0x0000ff00U) ^
965 (T5[(K2 ) & 0xff] & 0x000000ffU);
966 K3 = T4[(kappa[i] ) & 0xff] ^
967 (T5[(K3 >> 24) & 0xff] & 0xff000000U) ^
968 (T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^
969 (T5[(K3 >> 8) & 0xff] & 0x0000ff00U) ^
970 (T5[(K3 ) & 0xff] & 0x000000ffU);
971 }
972 /*
973 -- this is the code to use with the large U tables:
974 K0 = K1 = K2 = K3 = 0;
975 for (i = 0; i < N; i++) {
976 K0 ^= U[i][(kappa[i] >> 24) & 0xff];
977 K1 ^= U[i][(kappa[i] >> 16) & 0xff];
978 K2 ^= U[i][(kappa[i] >> 8) & 0xff];
979 K3 ^= U[i][(kappa[i] ) & 0xff];
980 }
981 */
982 skey->anubis.roundKeyEnc[r][0] = K0;
983 skey->anubis.roundKeyEnc[r][1] = K1;
984 skey->anubis.roundKeyEnc[r][2] = K2;
985 skey->anubis.roundKeyEnc[r][3] = K3;
986
987 /*
988 * compute kappa^{r+1} from kappa^r:
989 */
990 if (r == R) {
991 break;
992 }
993 for (i = 0; i < N; i++) {
994 int j = i;
995 inter[i] = T0[(kappa[j--] >> 24) & 0xff]; if (j < 0) j = N - 1;
996 inter[i] ^= T1[(kappa[j--] >> 16) & 0xff]; if (j < 0) j = N - 1;
997 inter[i] ^= T2[(kappa[j--] >> 8) & 0xff]; if (j < 0) j = N - 1;
998 inter[i] ^= T3[(kappa[j ] ) & 0xff];
999 }
1000 kappa[0] = inter[0] ^ rc[r];
1001 for (i = 1; i < N; i++) {
1002 kappa[i] = inter[i];
1003 }
1004 }
1005
1006 /*
1007 * generate inverse key schedule: K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}):
1008 */
1009 for (i = 0; i < 4; i++) {
1010 skey->anubis.roundKeyDec[0][i] = skey->anubis.roundKeyEnc[R][i];
1011 skey->anubis.roundKeyDec[R][i] = skey->anubis.roundKeyEnc[0][i];
1012 }
1013 for (r = 1; r < R; r++) {
1014 for (i = 0; i < 4; i++) {
1015 v = skey->anubis.roundKeyEnc[R - r][i];
1016 skey->anubis.roundKeyDec[r][i] =
1017 T0[T4[(v >> 24) & 0xff] & 0xff] ^
1018 T1[T4[(v >> 16) & 0xff] & 0xff] ^
1019 T2[T4[(v >> 8) & 0xff] & 0xff] ^
1020 T3[T4[(v ) & 0xff] & 0xff];
1021 }
1022 }
1023
1024 return CRYPT_OK;
1025 }
1026
1027 #ifdef LTC_CLEAN_STACK
1028 int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
1029 {
1030 int err;
1031 err = _anubis_setup(key, keylen, num_rounds, skey);
1032 burn_stack(sizeof(int) * 5 + sizeof(ulong32) * (MAX_N + MAX_N + 5));
1033 return err;
1034 }
1035 #endif
1036
1037
1038 static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext,
1039 ulong32 roundKey[18 + 1][4], int R) {
1040 int i, pos, r;
1041 ulong32 state[4];
1042 ulong32 inter[4];
1043
1044 /*
1045 * map plaintext block to cipher state (mu)
1046 * and add initial round key (sigma[K^0]):
1047 */
1048 for (i = 0, pos = 0; i < 4; i++, pos += 4) {
1049 state[i] =
1050 (plaintext[pos ] << 24) ^
1051 (plaintext[pos + 1] << 16) ^
1052 (plaintext[pos + 2] << 8) ^
1053 (plaintext[pos + 3] ) ^
1054 roundKey[0][i];
1055 }
1056
1057 /*
1058 * R - 1 full rounds:
1059 */
1060 for (r = 1; r < R; r++) {
1061 inter[0] =
1062 T0[(state[0] >> 24) & 0xff] ^
1063 T1[(state[1] >> 24) & 0xff] ^
1064 T2[(state[2] >> 24) & 0xff] ^
1065 T3[(state[3] >> 24) & 0xff] ^
1066 roundKey[r][0];
1067 inter[1] =
1068 T0[(state[0] >> 16) & 0xff] ^
1069 T1[(state[1] >> 16) & 0xff] ^
1070 T2[(state[2] >> 16) & 0xff] ^
1071 T3[(state[3] >> 16) & 0xff] ^
1072 roundKey[r][1];
1073 inter[2] =
1074 T0[(state[0] >> 8) & 0xff] ^
1075 T1[(state[1] >> 8) & 0xff] ^
1076 T2[(state[2] >> 8) & 0xff] ^
1077 T3[(state[3] >> 8) & 0xff] ^
1078 roundKey[r][2];
1079 inter[3] =
1080 T0[(state[0] ) & 0xff] ^
1081 T1[(state[1] ) & 0xff] ^
1082 T2[(state[2] ) & 0xff] ^
1083 T3[(state[3] ) & 0xff] ^
1084 roundKey[r][3];
1085 state[0] = inter[0];
1086 state[1] = inter[1];
1087 state[2] = inter[2];
1088 state[3] = inter[3];
1089 }
1090
1091 /*
1092 * last round:
1093 */
1094 inter[0] =
1095 (T0[(state[0] >> 24) & 0xff] & 0xff000000U) ^
1096 (T1[(state[1] >> 24) & 0xff] & 0x00ff0000U) ^
1097 (T2[(state[2] >> 24) & 0xff] & 0x0000ff00U) ^
1098 (T3[(state[3] >> 24) & 0xff] & 0x000000ffU) ^
1099 roundKey[R][0];
1100 inter[1] =
1101 (T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^
1102 (T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^
1103 (T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^
1104 (T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^
1105 roundKey[R][1];
1106 inter[2] =
1107 (T0[(state[0] >> 8) & 0xff] & 0xff000000U) ^
1108 (T1[(state[1] >> 8) & 0xff] & 0x00ff0000U) ^
1109 (T2[(state[2] >> 8) & 0xff] & 0x0000ff00U) ^
1110 (T3[(state[3] >> 8) & 0xff] & 0x000000ffU) ^
1111 roundKey[R][2];
1112 inter[3] =
1113 (T0[(state[0] ) & 0xff] & 0xff000000U) ^
1114 (T1[(state[1] ) & 0xff] & 0x00ff0000U) ^
1115 (T2[(state[2] ) & 0xff] & 0x0000ff00U) ^
1116 (T3[(state[3] ) & 0xff] & 0x000000ffU) ^
1117 roundKey[R][3];
1118
1119 /*
1120 * map cipher state to ciphertext block (mu^{-1}):
1121 */
1122 for (i = 0, pos = 0; i < 4; i++, pos += 4) {
1123 ulong32 w = inter[i];
1124 ciphertext[pos ] = (unsigned char)(w >> 24);
1125 ciphertext[pos + 1] = (unsigned char)(w >> 16);
1126 ciphertext[pos + 2] = (unsigned char)(w >> 8);
1127 ciphertext[pos + 3] = (unsigned char)(w );
1128 }
1129 }
1130
1131 /**
1132 Encrypts a block of text with Anubis
1133 @param pt The input plaintext (16 bytes)
1134 @param ct The output ciphertext (16 bytes)
1135 @param skey The key as scheduled
1136 @return CRYPT_OK if successful
1137 */
1138 int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
1139 {
1140 LTC_ARGCHK(pt != NULL);
1141 LTC_ARGCHK(ct != NULL);
1142 LTC_ARGCHK(skey != NULL);
1143 anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R);
1144 return CRYPT_OK;
1145 }
1146
1147 /**
1148 Decrypts a block of text with Anubis
1149 @param ct The input ciphertext (16 bytes)
1150 @param pt The output plaintext (16 bytes)
1151 @param skey The key as scheduled
1152 @return CRYPT_OK if successful
1153 */
1154 int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
1155 {
1156 LTC_ARGCHK(pt != NULL);
1157 LTC_ARGCHK(ct != NULL);
1158 LTC_ARGCHK(skey != NULL);
1159 anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R);
1160 return CRYPT_OK;
1161 }
1162
1163 /**
1164 Performs a self-test of the Anubis block cipher
1165 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
1166 */
1167 int anubis_test(void)
1168 {
1169 #if !defined(LTC_TEST)
1170 return CRYPT_NOP;
1171 #else
1172 static const struct test {
1173 int keylen;
1174 unsigned char pt[16], ct[16], key[40];
1175 } tests[] = {
1176 #ifndef LTC_ANUBIS_TWEAK
1177 /**** ORIGINAL LTC_ANUBIS ****/
1178 /* 128 bit keys */
1179 {
1180 16,
1181 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1183 { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18,
1184 0xF1, 0x32, 0xC7, 0x8A, 0xF4, 0x13, 0x2A, 0xFE },
1185 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1187 }, {
1188 16,
1189 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1191 { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89,
1192 0xFC, 0x5E, 0xB5, 0xBA, 0xD4, 0xFE, 0x32, 0x6D },
1193 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1195 },
1196
1197 /* 160-bit keys */
1198 {
1199 20,
1200 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1202 { 0xBD, 0x5E, 0x32, 0xBE, 0x51, 0x67, 0xA8, 0xE2,
1203 0x72, 0xD7, 0x95, 0x0F, 0x83, 0xC6, 0x8C, 0x31 },
1204 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1206 0x00, 0x00, 0x00, 0x00 }
1207 }, {
1208 20,
1209 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1211 { 0x4C, 0x1F, 0x86, 0x2E, 0x11, 0xEB, 0xCE, 0xEB,
1212 0xFE, 0xB9, 0x73, 0xC9, 0xDF, 0xEF, 0x7A, 0xDB },
1213 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1215 0x00, 0x00, 0x00, 0x01 }
1216 },
1217
1218 /* 192-bit keys */
1219 {
1220 24,
1221 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1223 { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66,
1224 0xD0, 0xC7, 0x9E, 0x04, 0x7C, 0xC7, 0x58, 0xF0 },
1225 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1228 }, {
1229 24,
1230 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1232 { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD,
1233 0x57, 0x14, 0x5F, 0x57, 0x04, 0x9F, 0x70, 0x74 },
1234 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1237 },
1238
1239 /* 224-bit keys */
1240 {
1241 28,
1242 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1244 { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B,
1245 0xEF, 0x08, 0xE8, 0x7A, 0x58, 0xD6, 0xF8, 0x53 },
1246 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x00 }
1250 }, {
1251 28,
1252 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1254 { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53,
1255 0x8B, 0xC4, 0x32, 0x6A, 0xF5, 0xB9, 0x1B, 0x5F },
1256 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1259 0x00, 0x00, 0x00, 0x01 }
1260 },
1261
1262 /* 256-bit keys */
1263 {
1264 32,
1265 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1267 { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13,
1268 0xED, 0xF5, 0xDF, 0xDD, 0xD6, 0x3B, 0x71, 0x93 },
1269 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1273 }, {
1274 32,
1275 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1277 { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29,
1278 0x00, 0xD5, 0xEC, 0x98, 0x2B, 0x9E, 0xE8, 0x21 },
1279 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1282 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1283 },
1284
1285 /* 288-bit keys */
1286 {
1287 36,
1288 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1290 { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B,
1291 0x41, 0x95, 0xB9, 0x71, 0x75, 0x79, 0x04, 0x7C },
1292 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1296 0x00, 0x00, 0x00, 0x00 }
1297 }, {
1298 36,
1299 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1301 { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2,
1302 0xBD, 0xA7, 0xA7, 0x53, 0xAB, 0x40, 0x22, 0xE0 },
1303 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307 0x00, 0x00, 0x00, 0x01 }
1308 },
1309
1310 /* 320-bit keys */
1311 {
1312 40,
1313 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1315 { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02,
1316 0x4B, 0xCC, 0x39, 0x80, 0xD8, 0x22, 0xEA, 0xA4 },
1317 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1322 }, {
1323 40,
1324 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1326 { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0,
1327 0x44, 0xA8, 0x3C, 0x73, 0x81, 0x7E, 0x53, 0xD8 },
1328 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1333 }
1334 #else
1335 /**** Tweaked LTC_ANUBIS ****/
1336 /* 128 bit keys */
1337 {
1338 16,
1339 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1341 { 0xB8, 0x35, 0xBD, 0xC3, 0x34, 0x82, 0x9D, 0x83,
1342 0x71, 0xBF, 0xA3, 0x71, 0xE4, 0xB3, 0xC4, 0xFD },
1343 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1345 }, {
1346 16,
1347 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1349 { 0xE6, 0x14, 0x1E, 0xAF, 0xEB, 0xE0, 0x59, 0x3C,
1350 0x48, 0xE1, 0xCD, 0xF2, 0x1B, 0xBA, 0xA1, 0x89 },
1351 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1353 },
1354
1355 /* 160-bit keys */
1356 {
1357 20,
1358 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1360 { 0x97, 0x59, 0x79, 0x4B, 0x5C, 0xA0, 0x70, 0x73,
1361 0x24, 0xEF, 0xB3, 0x58, 0x67, 0xCA, 0xD4, 0xB3 },
1362 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00 }
1365 }, {
1366 20,
1367 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1369 { 0xB8, 0x0D, 0xFB, 0x9B, 0xE4, 0xA1, 0x58, 0x87,
1370 0xB3, 0x76, 0xD5, 0x02, 0x18, 0x95, 0xC1, 0x2E },
1371 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373 0x00, 0x00, 0x00, 0x01 }
1374 },
1375
1376 /* 192-bit keys */
1377 {
1378 24,
1379 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1381 { 0x7D, 0x62, 0x3B, 0x52, 0xC7, 0x4C, 0x64, 0xD8,
1382 0xEB, 0xC7, 0x2D, 0x57, 0x97, 0x85, 0x43, 0x8F },
1383 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1386 }, {
1387 24,
1388 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1390 { 0xB1, 0x0A, 0x59, 0xDD, 0x5D, 0x5D, 0x8D, 0x67,
1391 0xEC, 0xEE, 0x4A, 0xC4, 0xBE, 0x4F, 0xA8, 0x4F },
1392 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1395 },
1396
1397 /* 224-bit keys */
1398 {
1399 28,
1400 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1402 { 0x68, 0x9E, 0x05, 0x94, 0x6A, 0x94, 0x43, 0x8F,
1403 0xE7, 0x8E, 0x37, 0x3D, 0x24, 0x97, 0x92, 0xF5 },
1404 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1407 0x00, 0x00, 0x00, 0x00 }
1408 }, {
1409 28,
1410 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1412 { 0xDD, 0xB7, 0xB0, 0xB4, 0xE9, 0xB4, 0x9B, 0x9C,
1413 0x38, 0x20, 0x25, 0x0B, 0x47, 0xC2, 0x1F, 0x89 },
1414 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1417 0x00, 0x00, 0x00, 0x01 }
1418 },
1419
1420 /* 256-bit keys */
1421 {
1422 32,
1423 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1425 { 0x96, 0x00, 0xF0, 0x76, 0x91, 0x69, 0x29, 0x87,
1426 0xF5, 0xE5, 0x97, 0xDB, 0xDB, 0xAF, 0x1B, 0x0A },
1427 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1431 }, {
1432 32,
1433 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1435 { 0x69, 0x9C, 0xAF, 0xDD, 0x94, 0xC7, 0xBC, 0x60,
1436 0x44, 0xFE, 0x02, 0x05, 0x8A, 0x6E, 0xEF, 0xBD },
1437 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1441 },
1442
1443 /* 288-bit keys */
1444 {
1445 36,
1446 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1448 { 0x0F, 0xC7, 0xA2, 0xC0, 0x11, 0x17, 0xAC, 0x43,
1449 0x52, 0x5E, 0xDF, 0x6C, 0xF3, 0x96, 0x33, 0x6C },
1450 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1454 0x00, 0x00, 0x00, 0x00 }
1455 }, {
1456 36,
1457 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1459 { 0xAD, 0x08, 0x4F, 0xED, 0x55, 0xA6, 0x94, 0x3E,
1460 0x7E, 0x5E, 0xED, 0x05, 0xA1, 0x9D, 0x41, 0xB4 },
1461 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1465 0x00, 0x00, 0x00, 0x01 }
1466 },
1467
1468 /* 320-bit keys */
1469 {
1470 40,
1471 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1473 { 0xFE, 0xE2, 0x0E, 0x2A, 0x9D, 0xC5, 0x83, 0xBA,
1474 0xA3, 0xA6, 0xD6, 0xA6, 0xF2, 0xE8, 0x06, 0xA5 },
1475 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
1480 }, {
1481 40,
1482 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1484 { 0x86, 0x3D, 0xCC, 0x4A, 0x60, 0x34, 0x9C, 0x28,
1485 0xA7, 0xDA, 0xA4, 0x3B, 0x0A, 0xD7, 0xFD, 0xC7 },
1486 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
1491 }
1492 #endif
1493 };
1494 int x, y;
1495 unsigned char buf[2][16];
1496 symmetric_key skey;
1497
1498 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
1499 anubis_setup(tests[x].key, tests[x].keylen, 0, &skey);
1500 anubis_ecb_encrypt(tests[x].pt, buf[0], &skey);
1501 anubis_ecb_decrypt(buf[0], buf[1], &skey);
1502 if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) {
1503 return CRYPT_FAIL_TESTVECTOR;
1504 }
1505
1506 for (y = 0; y < 1000; y++) anubis_ecb_encrypt(buf[0], buf[0], &skey);
1507 for (y = 0; y < 1000; y++) anubis_ecb_decrypt(buf[0], buf[0], &skey);
1508 if (XMEMCMP(buf[0], tests[x].ct, 16)) {
1509 return CRYPT_FAIL_TESTVECTOR;
1510 }
1511
1512 }
1513 return CRYPT_OK;
1514 #endif
1515 }
1516
1517 /** Terminate the context
1518 @param skey The scheduled key
1519 */
1520 void anubis_done(symmetric_key *skey)
1521 {
1522 }
1523
1524 /**
1525 Gets suitable key size
1526 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
1527 @return CRYPT_OK if the input key size is acceptable.
1528 */
1529 int anubis_keysize(int *keysize)
1530 {
1531 LTC_ARGCHK(keysize != NULL);
1532 if (*keysize >= 40) {
1533 *keysize = 40;
1534 } else if (*keysize >= 36) {
1535 *keysize = 36;
1536 } else if (*keysize >= 32) {
1537 *keysize = 32;
1538 } else if (*keysize >= 28) {
1539 *keysize = 28;
1540 } else if (*keysize >= 24) {
1541 *keysize = 24;
1542 } else if (*keysize >= 20) {
1543 *keysize = 20;
1544 } else if (*keysize >= 16) {
1545 *keysize = 16;
1546 } else {
1547 return CRYPT_INVALID_KEYSIZE;
1548 }
1549 return CRYPT_OK;
1550 }
1551
1552 #endif
1553
1554
1555 /* $Source$ */
1556 /* $Revision$ */
1557 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @file blowfish.c
12 Implementation of the Blowfish block cipher, Tom St Denis
13 */
14 #include "tomcrypt.h"
15
16 #ifdef LTC_BLOWFISH
17
18 const struct ltc_cipher_descriptor blowfish_desc =
19 {
20 "blowfish",
21 0,
22 8, 56, 8, 16,
23 &blowfish_setup,
24 &blowfish_ecb_encrypt,
25 &blowfish_ecb_decrypt,
26 &blowfish_test,
27 &blowfish_done,
28 &blowfish_keysize,
29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
30 };
31
32 static const ulong32 ORIG_P[16 + 2] = {
33 0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL,
34 0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL,
35 0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL,
36 0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL,
37 0x9216D5D9UL, 0x8979FB1BUL
38 };
39
40 static const ulong32 ORIG_S[4][256] = {
41 { 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL,
42 0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL,
43 0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL,
44 0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL,
45 0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL,
46 0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL,
47 0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL,
48 0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL,
49 0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL,
50 0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL,
51 0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL,
52 0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL,
53 0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL,
54 0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL,
55 0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL,
56 0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL,
57 0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL,
58 0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL,
59 0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL,
60 0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL,
61 0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL,
62 0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL,
63 0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL,
64 0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL,
65 0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL,
66 0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL,
67 0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL,
68 0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL,
69 0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL,
70 0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL,
71 0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL,
72 0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL,
73 0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL,
74 0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL,
75 0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL,
76 0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL,
77 0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL,
78 0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL,
79 0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL,
80 0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL,
81 0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL,
82 0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL,
83 0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL,
84 0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL,
85 0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL,
86 0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL,
87 0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL,
88 0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL,
89 0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL,
90 0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL,
91 0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL,
92 0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL,
93 0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL,
94 0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL,
95 0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL,
96 0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL,
97 0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL,
98 0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL,
99 0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL,
100 0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL,
101 0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL,
102 0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL,
103 0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL,
104 0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL },
105 { 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL,
106 0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL,
107 0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL,
108 0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL,
109 0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL,
110 0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL,
111 0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL,
112 0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL,
113 0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL,
114 0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL,
115 0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL,
116 0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL,
117 0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL,
118 0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL,
119 0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL,
120 0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL,
121 0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL,
122 0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL,
123 0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL,
124 0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL,
125 0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL,
126 0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL,
127 0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL,
128 0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL,
129 0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL,
130 0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL,
131 0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL,
132 0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL,
133 0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL,
134 0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL,
135 0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL,
136 0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL,
137 0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL,
138 0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL,
139 0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL,
140 0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL,
141 0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL,
142 0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL,
143 0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL,
144 0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL,
145 0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL,
146 0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL,
147 0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL,
148 0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL,
149 0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL,
150 0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL,
151 0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL,
152 0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL,
153 0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL,
154 0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL,
155 0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL,
156 0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL,
157 0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL,
158 0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL,
159 0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL,
160 0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL,
161 0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL,
162 0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL,
163 0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL,
164 0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL,
165 0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL,
166 0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL,
167 0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL,
168 0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL },
169 { 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL,
170 0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL,
171 0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL,
172 0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL,
173 0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL,
174 0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL,
175 0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL,
176 0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL,
177 0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL,
178 0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL,
179 0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL,
180 0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL,
181 0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL,
182 0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL,
183 0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL,
184 0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL,
185 0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL,
186 0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL,
187 0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL,
188 0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL,
189 0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL,
190 0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL,
191 0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL,
192 0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL,
193 0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL,
194 0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL,
195 0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL,
196 0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL,
197 0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL,
198 0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL,
199 0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL,
200 0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL,
201 0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL,
202 0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL,
203 0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL,
204 0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL,
205 0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL,
206 0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL,
207 0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL,
208 0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL,
209 0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL,
210 0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL,
211 0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL,
212 0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL,
213 0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL,
214 0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL,
215 0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL,
216 0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL,
217 0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL,
218 0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL,
219 0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL,
220 0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL,
221 0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL,
222 0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL,
223 0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL,
224 0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL,
225 0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL,
226 0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL,
227 0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL,
228 0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL,
229 0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL,
230 0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL,
231 0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL,
232 0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL },
233 { 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL,
234 0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL,
235 0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL,
236 0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL,
237 0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL,
238 0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL,
239 0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL,
240 0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL,
241 0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL,
242 0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL,
243 0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL,
244 0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL,
245 0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL,
246 0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL,
247 0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL,
248 0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL,
249 0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL,
250 0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL,
251 0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL,
252 0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL,
253 0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL,
254 0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL,
255 0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL,
256 0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL,
257 0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL,
258 0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL,
259 0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL,
260 0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL,
261 0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL,
262 0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL,
263 0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL,
264 0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL,
265 0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL,
266 0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL,
267 0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL,
268 0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL,
269 0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL,
270 0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL,
271 0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL,
272 0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL,
273 0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL,
274 0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL,
275 0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL,
276 0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL,
277 0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL,
278 0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL,
279 0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL,
280 0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL,
281 0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL,
282 0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL,
283 0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL,
284 0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL,
285 0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL,
286 0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL,
287 0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL,
288 0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL,
289 0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL,
290 0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL,
291 0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL,
292 0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL,
293 0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL,
294 0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL,
295 0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL,
296 0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL }
297 };
298
299 /**
300 Initialize the Blowfish block cipher
301 @param key The symmetric key you wish to pass
302 @param keylen The key length in bytes
303 @param num_rounds The number of rounds desired (0 for default)
304 @param skey The key in as scheduled by this function.
305 @return CRYPT_OK if successful
306 */
307 int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
308 symmetric_key *skey)
309 {
310 ulong32 x, y, z, A;
311 unsigned char B[8];
312
313 LTC_ARGCHK(key != NULL);
314 LTC_ARGCHK(skey != NULL);
315
316 /* check key length */
317 if (keylen < 8 || keylen > 56) {
318 return CRYPT_INVALID_KEYSIZE;
319 }
320
321 /* check rounds */
322 if (num_rounds != 0 && num_rounds != 16) {
323 return CRYPT_INVALID_ROUNDS;
324 }
325
326 /* load in key bytes (Supplied by David Hopwood) */
327 for (x = y = 0; x < 18; x++) {
328 A = 0;
329 for (z = 0; z < 4; z++) {
330 A = (A << 8) | ((ulong32)key[y++] & 255);
331 if (y == (ulong32)keylen) {
332 y = 0;
333 }
334 }
335 skey->blowfish.K[x] = ORIG_P[x] ^ A;
336 }
337
338 /* copy sboxes */
339 for (x = 0; x < 4; x++) {
340 for (y = 0; y < 256; y++) {
341 skey->blowfish.S[x][y] = ORIG_S[x][y];
342 }
343 }
344
345 /* encrypt K array */
346 for (x = 0; x < 8; x++) {
347 B[x] = 0;
348 }
349
350 for (x = 0; x < 18; x += 2) {
351 /* encrypt it */
352 blowfish_ecb_encrypt(B, B, skey);
353 /* copy it */
354 LOAD32H(skey->blowfish.K[x], &B[0]);
355 LOAD32H(skey->blowfish.K[x+1], &B[4]);
356 }
357
358 /* encrypt S array */
359 for (x = 0; x < 4; x++) {
360 for (y = 0; y < 256; y += 2) {
361 /* encrypt it */
362 blowfish_ecb_encrypt(B, B, skey);
363 /* copy it */
364 LOAD32H(skey->blowfish.S[x][y], &B[0]);
365 LOAD32H(skey->blowfish.S[x][y+1], &B[4]);
366 }
367 }
368
369 #ifdef LTC_CLEAN_STACK
370 zeromem(B, sizeof(B));
371 #endif
372
373 return CRYPT_OK;
374 }
375
376 #ifndef __GNUC__
377 #define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)]
378 #else
379 #define F(x) ((skey->blowfish.S[0][byte(x,3)] + skey->blowfish.S[1][byte(x,2)]) ^ skey->blowfish.S[2][byte(x,1)]) + skey->blowfish.S[3][byte(x,0)]
380 #endif
381
382 /**
383 Encrypts a block of text with Blowfish
384 @param pt The input plaintext (8 bytes)
385 @param ct The output ciphertext (8 bytes)
386 @param skey The key as scheduled
387 @return CRYPT_OK if successful
388 */
389 #ifdef LTC_CLEAN_STACK
390 static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
391 #else
392 int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
393 #endif
394 {
395 ulong32 L, R;
396 int r;
397 #ifndef __GNUC__
398 ulong32 *S1, *S2, *S3, *S4;
399 #endif
400
401 LTC_ARGCHK(pt != NULL);
402 LTC_ARGCHK(ct != NULL);
403 LTC_ARGCHK(skey != NULL);
404
405 #ifndef __GNUC__
406 S1 = skey->blowfish.S[0];
407 S2 = skey->blowfish.S[1];
408 S3 = skey->blowfish.S[2];
409 S4 = skey->blowfish.S[3];
410 #endif
411
412 /* load it */
413 LOAD32H(L, &pt[0]);
414 LOAD32H(R, &pt[4]);
415
416 /* do 16 rounds */
417 for (r = 0; r < 16; ) {
418 L ^= skey->blowfish.K[r++]; R ^= F(L);
419 R ^= skey->blowfish.K[r++]; L ^= F(R);
420 L ^= skey->blowfish.K[r++]; R ^= F(L);
421 R ^= skey->blowfish.K[r++]; L ^= F(R);
422 }
423
424 /* last keying */
425 R ^= skey->blowfish.K[17];
426 L ^= skey->blowfish.K[16];
427
428 /* store */
429 STORE32H(R, &ct[0]);
430 STORE32H(L, &ct[4]);
431
432 return CRYPT_OK;
433 }
434
435 #ifdef LTC_CLEAN_STACK
436 int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
437 {
438 int err = _blowfish_ecb_encrypt(pt, ct, skey);
439 burn_stack(sizeof(ulong32) * 2 + sizeof(int));
440 return err;
441 }
442 #endif
443
444 /**
445 Decrypts a block of text with Blowfish
446 @param ct The input ciphertext (8 bytes)
447 @param pt The output plaintext (8 bytes)
448 @param skey The key as scheduled
449 @return CRYPT_OK if successful
450 */
451 #ifdef LTC_CLEAN_STACK
452 static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
453 #else
454 int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
455 #endif
456 {
457 ulong32 L, R;
458 int r;
459 #ifndef __GNUC__
460 ulong32 *S1, *S2, *S3, *S4;
461 #endif
462
463 LTC_ARGCHK(pt != NULL);
464 LTC_ARGCHK(ct != NULL);
465 LTC_ARGCHK(skey != NULL);
466
467 #ifndef __GNUC__
468 S1 = skey->blowfish.S[0];
469 S2 = skey->blowfish.S[1];
470 S3 = skey->blowfish.S[2];
471 S4 = skey->blowfish.S[3];
472 #endif
473
474 /* load it */
475 LOAD32H(R, &ct[0]);
476 LOAD32H(L, &ct[4]);
477
478 /* undo last keying */
479 R ^= skey->blowfish.K[17];
480 L ^= skey->blowfish.K[16];
481
482 /* do 16 rounds */
483 for (r = 15; r > 0; ) {
484 L ^= F(R); R ^= skey->blowfish.K[r--];
485 R ^= F(L); L ^= skey->blowfish.K[r--];
486 L ^= F(R); R ^= skey->blowfish.K[r--];
487 R ^= F(L); L ^= skey->blowfish.K[r--];
488 }
489
490 /* store */
491 STORE32H(L, &pt[0]);
492 STORE32H(R, &pt[4]);
493 return CRYPT_OK;
494 }
495
496 #ifdef LTC_CLEAN_STACK
497 int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
498 {
499 int err = _blowfish_ecb_decrypt(ct, pt, skey);
500 burn_stack(sizeof(ulong32) * 2 + sizeof(int));
501 return err;
502 }
503 #endif
504
505
506 /**
507 Performs a self-test of the Blowfish block cipher
508 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
509 */
510 int blowfish_test(void)
511 {
512 #ifndef LTC_TEST
513 return CRYPT_NOP;
514 #else
515 int err;
516 symmetric_key key;
517 static const struct {
518 unsigned char key[8], pt[8], ct[8];
519 } tests[] = {
520 {
521 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
522 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
523 { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}
524 },
525 {
526 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
527 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
528 { 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}
529 },
530 {
531 { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
532 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
533 { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}
534 }
535 };
536 unsigned char tmp[2][8];
537 int x, y;
538
539 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
540 /* setup key */
541 if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) {
542 return err;
543 }
544
545 /* encrypt and decrypt */
546 blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key);
547 blowfish_ecb_decrypt(tmp[0], tmp[1], &key);
548
549 /* compare */
550 if ((XMEMCMP(tmp[0], tests[x].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[x].pt, 8) != 0)) {
551 return CRYPT_FAIL_TESTVECTOR;
552 }
553
554 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
555 for (y = 0; y < 8; y++) tmp[0][y] = 0;
556 for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key);
557 for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key);
558 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
559 }
560 return CRYPT_OK;
561 #endif
562 }
563
564 /** Terminate the context
565 @param skey The scheduled key
566 */
567 void blowfish_done(symmetric_key *skey)
568 {
569 }
570
571 /**
572 Gets suitable key size
573 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
574 @return CRYPT_OK if the input key size is acceptable.
575 */
576 int blowfish_keysize(int *keysize)
577 {
578 LTC_ARGCHK(keysize != NULL);
579
580 if (*keysize < 8) {
581 return CRYPT_INVALID_KEYSIZE;
582 } else if (*keysize > 56) {
583 *keysize = 56;
584 }
585 return CRYPT_OK;
586 }
587
588 #endif
589
590
591 /* $Source$ */
592 /* $Revision$ */
593 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file camellia.c
13 Implementation by Tom St Denis of Elliptic Semiconductor
14 */
15
16 #include "tomcrypt.h"
17
18 #ifdef LTC_CAMELLIA
19
20 const struct ltc_cipher_descriptor camellia_desc = {
21 "camellia",
22 23,
23 16, 32, 16, 18,
24 &camellia_setup,
25 &camellia_ecb_encrypt,
26 &camellia_ecb_decrypt,
27 &camellia_test,
28 &camellia_done,
29 &camellia_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 static const ulong32 SP1110[] = {
34 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500,
35 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100,
36 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
37 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00,
38 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00,
39 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
40 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00,
41 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00,
42 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
43 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900,
44 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500,
45 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
46 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00,
47 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200,
48 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
49 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000,
50 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700,
51 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
52 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00,
53 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400,
54 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
55 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200,
56 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00,
57 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
58 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00,
59 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900,
60 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
61 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00,
62 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00,
63 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
64 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
65 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
66 };
67
68 static const ulong32 SP0222[] = {
69 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb,
70 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282,
71 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
72 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b,
73 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d,
74 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
75 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a,
76 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a,
77 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
78 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333,
79 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a,
80 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
81 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838,
82 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444,
83 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
84 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0,
85 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f,
86 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
87 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7,
88 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929,
89 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
90 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5,
91 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676,
92 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
93 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d,
94 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2,
95 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
96 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5,
97 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414,
98 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
99 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383,
100 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
101 };
102
103 static const ulong32 SP3033[] = {
104 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2,
105 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0,
106 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
107 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede,
108 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767,
109 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
110 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e,
111 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6,
112 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
113 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc,
114 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282,
115 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
116 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e,
117 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111,
118 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
119 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828,
120 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb,
121 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
122 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded,
123 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a,
124 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
125 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171,
126 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d,
127 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
128 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747,
129 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac,
130 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
131 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d,
132 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505,
133 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
134 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
135 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
136 };
137
138 static const ulong32 SP4404[] = {
139 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae,
140 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092,
141 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
142 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c,
143 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084,
144 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
145 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2,
146 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069,
147 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
148 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd,
149 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf,
150 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
151 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4,
152 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d,
153 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
154 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080,
155 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041,
156 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
157 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a,
158 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d,
159 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
160 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7,
161 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022,
162 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
163 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2,
164 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094,
165 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
166 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e,
167 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059,
168 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
169 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
170 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
171 };
172
173 static ulong64 key_sigma[] = {
174 CONST64(0xA09E667F3BCC908B),
175 CONST64(0xB67AE8584CAA73B2),
176 CONST64(0xC6EF372FE94F82BE),
177 CONST64(0x54FF53A5F1D36F1C),
178 CONST64(0x10E527FADE682D1D),
179 CONST64(0xB05688C2B3E6C1FD)
180 };
181
182 static ulong64 F(ulong64 x)
183 {
184 ulong32 D, U;
185
186 #define loc(i) ((8-i)*8)
187
188 D = SP1110[(x >> loc(8)) & 0xFF] ^ SP0222[(x >> loc(5)) & 0xFF] ^ SP3033[(x >> loc(6)) & 0xFF] ^ SP4404[(x >> loc(7)) & 0xFF];
189 U = SP1110[(x >> loc(1)) & 0xFF] ^ SP0222[(x >> loc(2)) & 0xFF] ^ SP3033[(x >> loc(3)) & 0xFF] ^ SP4404[(x >> loc(4)) & 0xFF];
190
191 D ^= U;
192 U = D ^ ROR(U, (const int)8);
193
194 return ((ulong64)U) | (((ulong64)D) << CONST64(32));
195 }
196
197 static void rot_128(unsigned char *in, unsigned count, unsigned char *out)
198 {
199 unsigned x, w, b;
200
201 w = count >> 3;
202 b = count & 7;
203
204 for (x = 0; x < 16; x++) {
205 out[x] = (in[(x+w)&15] << b) | (in[(x+w+1)&15] >> (8 - b));
206 }
207 }
208
209 int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
210 {
211 unsigned char T[48], kA[16], kB[16], kR[16], kL[16];
212 int x;
213 ulong64 A, B;
214
215 // LTC_ARGCHK(key != NULL);
216 // LTC_ARGCHK(skey != NULL);
217
218 /* Valid sizes (in bytes) are 16, 24, 32 */
219 if (keylen != 16 && keylen != 24 && keylen != 32) {
220 return CRYPT_INVALID_KEYSIZE;
221 }
222
223 /* number of rounds */
224 skey->camellia.R = (keylen == 16) ? 18 : 24;
225
226 if (num_rounds != 0 && num_rounds != skey->camellia.R) {
227 return CRYPT_INVALID_ROUNDS;
228 }
229
230 /* expand key */
231 if (keylen == 16) {
232 for (x = 0; x < 16; x++) {
233 T[x] = key[x];
234 T[x + 16] = 0;
235 }
236 } else if (keylen == 24) {
237 for (x = 0; x < 24; x++) {
238 T[x] = key[x];
239 }
240 for (x = 24; x < 32; x++) {
241 T[x] = key[x-8] ^ 0xFF;
242 }
243 } else {
244 for (x = 0; x < 32; x++) {
245 T[x] = key[x];
246 }
247 }
248
249 for (x = 0; x < 16; x++) {
250 kL[x] = T[x];
251 kR[x] = T[x + 16];
252 }
253
254 for (x = 32; x < 48; x++) {
255 T[x] = T[x - 32] ^ T[x - 16];
256 }
257
258 /* first two rounds */
259 LOAD64H(A, T+32); LOAD64H(B, T+40);
260 B ^= F(A ^ key_sigma[0]);
261 A ^= F(B ^ key_sigma[1]);
262 STORE64H(A, T+32); STORE64H(B, T+40);
263
264 /* xor kL in */
265 for (x = 0; x < 16; x++) { T[x+32] ^= kL[x]; }
266
267 /* next two rounds */
268 LOAD64H(A, T+32); LOAD64H(B, T+40);
269 B ^= F(A ^ key_sigma[2]);
270 A ^= F(B ^ key_sigma[3]);
271 STORE64H(A, T+32); STORE64H(B, T+40);
272
273 /* grab KA */
274 for (x = 0; x < 16; x++) { kA[x] = T[x+32]; }
275
276 /* xor kR in */
277 for (x = 0; x < 16; x++) { T[x+32] ^= kR[x]; }
278
279 if (keylen == 16) {
280 /* grab whitening keys kw1 and kw2 */
281 LOAD64H(skey->camellia.kw[0], kL);
282 LOAD64H(skey->camellia.kw[1], kL+8);
283
284 /* k1-k2 */
285 LOAD64H(skey->camellia.k[0], kA);
286 LOAD64H(skey->camellia.k[1], kA+8);
287
288 /* rotate kL by 15, k3/k4 */
289 rot_128(kL, 15, T+32);
290 LOAD64H(skey->camellia.k[2], T+32);
291 LOAD64H(skey->camellia.k[3], T+40);
292
293 /* rotate kA by 15, k5/k6 */
294 rot_128(kA, 15, T+32);
295 LOAD64H(skey->camellia.k[4], T+32);
296 LOAD64H(skey->camellia.k[5], T+40);
297
298 /* rotate kA by 30, kl1, kl2 */
299 rot_128(kA, 30, T+32);
300 LOAD64H(skey->camellia.kl[0], T+32);
301 LOAD64H(skey->camellia.kl[1], T+40);
302
303 /* rotate kL by 45, k7/k8 */
304 rot_128(kL, 45, T+32);
305 LOAD64H(skey->camellia.k[6], T+32);
306 LOAD64H(skey->camellia.k[7], T+40);
307
308 /* rotate kA by 45, k9/k10 */
309 rot_128(kA, 45, T+32);
310 LOAD64H(skey->camellia.k[8], T+32);
311 rot_128(kL, 60, T+32);
312 LOAD64H(skey->camellia.k[9], T+40);
313
314 /* rotate kA by 60, k11/k12 */
315 rot_128(kA, 60, T+32);
316 LOAD64H(skey->camellia.k[10], T+32);
317 LOAD64H(skey->camellia.k[11], T+40);
318
319 /* rotate kL by 77, kl3, kl4 */
320 rot_128(kL, 77, T+32);
321 LOAD64H(skey->camellia.kl[2], T+32);
322 LOAD64H(skey->camellia.kl[3], T+40);
323
324 /* rotate kL by 94, k13/k14 */
325 rot_128(kL, 94, T+32);
326 LOAD64H(skey->camellia.k[12], T+32);
327 LOAD64H(skey->camellia.k[13], T+40);
328
329 /* rotate kA by 94, k15/k16 */
330 rot_128(kA, 94, T+32);
331 LOAD64H(skey->camellia.k[14], T+32);
332 LOAD64H(skey->camellia.k[15], T+40);
333
334 /* rotate kL by 111, k17/k18 */
335 rot_128(kL, 111, T+32);
336 LOAD64H(skey->camellia.k[16], T+32);
337 LOAD64H(skey->camellia.k[17], T+40);
338
339 /* rotate kA by 111, kw3/kw4 */
340 rot_128(kA, 111, T+32);
341 LOAD64H(skey->camellia.kw[2], T+32);
342 LOAD64H(skey->camellia.kw[3], T+40);
343 } else {
344 /* last two rounds */
345 LOAD64H(A, T+32); LOAD64H(B, T+40);
346 B ^= F(A ^ key_sigma[4]);
347 A ^= F(B ^ key_sigma[5]);
348 STORE64H(A, T+32); STORE64H(B, T+40);
349
350 /* grab kB */
351 for (x = 0; x < 16; x++) { kB[x] = T[x+32]; }
352
353 /* kw1/2 from kL*/
354 LOAD64H(skey->camellia.kw[0], kL);
355 LOAD64H(skey->camellia.kw[1], kL+8);
356
357 /* k1/k2 = kB */
358 LOAD64H(skey->camellia.k[0], kB);
359 LOAD64H(skey->camellia.k[1], kB+8);
360
361 /* k3/k4 = kR by 15 */
362 rot_128(kR, 15, T+32);
363 LOAD64H(skey->camellia.k[2], T+32);
364 LOAD64H(skey->camellia.k[3], T+40);
365
366 /* k5/k7 = kA by 15 */
367 rot_128(kA, 15, T+32);
368 LOAD64H(skey->camellia.k[4], T+32);
369 LOAD64H(skey->camellia.k[5], T+40);
370
371 /* kl1/2 = kR by 30 */
372 rot_128(kR, 30, T+32);
373 LOAD64H(skey->camellia.kl[0], T+32);
374 LOAD64H(skey->camellia.kl[1], T+40);
375
376 /* k7/k8 = kB by 30 */
377 rot_128(kB, 30, T+32);
378 LOAD64H(skey->camellia.k[6], T+32);
379 LOAD64H(skey->camellia.k[7], T+40);
380
381 /* k9/k10 = kL by 45 */
382 rot_128(kL, 45, T+32);
383 LOAD64H(skey->camellia.k[8], T+32);
384 LOAD64H(skey->camellia.k[9], T+40);
385
386 /* k11/k12 = kA by 45 */
387 rot_128(kA, 45, T+32);
388 LOAD64H(skey->camellia.k[10], T+32);
389 LOAD64H(skey->camellia.k[11], T+40);
390
391 /* kl3/4 = kL by 60 */
392 rot_128(kL, 60, T+32);
393 LOAD64H(skey->camellia.kl[2], T+32);
394 LOAD64H(skey->camellia.kl[3], T+40);
395
396 /* k13/k14 = kR by 60 */
397 rot_128(kR, 60, T+32);
398 LOAD64H(skey->camellia.k[12], T+32);
399 LOAD64H(skey->camellia.k[13], T+40);
400
401 /* k15/k16 = kB by 15 */
402 rot_128(kB, 60, T+32);
403 LOAD64H(skey->camellia.k[14], T+32);
404 LOAD64H(skey->camellia.k[15], T+40);
405
406 /* k17/k18 = kL by 77 */
407 rot_128(kL, 77, T+32);
408 LOAD64H(skey->camellia.k[16], T+32);
409 LOAD64H(skey->camellia.k[17], T+40);
410
411 /* kl5/6 = kA by 77 */
412 rot_128(kA, 77, T+32);
413 LOAD64H(skey->camellia.kl[4], T+32);
414 LOAD64H(skey->camellia.kl[5], T+40);
415
416 /* k19/k20 = kR by 94 */
417 rot_128(kR, 94, T+32);
418 LOAD64H(skey->camellia.k[18], T+32);
419 LOAD64H(skey->camellia.k[19], T+40);
420
421 /* k21/k22 = kA by 94 */
422 rot_128(kA, 94, T+32);
423 LOAD64H(skey->camellia.k[20], T+32);
424 LOAD64H(skey->camellia.k[21], T+40);
425
426 /* k23/k24 = kL by 111 */
427 rot_128(kL, 111, T+32);
428 LOAD64H(skey->camellia.k[22], T+32);
429 LOAD64H(skey->camellia.k[23], T+40);
430
431 /* kw2/kw3 = kB by 111 */
432 rot_128(kB, 111, T+32);
433 LOAD64H(skey->camellia.kw[2], T+32);
434 LOAD64H(skey->camellia.kw[3], T+40);
435 }
436
437 return CRYPT_OK;
438 }
439
440 int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
441 {
442 ulong64 L, R;
443 ulong32 a, b;
444
445 LOAD64H(L, pt+0); LOAD64H(R, pt+8);
446 L ^= skey->camellia.kw[0];
447 R ^= skey->camellia.kw[1];
448
449 /* first 6 rounds */
450 R ^= F(L ^ skey->camellia.k[0]);
451 L ^= F(R ^ skey->camellia.k[1]);
452 R ^= F(L ^ skey->camellia.k[2]);
453 L ^= F(R ^ skey->camellia.k[3]);
454 R ^= F(L ^ skey->camellia.k[4]);
455 L ^= F(R ^ skey->camellia.k[5]);
456
457 /* FL */
458 a = (ulong32)(L >> 32);
459 b = (ulong32)(L & 0xFFFFFFFFUL);
460 b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1);
461 a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU);
462 L = (((ulong64)a) << 32) | b;
463
464 /* FL^-1 */
465 a = (ulong32)(R >> 32);
466 b = (ulong32)(R & 0xFFFFFFFFUL);
467 a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU);
468 b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1);
469 R = (((ulong64)a) << 32) | b;
470
471 /* second 6 rounds */
472 R ^= F(L ^ skey->camellia.k[6]);
473 L ^= F(R ^ skey->camellia.k[7]);
474 R ^= F(L ^ skey->camellia.k[8]);
475 L ^= F(R ^ skey->camellia.k[9]);
476 R ^= F(L ^ skey->camellia.k[10]);
477 L ^= F(R ^ skey->camellia.k[11]);
478
479 /* FL */
480 a = (ulong32)(L >> 32);
481 b = (ulong32)(L & 0xFFFFFFFFUL);
482 b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1);
483 a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU);
484 L = (((ulong64)a) << 32) | b;
485
486 /* FL^-1 */
487 a = (ulong32)(R >> 32);
488 b = (ulong32)(R & 0xFFFFFFFFUL);
489 a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU);
490 b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1);
491 R = (((ulong64)a) << 32) | b;
492
493 /* third 6 rounds */
494 R ^= F(L ^ skey->camellia.k[12]);
495 L ^= F(R ^ skey->camellia.k[13]);
496 R ^= F(L ^ skey->camellia.k[14]);
497 L ^= F(R ^ skey->camellia.k[15]);
498 R ^= F(L ^ skey->camellia.k[16]);
499 L ^= F(R ^ skey->camellia.k[17]);
500
501 /* next FL */
502 if (skey->camellia.R == 24) {
503 /* FL */
504 a = (ulong32)(L >> 32);
505 b = (ulong32)(L & 0xFFFFFFFFUL);
506 b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1);
507 a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU);
508 L = (((ulong64)a) << 32) | b;
509
510 /* FL^-1 */
511 a = (ulong32)(R >> 32);
512 b = (ulong32)(R & 0xFFFFFFFFUL);
513 a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU);
514 b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1);
515 R = (((ulong64)a) << 32) | b;
516
517 /* fourth 6 rounds */
518 R ^= F(L ^ skey->camellia.k[18]);
519 L ^= F(R ^ skey->camellia.k[19]);
520 R ^= F(L ^ skey->camellia.k[20]);
521 L ^= F(R ^ skey->camellia.k[21]);
522 R ^= F(L ^ skey->camellia.k[22]);
523 L ^= F(R ^ skey->camellia.k[23]);
524 }
525
526 L ^= skey->camellia.kw[3];
527 R ^= skey->camellia.kw[2];
528
529 STORE64H(R, ct+0); STORE64H(L, ct+8);
530
531 return CRYPT_OK;
532 }
533
534 int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
535 {
536 ulong64 L, R;
537 ulong32 a, b;
538
539 LOAD64H(R, ct+0); LOAD64H(L, ct+8);
540 L ^= skey->camellia.kw[3];
541 R ^= skey->camellia.kw[2];
542
543 /* next FL */
544 if (skey->camellia.R == 24) {
545 /* fourth 6 rounds */
546 L ^= F(R ^ skey->camellia.k[23]);
547 R ^= F(L ^ skey->camellia.k[22]);
548 L ^= F(R ^ skey->camellia.k[21]);
549 R ^= F(L ^ skey->camellia.k[20]);
550 L ^= F(R ^ skey->camellia.k[19]);
551 R ^= F(L ^ skey->camellia.k[18]);
552
553 /* FL */
554 a = (ulong32)(L >> 32);
555 b = (ulong32)(L & 0xFFFFFFFFUL);
556 a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU);
557 b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1);
558 L = (((ulong64)a) << 32) | b;
559
560 /* FL^-1 */
561 a = (ulong32)(R >> 32);
562 b = (ulong32)(R & 0xFFFFFFFFUL);
563 b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1);
564 a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU);
565 R = (((ulong64)a) << 32) | b;
566
567 }
568
569 /* third 6 rounds */
570 L ^= F(R ^ skey->camellia.k[17]);
571 R ^= F(L ^ skey->camellia.k[16]);
572 L ^= F(R ^ skey->camellia.k[15]);
573 R ^= F(L ^ skey->camellia.k[14]);
574 L ^= F(R ^ skey->camellia.k[13]);
575 R ^= F(L ^ skey->camellia.k[12]);
576
577 /* FL */
578 a = (ulong32)(L >> 32);
579 b = (ulong32)(L & 0xFFFFFFFFUL);
580 a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU);
581 b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1);
582 L = (((ulong64)a) << 32) | b;
583
584 /* FL^-1 */
585 a = (ulong32)(R >> 32);
586 b = (ulong32)(R & 0xFFFFFFFFUL);
587 b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1);
588 a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU);
589 R = (((ulong64)a) << 32) | b;
590
591 /* second 6 rounds */
592 L ^= F(R ^ skey->camellia.k[11]);
593 R ^= F(L ^ skey->camellia.k[10]);
594 L ^= F(R ^ skey->camellia.k[9]);
595 R ^= F(L ^ skey->camellia.k[8]);
596 L ^= F(R ^ skey->camellia.k[7]);
597 R ^= F(L ^ skey->camellia.k[6]);
598
599 /* FL */
600 a = (ulong32)(L >> 32);
601 b = (ulong32)(L & 0xFFFFFFFFUL);
602 a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU);
603 b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1);
604 L = (((ulong64)a) << 32) | b;
605
606 /* FL^-1 */
607 a = (ulong32)(R >> 32);
608 b = (ulong32)(R & 0xFFFFFFFFUL);
609 b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1);
610 a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU);
611 R = (((ulong64)a) << 32) | b;
612
613 /* first 6 rounds */
614 L ^= F(R ^ skey->camellia.k[5]);
615 R ^= F(L ^ skey->camellia.k[4]);
616 L ^= F(R ^ skey->camellia.k[3]);
617 R ^= F(L ^ skey->camellia.k[2]);
618 L ^= F(R ^ skey->camellia.k[1]);
619 R ^= F(L ^ skey->camellia.k[0]);
620
621 L ^= skey->camellia.kw[1];
622 R ^= skey->camellia.kw[0];
623
624 STORE64H(R, pt+0); STORE64H(L, pt+8);
625
626 return CRYPT_OK;
627 }
628
629 int camellia_test(void)
630 {
631 static const struct {
632 int keylen;
633 unsigned char key[32], pt[16], ct[16];
634 } tests[] = {
635
636 {
637 16,
638 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
639 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
640 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
641 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
642 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
643 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }
644 },
645
646 {
647 24,
648 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
649 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
650 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
651 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
652 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
653 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
654 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }
655 },
656
657
658 {
659 32,
660 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
661 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
662 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
663 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
664 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
665 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
666 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
667 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }
668 }
669 };
670 unsigned char buf[2][16];
671 symmetric_key skey;
672 int err, x;
673
674 for (x = 0; x < 3; x++) {
675 if ((err = camellia_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
676 return err;
677 }
678 if ((err = camellia_ecb_encrypt(tests[x].pt, buf[0], &skey)) != CRYPT_OK) {
679 camellia_done(&skey);
680 return err;
681 }
682 if ((err = camellia_ecb_decrypt(tests[x].ct, buf[1], &skey)) != CRYPT_OK) {
683 camellia_done(&skey);
684 return err;
685 }
686 camellia_done(&skey);
687 if (XMEMCMP(tests[x].ct, buf[0], 16) || XMEMCMP(tests[x].pt, buf[1], 16)) {
688 #if 0
689 int i, j;
690 printf ("\n\nLTC_CAMELLIA failed for x=%d, I got:\n", x);
691 for (i = 0; i < 2; i++) {
692 const unsigned char *expected, *actual;
693 expected = (i ? tests[x].pt : tests[x].ct);
694 actual = buf[i];
695 printf ("expected actual (%s)\n", (i ? "plaintext" : "ciphertext"));
696 for (j = 0; j < 16; j++) {
697 const char *eq = (expected[j] == actual[j] ? "==" : "!=");
698 printf (" %02x %s %02x\n", expected[j], eq, actual[j]);
699 }
700 printf ("\n");
701 }
702 #endif
703 return CRYPT_FAIL_TESTVECTOR;
704 }
705 }
706 return CRYPT_OK;
707 }
708
709 void camellia_done(symmetric_key *skey) {}
710
711 int camellia_keysize(int *keysize)
712 {
713 if (*keysize >= 32) { *keysize = 32; }
714 else if (*keysize >= 24) { *keysize = 24; }
715 else if (*keysize >= 16) { *keysize = 16; }
716 else return CRYPT_INVALID_KEYSIZE;
717 return CRYPT_OK;
718 }
719
720 #endif
721
722 /* $Source$ */
723 /* $Revision$ */
724 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file cast5.c
13 Implementation of LTC_CAST5 (RFC 2144) by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_CAST5
18
19 const struct ltc_cipher_descriptor cast5_desc = {
20 "cast5",
21 15,
22 5, 16, 8, 16,
23 &cast5_setup,
24 &cast5_ecb_encrypt,
25 &cast5_ecb_decrypt,
26 &cast5_test,
27 &cast5_done,
28 &cast5_keysize,
29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
30 };
31
32 static const ulong32 S1[256] = {
33 0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL,
34 0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL,
35 0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL,
36 0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL,
37 0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL,
38 0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL,
39 0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL,
40 0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL,
41 0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL,
42 0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL,
43 0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL,
44 0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL,
45 0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL,
46 0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL,
47 0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL,
48 0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL,
49 0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL,
50 0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL,
51 0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL,
52 0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL,
53 0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL,
54 0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL,
55 0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL,
56 0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL,
57 0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL,
58 0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL,
59 0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL,
60 0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL,
61 0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL,
62 0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL,
63 0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL,
64 0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL,
65 0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL,
66 0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL,
67 0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL,
68 0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL,
69 0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL,
70 0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL,
71 0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL,
72 0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL,
73 0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL,
74 0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL,
75 0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL};
76
77 static const ulong32 S2[256] = {
78 0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL,
79 0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL,
80 0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL,
81 0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL,
82 0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL,
83 0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL,
84 0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL,
85 0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL,
86 0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL,
87 0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL,
88 0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL,
89 0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL,
90 0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL,
91 0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL,
92 0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL,
93 0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL,
94 0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL,
95 0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL,
96 0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL,
97 0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL,
98 0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL,
99 0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL,
100 0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL,
101 0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL,
102 0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL,
103 0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL,
104 0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL,
105 0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL,
106 0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL,
107 0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL,
108 0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL,
109 0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL,
110 0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL,
111 0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL,
112 0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL,
113 0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL,
114 0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL,
115 0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL,
116 0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL,
117 0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL,
118 0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL,
119 0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL,
120 0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL};
121
122 static const ulong32 S3[256] = {
123 0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL,
124 0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL,
125 0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL,
126 0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL,
127 0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL,
128 0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL,
129 0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL,
130 0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL,
131 0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL,
132 0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL,
133 0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL,
134 0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL,
135 0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL,
136 0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL,
137 0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL,
138 0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL,
139 0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL,
140 0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL,
141 0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL,
142 0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL,
143 0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL,
144 0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL,
145 0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL,
146 0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL,
147 0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL,
148 0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL,
149 0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL,
150 0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL,
151 0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL,
152 0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL,
153 0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL,
154 0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL,
155 0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL,
156 0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL,
157 0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL,
158 0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL,
159 0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL,
160 0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL,
161 0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL,
162 0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL,
163 0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL,
164 0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL,
165 0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL};
166
167 static const ulong32 S4[256] = {
168 0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL,
169 0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL,
170 0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL,
171 0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL,
172 0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL,
173 0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL,
174 0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL,
175 0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL,
176 0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL,
177 0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL,
178 0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL,
179 0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL,
180 0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL,
181 0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL,
182 0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL,
183 0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL,
184 0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL,
185 0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL,
186 0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL,
187 0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL,
188 0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL,
189 0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL,
190 0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL,
191 0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL,
192 0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL,
193 0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL,
194 0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL,
195 0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL,
196 0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL,
197 0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL,
198 0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL,
199 0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL,
200 0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL,
201 0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL,
202 0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL,
203 0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL,
204 0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL,
205 0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL,
206 0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL,
207 0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL,
208 0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL,
209 0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL,
210 0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL};
211
212 static const ulong32 S5[256] = {
213 0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL,
214 0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL,
215 0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL,
216 0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL,
217 0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL,
218 0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL,
219 0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL,
220 0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL,
221 0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL,
222 0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL,
223 0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL,
224 0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL,
225 0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL,
226 0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL,
227 0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL,
228 0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL,
229 0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL,
230 0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL,
231 0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL,
232 0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL,
233 0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL,
234 0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL,
235 0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL,
236 0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL,
237 0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL,
238 0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL,
239 0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL,
240 0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL,
241 0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL,
242 0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL,
243 0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL,
244 0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL,
245 0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL,
246 0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL,
247 0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL,
248 0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL,
249 0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL,
250 0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL,
251 0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL,
252 0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL,
253 0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL,
254 0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL,
255 0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL};
256
257 static const ulong32 S6[256] = {
258 0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL,
259 0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL,
260 0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL,
261 0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL,
262 0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL,
263 0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL,
264 0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL,
265 0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL,
266 0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL,
267 0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL,
268 0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL,
269 0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL,
270 0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL,
271 0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL,
272 0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL,
273 0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL,
274 0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL,
275 0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL,
276 0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL,
277 0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL,
278 0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL,
279 0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL,
280 0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL,
281 0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL,
282 0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL,
283 0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL,
284 0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL,
285 0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL,
286 0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL,
287 0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL,
288 0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL,
289 0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL,
290 0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL,
291 0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL,
292 0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL,
293 0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL,
294 0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL,
295 0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL,
296 0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL,
297 0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL,
298 0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL,
299 0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL,
300 0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL};
301
302 static const ulong32 S7[256] = {
303 0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL,
304 0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL,
305 0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL,
306 0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL,
307 0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL,
308 0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL,
309 0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL,
310 0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL,
311 0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL,
312 0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL,
313 0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL,
314 0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL,
315 0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL,
316 0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL,
317 0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL,
318 0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL,
319 0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL,
320 0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL,
321 0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL,
322 0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL,
323 0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL,
324 0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL,
325 0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL,
326 0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL,
327 0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL,
328 0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL,
329 0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL,
330 0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL,
331 0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL,
332 0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL,
333 0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL,
334 0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL,
335 0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL,
336 0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL,
337 0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL,
338 0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL,
339 0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL,
340 0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL,
341 0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL,
342 0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL,
343 0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL,
344 0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL,
345 0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL};
346
347 static const ulong32 S8[256] = {
348 0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL,
349 0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL,
350 0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL,
351 0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL,
352 0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL,
353 0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL,
354 0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL,
355 0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL,
356 0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL,
357 0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL,
358 0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL,
359 0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL,
360 0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL,
361 0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL,
362 0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL,
363 0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL,
364 0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL,
365 0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL,
366 0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL,
367 0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL,
368 0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL,
369 0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL,
370 0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL,
371 0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL,
372 0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL,
373 0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL,
374 0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL,
375 0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL,
376 0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL,
377 0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL,
378 0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL,
379 0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL,
380 0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL,
381 0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL,
382 0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL,
383 0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL,
384 0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL,
385 0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL,
386 0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL,
387 0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL,
388 0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL,
389 0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL,
390 0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL};
391
392 /* returns the i'th byte of a variable */
393 #ifdef _MSC_VER
394 #define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3))))
395 #else
396 #define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255)
397 #endif
398
399 /**
400 Initialize the LTC_CAST5 block cipher
401 @param key The symmetric key you wish to pass
402 @param keylen The key length in bytes
403 @param num_rounds The number of rounds desired (0 for default)
404 @param skey The key in as scheduled by this function.
405 @return CRYPT_OK if successful
406 */
407 #ifdef LTC_CLEAN_STACK
408 static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
409 #else
410 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
411 #endif
412 {
413 ulong32 x[4], z[4];
414 unsigned char buf[16];
415 int y, i;
416
417 LTC_ARGCHK(key != NULL);
418 LTC_ARGCHK(skey != NULL);
419
420 if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) {
421 return CRYPT_INVALID_ROUNDS;
422 }
423
424 if (num_rounds == 12 && keylen > 10) {
425 return CRYPT_INVALID_ROUNDS;
426 }
427
428 if (keylen < 5 || keylen > 16) {
429 return CRYPT_INVALID_KEYSIZE;
430 }
431
432 /* extend the key as required */
433 zeromem(buf, sizeof(buf));
434 XMEMCPY(buf, key, (size_t)keylen);
435
436 /* load and start the awful looking network */
437 for (y = 0; y < 4; y++) {
438 LOAD32H(x[3-y],buf+4*y);
439 }
440
441 for (i = y = 0; y < 2; y++) {
442 z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
443 z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
444 z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
445 z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
446 skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)];
447 skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)];
448 skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)];
449 skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)];
450
451 x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
452 x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
453 x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
454 x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
455 skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)];
456 skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)];
457 skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)];
458 skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)];
459
460 /* second half */
461 z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
462 z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
463 z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
464 z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
465 skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)];
466 skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)];
467 skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)];
468 skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)];
469
470 x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
471 x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
472 x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
473 x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
474 skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)];
475 skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)];
476 skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)];
477 skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)];
478 }
479
480 skey->cast5.keylen = keylen;
481
482 #ifdef LTC_CLEAN_STACK
483 zeromem(buf, sizeof(buf));
484 zeromem(x, sizeof(x));
485 zeromem(z, sizeof(z));
486 #endif
487
488 return CRYPT_OK;
489 }
490
491 #ifdef LTC_CLEAN_STACK
492 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
493 {
494 int z;
495 z = _cast5_setup(key, keylen, num_rounds, skey);
496 burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2);
497 return z;
498 }
499 #endif
500
501 #ifdef _MSC_VER
502 #define INLINE __inline
503 #else
504 #define INLINE
505 #endif
506
507 INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr)
508 {
509 ulong32 I;
510 I = (Km + R);
511 I = ROL(I, Kr);
512 return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)];
513 }
514
515 INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr)
516 {
517 ulong32 I;
518 I = (Km ^ R);
519 I = ROL(I, Kr);
520 return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)];
521 }
522
523 INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr)
524 {
525 ulong32 I;
526 I = (Km - R);
527 I = ROL(I, Kr);
528 return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)];
529 }
530
531 /**
532 Encrypts a block of text with LTC_CAST5
533 @param pt The input plaintext (8 bytes)
534 @param ct The output ciphertext (8 bytes)
535 @param skey The key as scheduled
536 */
537 #ifdef LTC_CLEAN_STACK
538 static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
539 #else
540 int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
541 #endif
542 {
543 ulong32 R, L;
544
545 LTC_ARGCHK(pt != NULL);
546 LTC_ARGCHK(ct != NULL);
547 LTC_ARGCHK(skey != NULL);
548
549 LOAD32H(L,&pt[0]);
550 LOAD32H(R,&pt[4]);
551 L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
552 R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]);
553 L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]);
554 R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]);
555 L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]);
556 R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]);
557 L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]);
558 R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]);
559 L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]);
560 R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]);
561 L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]);
562 R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]);
563 if (skey->cast5.keylen > 10) {
564 L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]);
565 R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]);
566 L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]);
567 R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]);
568 }
569 STORE32H(R,&ct[0]);
570 STORE32H(L,&ct[4]);
571 return CRYPT_OK;
572 }
573
574
575 #ifdef LTC_CLEAN_STACK
576 int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
577 {
578 int err =_cast5_ecb_encrypt(pt,ct,skey);
579 burn_stack(sizeof(ulong32)*3);
580 return err;
581 }
582 #endif
583
584 /**
585 Decrypts a block of text with LTC_CAST5
586 @param ct The input ciphertext (8 bytes)
587 @param pt The output plaintext (8 bytes)
588 @param skey The key as scheduled
589 */
590 #ifdef LTC_CLEAN_STACK
591 static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
592 #else
593 int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
594 #endif
595 {
596 ulong32 R, L;
597
598 LTC_ARGCHK(pt != NULL);
599 LTC_ARGCHK(ct != NULL);
600 LTC_ARGCHK(skey != NULL);
601
602 LOAD32H(R,&ct[0]);
603 LOAD32H(L,&ct[4]);
604 if (skey->cast5.keylen > 10) {
605 R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]);
606 L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]);
607 R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]);
608 L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]);
609 }
610 R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]);
611 L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]);
612 R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]);
613 L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]);
614 R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]);
615 L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]);
616 R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]);
617 L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]);
618 R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]);
619 L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]);
620 R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]);
621 L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
622 STORE32H(L,&pt[0]);
623 STORE32H(R,&pt[4]);
624
625 return CRYPT_OK;
626 }
627
628 #ifdef LTC_CLEAN_STACK
629 int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
630 {
631 int err = _cast5_ecb_decrypt(ct,pt,skey);
632 burn_stack(sizeof(ulong32)*3);
633 return err;
634 }
635 #endif
636
637 /**
638 Performs a self-test of the LTC_CAST5 block cipher
639 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
640 */
641 int cast5_test(void)
642 {
643 #ifndef LTC_TEST
644 return CRYPT_NOP;
645 #else
646 static const struct {
647 int keylen;
648 unsigned char key[16];
649 unsigned char pt[8];
650 unsigned char ct[8];
651 } tests[] = {
652 { 16,
653 {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
654 {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
655 {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2}
656 },
657 { 10,
658 {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
659 {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
660 {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B},
661 },
662 { 5,
663 {0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
664 {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
665 {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E}
666 }
667 };
668 int i, y, err;
669 symmetric_key key;
670 unsigned char tmp[2][8];
671
672 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
673 if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
674 return err;
675 }
676 cast5_ecb_encrypt(tests[i].pt, tmp[0], &key);
677 cast5_ecb_decrypt(tmp[0], tmp[1], &key);
678 if ((XMEMCMP(tmp[0], tests[i].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[i].pt, 8) != 0)) {
679 return CRYPT_FAIL_TESTVECTOR;
680 }
681 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
682 for (y = 0; y < 8; y++) tmp[0][y] = 0;
683 for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key);
684 for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key);
685 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
686
687 }
688 return CRYPT_OK;
689 #endif
690 }
691
692 /** Terminate the context
693 @param skey The scheduled key
694 */
695 void cast5_done(symmetric_key *skey)
696 {
697 }
698
699 /**
700 Gets suitable key size
701 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
702 @return CRYPT_OK if the input key size is acceptable.
703 */
704 int cast5_keysize(int *keysize)
705 {
706 LTC_ARGCHK(keysize != NULL);
707 if (*keysize < 5) {
708 return CRYPT_INVALID_KEYSIZE;
709 } else if (*keysize > 16) {
710 *keysize = 16;
711 }
712 return CRYPT_OK;
713 }
714
715 #endif
716
717 /* $Source$ */
718 /* $Revision$ */
719 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file des.c
14 LTC_DES code submitted by Dobes Vandermeer
15 */
16
17 #ifdef LTC_DES
18
19 #define EN0 0
20 #define DE1 1
21
22 const struct ltc_cipher_descriptor des_desc =
23 {
24 "des",
25 13,
26 8, 8, 8, 16,
27 &des_setup,
28 &des_ecb_encrypt,
29 &des_ecb_decrypt,
30 &des_test,
31 &des_done,
32 &des_keysize,
33 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
34 };
35
36 const struct ltc_cipher_descriptor des3_desc =
37 {
38 "3des",
39 14,
40 24, 24, 8, 16,
41 &des3_setup,
42 &des3_ecb_encrypt,
43 &des3_ecb_decrypt,
44 &des3_test,
45 &des3_done,
46 &des3_keysize,
47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
48 };
49
50 static const ulong32 bytebit[8] =
51 {
52 0200, 0100, 040, 020, 010, 04, 02, 01
53 };
54
55 static const ulong32 bigbyte[24] =
56 {
57 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL,
58 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL,
59 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL,
60 0x800UL, 0x400UL, 0x200UL, 0x100UL,
61 0x80UL, 0x40UL, 0x20UL, 0x10UL,
62 0x8UL, 0x4UL, 0x2UL, 0x1L
63 };
64
65 /* Use the key schedule specific in the standard (ANSI X3.92-1981) */
66
67 static const unsigned char pc1[56] = {
68 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
69 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
70 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
71 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
72 };
73
74 static const unsigned char totrot[16] = {
75 1, 2, 4, 6,
76 8, 10, 12, 14,
77 15, 17, 19, 21,
78 23, 25, 27, 28
79 };
80
81 static const unsigned char pc2[48] = {
82 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
83 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
84 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
85 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
86 };
87
88
89 static const ulong32 SP1[64] =
90 {
91 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL,
92 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL,
93 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL,
94 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL,
95 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL,
96 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL,
97 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL,
98 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL,
99 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL,
100 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL,
101 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL,
102 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL,
103 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL,
104 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL,
105 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL,
106 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL
107 };
108
109 static const ulong32 SP2[64] =
110 {
111 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL,
112 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL,
113 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL,
114 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL,
115 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL,
116 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL,
117 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL,
118 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL,
119 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL,
120 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL,
121 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL,
122 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL,
123 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL,
124 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL,
125 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL,
126 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL
127 };
128
129 static const ulong32 SP3[64] =
130 {
131 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL,
132 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL,
133 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL,
134 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL,
135 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL,
136 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL,
137 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL,
138 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL,
139 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL,
140 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL,
141 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL,
142 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL,
143 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL,
144 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL,
145 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL,
146 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL
147 };
148
149 static const ulong32 SP4[64] =
150 {
151 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
152 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL,
153 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL,
154 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL,
155 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL,
156 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL,
157 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL,
158 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL,
159 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL,
160 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL,
161 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL,
162 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
163 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL,
164 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL,
165 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL,
166 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL
167 };
168
169 static const ulong32 SP5[64] =
170 {
171 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL,
172 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL,
173 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL,
174 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL,
175 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL,
176 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL,
177 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL,
178 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL,
179 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL,
180 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL,
181 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL,
182 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL,
183 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL,
184 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL,
185 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL,
186 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL
187 };
188
189 static const ulong32 SP6[64] =
190 {
191 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL,
192 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL,
193 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL,
194 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
195 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL,
196 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL,
197 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL,
198 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL,
199 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL,
200 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL,
201 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
202 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL,
203 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL,
204 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL,
205 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL,
206 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL
207 };
208
209 static const ulong32 SP7[64] =
210 {
211 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL,
212 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL,
213 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL,
214 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL,
215 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL,
216 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL,
217 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL,
218 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL,
219 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL,
220 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL,
221 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL,
222 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL,
223 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL,
224 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL,
225 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL,
226 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL
227 };
228
229 static const ulong32 SP8[64] =
230 {
231 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL,
232 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL,
233 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL,
234 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL,
235 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL,
236 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL,
237 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL,
238 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL,
239 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL,
240 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL,
241 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL,
242 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL,
243 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL,
244 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL,
245 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL,
246 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL
247 };
248
249 #ifndef LTC_SMALL_CODE
250
251 static const ulong64 des_ip[8][256] = {
252
253 { CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010),
254 CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010),
255 CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010),
256 CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010),
257 CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010),
258 CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010),
259 CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010),
260 CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010),
261 CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010),
262 CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010),
263 CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010),
264 CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010),
265 CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010),
266 CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010),
267 CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010),
268 CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010),
269 CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010),
270 CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010),
271 CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010),
272 CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010),
273 CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010),
274 CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010),
275 CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010),
276 CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010),
277 CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010),
278 CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010),
279 CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010),
280 CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010),
281 CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010),
282 CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010),
283 CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010),
284 CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010),
285 CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010),
286 CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010),
287 CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010),
288 CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010),
289 CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010),
290 CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010),
291 CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010),
292 CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010),
293 CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010),
294 CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010),
295 CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010),
296 CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010),
297 CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010),
298 CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010),
299 CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010),
300 CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010),
301 CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010),
302 CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010),
303 CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010),
304 CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010),
305 CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010),
306 CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010),
307 CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010),
308 CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010),
309 CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010),
310 CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010),
311 CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010),
312 CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010),
313 CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010),
314 CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010),
315 CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010),
316 CONST64(0x1010100010101000), CONST64(0x1010101010101000), CONST64(0x1010100010101010), CONST64(0x1010101010101010)
317 },
318 { CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008),
319 CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008),
320 CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808),
321 CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808),
322 CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008),
323 CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008),
324 CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808),
325 CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808),
326 CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008),
327 CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008),
328 CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808),
329 CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808),
330 CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008),
331 CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008),
332 CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808),
333 CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808),
334 CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008),
335 CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008),
336 CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808),
337 CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808),
338 CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008),
339 CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008),
340 CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808),
341 CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808),
342 CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008),
343 CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008),
344 CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808),
345 CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808),
346 CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008),
347 CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008),
348 CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808),
349 CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808),
350 CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008),
351 CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008),
352 CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808),
353 CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808),
354 CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008),
355 CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008),
356 CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808),
357 CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808),
358 CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008),
359 CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008),
360 CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808),
361 CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808),
362 CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008),
363 CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008),
364 CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808),
365 CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808),
366 CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008),
367 CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008),
368 CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808),
369 CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808),
370 CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008),
371 CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008),
372 CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808),
373 CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808),
374 CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008),
375 CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008),
376 CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808),
377 CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808),
378 CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008),
379 CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008),
380 CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808),
381 CONST64(0x0808080008080800), CONST64(0x0808080808080800), CONST64(0x0808080008080808), CONST64(0x0808080808080808)
382 },
383 { CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004),
384 CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004),
385 CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404),
386 CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404),
387 CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004),
388 CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004),
389 CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404),
390 CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404),
391 CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004),
392 CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004),
393 CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404),
394 CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404),
395 CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004),
396 CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004),
397 CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404),
398 CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404),
399 CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004),
400 CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004),
401 CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404),
402 CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404),
403 CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004),
404 CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004),
405 CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404),
406 CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404),
407 CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004),
408 CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004),
409 CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404),
410 CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404),
411 CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004),
412 CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004),
413 CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404),
414 CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404),
415 CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004),
416 CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004),
417 CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404),
418 CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404),
419 CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004),
420 CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004),
421 CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404),
422 CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404),
423 CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004),
424 CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004),
425 CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404),
426 CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404),
427 CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004),
428 CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004),
429 CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404),
430 CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404),
431 CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004),
432 CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004),
433 CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404),
434 CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404),
435 CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004),
436 CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004),
437 CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404),
438 CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404),
439 CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004),
440 CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004),
441 CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404),
442 CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404),
443 CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004),
444 CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004),
445 CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404),
446 CONST64(0x0404040004040400), CONST64(0x0404040404040400), CONST64(0x0404040004040404), CONST64(0x0404040404040404)
447 },
448 { CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002),
449 CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002),
450 CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202),
451 CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202),
452 CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002),
453 CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002),
454 CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202),
455 CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202),
456 CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002),
457 CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002),
458 CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202),
459 CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202),
460 CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002),
461 CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002),
462 CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202),
463 CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202),
464 CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002),
465 CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002),
466 CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202),
467 CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202),
468 CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002),
469 CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002),
470 CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202),
471 CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202),
472 CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002),
473 CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002),
474 CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202),
475 CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202),
476 CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002),
477 CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002),
478 CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202),
479 CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202),
480 CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002),
481 CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002),
482 CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202),
483 CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202),
484 CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002),
485 CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002),
486 CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202),
487 CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202),
488 CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002),
489 CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002),
490 CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202),
491 CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202),
492 CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002),
493 CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002),
494 CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202),
495 CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202),
496 CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002),
497 CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002),
498 CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202),
499 CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202),
500 CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002),
501 CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002),
502 CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202),
503 CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202),
504 CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002),
505 CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002),
506 CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202),
507 CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202),
508 CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002),
509 CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002),
510 CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202),
511 CONST64(0x0202020002020200), CONST64(0x0202020202020200), CONST64(0x0202020002020202), CONST64(0x0202020202020202)
512 },
513 { CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100),
514 CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100),
515 CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100),
516 CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100),
517 CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100),
518 CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100),
519 CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100),
520 CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100),
521 CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100),
522 CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100),
523 CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100),
524 CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100),
525 CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100),
526 CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100),
527 CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100),
528 CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100),
529 CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100),
530 CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100),
531 CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100),
532 CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100),
533 CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100),
534 CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100),
535 CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100),
536 CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100),
537 CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100),
538 CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100),
539 CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100),
540 CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100),
541 CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100),
542 CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100),
543 CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100),
544 CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100),
545 CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101),
546 CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101),
547 CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101),
548 CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101),
549 CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101),
550 CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101),
551 CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101),
552 CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101),
553 CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101),
554 CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101),
555 CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101),
556 CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101),
557 CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101),
558 CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101),
559 CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101),
560 CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101),
561 CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101),
562 CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101),
563 CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101),
564 CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101),
565 CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101),
566 CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101),
567 CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101),
568 CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101),
569 CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101),
570 CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101),
571 CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101),
572 CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101),
573 CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101),
574 CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101),
575 CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101),
576 CONST64(0x0101000101010001), CONST64(0x0101010101010001), CONST64(0x0101000101010101), CONST64(0x0101010101010101)
577 },
578 { CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080),
579 CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080),
580 CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080),
581 CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080),
582 CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080),
583 CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080),
584 CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080),
585 CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080),
586 CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080),
587 CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080),
588 CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080),
589 CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080),
590 CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080),
591 CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080),
592 CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080),
593 CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080),
594 CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080),
595 CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080),
596 CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080),
597 CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080),
598 CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080),
599 CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080),
600 CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080),
601 CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080),
602 CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080),
603 CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080),
604 CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080),
605 CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080),
606 CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080),
607 CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080),
608 CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080),
609 CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080),
610 CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080),
611 CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080),
612 CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080),
613 CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080),
614 CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080),
615 CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080),
616 CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080),
617 CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080),
618 CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080),
619 CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080),
620 CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080),
621 CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080),
622 CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080),
623 CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080),
624 CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080),
625 CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080),
626 CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080),
627 CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080),
628 CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080),
629 CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080),
630 CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080),
631 CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080),
632 CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080),
633 CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080),
634 CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080),
635 CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080),
636 CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080),
637 CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080),
638 CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080),
639 CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080),
640 CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080),
641 CONST64(0x8080800080808000), CONST64(0x8080808080808000), CONST64(0x8080800080808080), CONST64(0x8080808080808080)
642 },
643 { CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040),
644 CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040),
645 CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040),
646 CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040),
647 CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040),
648 CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040),
649 CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040),
650 CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040),
651 CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040),
652 CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040),
653 CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040),
654 CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040),
655 CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040),
656 CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040),
657 CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040),
658 CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040),
659 CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040),
660 CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040),
661 CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040),
662 CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040),
663 CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040),
664 CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040),
665 CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040),
666 CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040),
667 CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040),
668 CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040),
669 CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040),
670 CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040),
671 CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040),
672 CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040),
673 CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040),
674 CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040),
675 CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040),
676 CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040),
677 CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040),
678 CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040),
679 CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040),
680 CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040),
681 CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040),
682 CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040),
683 CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040),
684 CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040),
685 CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040),
686 CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040),
687 CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040),
688 CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040),
689 CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040),
690 CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040),
691 CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040),
692 CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040),
693 CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040),
694 CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040),
695 CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040),
696 CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040),
697 CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040),
698 CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040),
699 CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040),
700 CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040),
701 CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040),
702 CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040),
703 CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040),
704 CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040),
705 CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040),
706 CONST64(0x4040400040404000), CONST64(0x4040404040404000), CONST64(0x4040400040404040), CONST64(0x4040404040404040)
707 },
708 { CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020),
709 CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020),
710 CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020),
711 CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020),
712 CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020),
713 CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020),
714 CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020),
715 CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020),
716 CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020),
717 CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020),
718 CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020),
719 CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020),
720 CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020),
721 CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020),
722 CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020),
723 CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020),
724 CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020),
725 CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020),
726 CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020),
727 CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020),
728 CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020),
729 CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020),
730 CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020),
731 CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020),
732 CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020),
733 CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020),
734 CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020),
735 CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020),
736 CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020),
737 CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020),
738 CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020),
739 CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020),
740 CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020),
741 CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020),
742 CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020),
743 CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020),
744 CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020),
745 CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020),
746 CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020),
747 CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020),
748 CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020),
749 CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020),
750 CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020),
751 CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020),
752 CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020),
753 CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020),
754 CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020),
755 CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020),
756 CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020),
757 CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020),
758 CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020),
759 CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020),
760 CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020),
761 CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020),
762 CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020),
763 CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020),
764 CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020),
765 CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020),
766 CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020),
767 CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020),
768 CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020),
769 CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020),
770 CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020),
771 CONST64(0x2020200020202000), CONST64(0x2020202020202000), CONST64(0x2020200020202020), CONST64(0x2020202020202020)
772 }};
773
774 static const ulong64 des_fp[8][256] = {
775
776 { CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000),
777 CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000),
778 CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200),
779 CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200),
780 CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002),
781 CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002),
782 CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202),
783 CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202),
784 CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000),
785 CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000),
786 CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200),
787 CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200),
788 CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002),
789 CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002),
790 CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202),
791 CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202),
792 CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000),
793 CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000),
794 CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200),
795 CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200),
796 CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002),
797 CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002),
798 CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202),
799 CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202),
800 CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000),
801 CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000),
802 CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200),
803 CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200),
804 CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002),
805 CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002),
806 CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202),
807 CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202),
808 CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000),
809 CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000),
810 CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200),
811 CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200),
812 CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002),
813 CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002),
814 CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202),
815 CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202),
816 CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000),
817 CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000),
818 CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200),
819 CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200),
820 CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002),
821 CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002),
822 CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202),
823 CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202),
824 CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000),
825 CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000),
826 CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200),
827 CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200),
828 CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002),
829 CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002),
830 CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202),
831 CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202),
832 CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000),
833 CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000),
834 CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200),
835 CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200),
836 CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002),
837 CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002),
838 CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202),
839 CONST64(0x0202020000020202), CONST64(0x0202028000020202), CONST64(0x0202020002020202), CONST64(0x0202028002020202)
840 },
841 { CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000),
842 CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000),
843 CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800),
844 CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800),
845 CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008),
846 CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008),
847 CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808),
848 CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808),
849 CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000),
850 CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000),
851 CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800),
852 CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800),
853 CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008),
854 CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008),
855 CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808),
856 CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808),
857 CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000),
858 CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000),
859 CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800),
860 CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800),
861 CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008),
862 CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008),
863 CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808),
864 CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808),
865 CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000),
866 CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000),
867 CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800),
868 CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800),
869 CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008),
870 CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008),
871 CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808),
872 CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808),
873 CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000),
874 CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000),
875 CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800),
876 CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800),
877 CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008),
878 CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008),
879 CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808),
880 CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808),
881 CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000),
882 CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000),
883 CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800),
884 CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800),
885 CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008),
886 CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008),
887 CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808),
888 CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808),
889 CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000),
890 CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000),
891 CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800),
892 CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800),
893 CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008),
894 CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008),
895 CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808),
896 CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808),
897 CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000),
898 CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000),
899 CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800),
900 CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800),
901 CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008),
902 CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008),
903 CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808),
904 CONST64(0x0808080000080808), CONST64(0x0808080200080808), CONST64(0x0808080008080808), CONST64(0x0808080208080808)
905 },
906 { CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000),
907 CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000),
908 CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000),
909 CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000),
910 CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020),
911 CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020),
912 CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020),
913 CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020),
914 CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000),
915 CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000),
916 CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000),
917 CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000),
918 CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020),
919 CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020),
920 CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020),
921 CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020),
922 CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000),
923 CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000),
924 CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000),
925 CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000),
926 CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020),
927 CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020),
928 CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020),
929 CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020),
930 CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000),
931 CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000),
932 CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000),
933 CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000),
934 CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020),
935 CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020),
936 CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020),
937 CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020),
938 CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000),
939 CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000),
940 CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000),
941 CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000),
942 CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020),
943 CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020),
944 CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020),
945 CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020),
946 CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000),
947 CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000),
948 CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000),
949 CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000),
950 CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020),
951 CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020),
952 CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020),
953 CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020),
954 CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000),
955 CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000),
956 CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000),
957 CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000),
958 CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020),
959 CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020),
960 CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020),
961 CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020),
962 CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000),
963 CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000),
964 CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000),
965 CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000),
966 CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020),
967 CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020),
968 CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020),
969 CONST64(0x2020200000202020), CONST64(0x2020200800202020), CONST64(0x2020200020202020), CONST64(0x2020200820202020)
970 },
971 { CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000),
972 CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000),
973 CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000),
974 CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000),
975 CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080),
976 CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080),
977 CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080),
978 CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080),
979 CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000),
980 CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000),
981 CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000),
982 CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000),
983 CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080),
984 CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080),
985 CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080),
986 CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080),
987 CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000),
988 CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000),
989 CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000),
990 CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000),
991 CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080),
992 CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080),
993 CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080),
994 CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080),
995 CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000),
996 CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000),
997 CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000),
998 CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000),
999 CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080),
1000 CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080),
1001 CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080),
1002 CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080),
1003 CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000),
1004 CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000),
1005 CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000),
1006 CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000),
1007 CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080),
1008 CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080),
1009 CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080),
1010 CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080),
1011 CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000),
1012 CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000),
1013 CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000),
1014 CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000),
1015 CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080),
1016 CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080),
1017 CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080),
1018 CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080),
1019 CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000),
1020 CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000),
1021 CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000),
1022 CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000),
1023 CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080),
1024 CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080),
1025 CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080),
1026 CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080),
1027 CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000),
1028 CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000),
1029 CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000),
1030 CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000),
1031 CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080),
1032 CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080),
1033 CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080),
1034 CONST64(0x8080800000808080), CONST64(0x8080802000808080), CONST64(0x8080800080808080), CONST64(0x8080802080808080)
1035 },
1036 { CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000),
1037 CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000),
1038 CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100),
1039 CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100),
1040 CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001),
1041 CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001),
1042 CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101),
1043 CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101),
1044 CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000),
1045 CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000),
1046 CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100),
1047 CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100),
1048 CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001),
1049 CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001),
1050 CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101),
1051 CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101),
1052 CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000),
1053 CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000),
1054 CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100),
1055 CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100),
1056 CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001),
1057 CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001),
1058 CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101),
1059 CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101),
1060 CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000),
1061 CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000),
1062 CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100),
1063 CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100),
1064 CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001),
1065 CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001),
1066 CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101),
1067 CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101),
1068 CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000),
1069 CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000),
1070 CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100),
1071 CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100),
1072 CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001),
1073 CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001),
1074 CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101),
1075 CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101),
1076 CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000),
1077 CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000),
1078 CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100),
1079 CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100),
1080 CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001),
1081 CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001),
1082 CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101),
1083 CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101),
1084 CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000),
1085 CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000),
1086 CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100),
1087 CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100),
1088 CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001),
1089 CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001),
1090 CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101),
1091 CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101),
1092 CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000),
1093 CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000),
1094 CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100),
1095 CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100),
1096 CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001),
1097 CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001),
1098 CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101),
1099 CONST64(0x0101010000010101), CONST64(0x0101014000010101), CONST64(0x0101010001010101), CONST64(0x0101014001010101)
1100 },
1101 { CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000),
1102 CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000),
1103 CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400),
1104 CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400),
1105 CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004),
1106 CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004),
1107 CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404),
1108 CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404),
1109 CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000),
1110 CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000),
1111 CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400),
1112 CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400),
1113 CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004),
1114 CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004),
1115 CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404),
1116 CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404),
1117 CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000),
1118 CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000),
1119 CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400),
1120 CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400),
1121 CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004),
1122 CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004),
1123 CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404),
1124 CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404),
1125 CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000),
1126 CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000),
1127 CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400),
1128 CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400),
1129 CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004),
1130 CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004),
1131 CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404),
1132 CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404),
1133 CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000),
1134 CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000),
1135 CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400),
1136 CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400),
1137 CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004),
1138 CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004),
1139 CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404),
1140 CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404),
1141 CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000),
1142 CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000),
1143 CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400),
1144 CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400),
1145 CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004),
1146 CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004),
1147 CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404),
1148 CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404),
1149 CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000),
1150 CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000),
1151 CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400),
1152 CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400),
1153 CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004),
1154 CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004),
1155 CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404),
1156 CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404),
1157 CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000),
1158 CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000),
1159 CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400),
1160 CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400),
1161 CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004),
1162 CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004),
1163 CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404),
1164 CONST64(0x0404040000040404), CONST64(0x0404040100040404), CONST64(0x0404040004040404), CONST64(0x0404040104040404)
1165 },
1166 { CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000),
1167 CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000),
1168 CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000),
1169 CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000),
1170 CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010),
1171 CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010),
1172 CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010),
1173 CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010),
1174 CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000),
1175 CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000),
1176 CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000),
1177 CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000),
1178 CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010),
1179 CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010),
1180 CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010),
1181 CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010),
1182 CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000),
1183 CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000),
1184 CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000),
1185 CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000),
1186 CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010),
1187 CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010),
1188 CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010),
1189 CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010),
1190 CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000),
1191 CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000),
1192 CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000),
1193 CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000),
1194 CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010),
1195 CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010),
1196 CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010),
1197 CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010),
1198 CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000),
1199 CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000),
1200 CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000),
1201 CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000),
1202 CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010),
1203 CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010),
1204 CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010),
1205 CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010),
1206 CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000),
1207 CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000),
1208 CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000),
1209 CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000),
1210 CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010),
1211 CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010),
1212 CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010),
1213 CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010),
1214 CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000),
1215 CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000),
1216 CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000),
1217 CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000),
1218 CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010),
1219 CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010),
1220 CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010),
1221 CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010),
1222 CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000),
1223 CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000),
1224 CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000),
1225 CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000),
1226 CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010),
1227 CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010),
1228 CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010),
1229 CONST64(0x1010100000101010), CONST64(0x1010100400101010), CONST64(0x1010100010101010), CONST64(0x1010100410101010)
1230 },
1231 { CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000),
1232 CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000),
1233 CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000),
1234 CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000),
1235 CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040),
1236 CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040),
1237 CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040),
1238 CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040),
1239 CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000),
1240 CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000),
1241 CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000),
1242 CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000),
1243 CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040),
1244 CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040),
1245 CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040),
1246 CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040),
1247 CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000),
1248 CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000),
1249 CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000),
1250 CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000),
1251 CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040),
1252 CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040),
1253 CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040),
1254 CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040),
1255 CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000),
1256 CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000),
1257 CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000),
1258 CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000),
1259 CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040),
1260 CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040),
1261 CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040),
1262 CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040),
1263 CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000),
1264 CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000),
1265 CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000),
1266 CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000),
1267 CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040),
1268 CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040),
1269 CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040),
1270 CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040),
1271 CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000),
1272 CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000),
1273 CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000),
1274 CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000),
1275 CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040),
1276 CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040),
1277 CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040),
1278 CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040),
1279 CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000),
1280 CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000),
1281 CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000),
1282 CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000),
1283 CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040),
1284 CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040),
1285 CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040),
1286 CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040),
1287 CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000),
1288 CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000),
1289 CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000),
1290 CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000),
1291 CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040),
1292 CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040),
1293 CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040),
1294 CONST64(0x4040400000404040), CONST64(0x4040401000404040), CONST64(0x4040400040404040), CONST64(0x4040401040404040)
1295 }};
1296
1297 #endif
1298
1299
1300 static void cookey(const ulong32 *raw1, ulong32 *keyout);
1301
1302 #ifdef LTC_CLEAN_STACK
1303 static void _deskey(const unsigned char *key, short edf, ulong32 *keyout)
1304 #else
1305 static void deskey(const unsigned char *key, short edf, ulong32 *keyout)
1306 #endif
1307 {
1308 ulong32 i, j, l, m, n, kn[32];
1309 unsigned char pc1m[56], pcr[56];
1310
1311 for (j=0; j < 56; j++) {
1312 l = (ulong32)pc1[j];
1313 m = l & 7;
1314 pc1m[j] = (unsigned char)((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0);
1315 }
1316
1317 for (i=0; i < 16; i++) {
1318 if (edf == DE1) {
1319 m = (15 - i) << 1;
1320 } else {
1321 m = i << 1;
1322 }
1323 n = m + 1;
1324 kn[m] = kn[n] = 0L;
1325 for (j=0; j < 28; j++) {
1326 l = j + (ulong32)totrot[i];
1327 if (l < 28) {
1328 pcr[j] = pc1m[l];
1329 } else {
1330 pcr[j] = pc1m[l - 28];
1331 }
1332 }
1333 for (/*j = 28*/; j < 56; j++) {
1334 l = j + (ulong32)totrot[i];
1335 if (l < 56) {
1336 pcr[j] = pc1m[l];
1337 } else {
1338 pcr[j] = pc1m[l - 28];
1339 }
1340 }
1341 for (j=0; j < 24; j++) {
1342 if ((int)pcr[(int)pc2[j]] != 0) {
1343 kn[m] |= bigbyte[j];
1344 }
1345 if ((int)pcr[(int)pc2[j+24]] != 0) {
1346 kn[n] |= bigbyte[j];
1347 }
1348 }
1349 }
1350
1351 cookey(kn, keyout);
1352 }
1353
1354 #ifdef LTC_CLEAN_STACK
1355 static void deskey(const unsigned char *key, short edf, ulong32 *keyout)
1356 {
1357 _deskey(key, edf, keyout);
1358 burn_stack(sizeof(int)*5 + sizeof(ulong32)*32 + sizeof(unsigned char)*112);
1359 }
1360 #endif
1361
1362 #ifdef LTC_CLEAN_STACK
1363 static void _cookey(const ulong32 *raw1, ulong32 *keyout)
1364 #else
1365 static void cookey(const ulong32 *raw1, ulong32 *keyout)
1366 #endif
1367 {
1368 ulong32 *cook;
1369 const ulong32 *raw0;
1370 ulong32 dough[32];
1371 int i;
1372
1373 cook = dough;
1374 for(i=0; i < 16; i++, raw1++)
1375 {
1376 raw0 = raw1++;
1377 *cook = (*raw0 & 0x00fc0000L) << 6;
1378 *cook |= (*raw0 & 0x00000fc0L) << 10;
1379 *cook |= (*raw1 & 0x00fc0000L) >> 10;
1380 *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
1381 *cook = (*raw0 & 0x0003f000L) << 12;
1382 *cook |= (*raw0 & 0x0000003fL) << 16;
1383 *cook |= (*raw1 & 0x0003f000L) >> 4;
1384 *cook++ |= (*raw1 & 0x0000003fL);
1385 }
1386
1387 XMEMCPY(keyout, dough, sizeof dough);
1388 }
1389
1390 #ifdef LTC_CLEAN_STACK
1391 static void cookey(const ulong32 *raw1, ulong32 *keyout)
1392 {
1393 _cookey(raw1, keyout);
1394 burn_stack(sizeof(ulong32 *) * 2 + sizeof(ulong32)*32 + sizeof(int));
1395 }
1396 #endif
1397
1398 #ifndef LTC_CLEAN_STACK
1399 static void desfunc(ulong32 *block, const ulong32 *keys)
1400 #else
1401 static void _desfunc(ulong32 *block, const ulong32 *keys)
1402 #endif
1403 {
1404 ulong32 work, right, leftt;
1405 int cur_round;
1406
1407 leftt = block[0];
1408 right = block[1];
1409
1410 #ifdef LTC_SMALL_CODE
1411 work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
1412 right ^= work;
1413 leftt ^= (work << 4);
1414
1415 work = ((leftt >> 16) ^ right) & 0x0000ffffL;
1416 right ^= work;
1417 leftt ^= (work << 16);
1418
1419 work = ((right >> 2) ^ leftt) & 0x33333333L;
1420 leftt ^= work;
1421 right ^= (work << 2);
1422
1423 work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
1424 leftt ^= work;
1425 right ^= (work << 8);
1426
1427 right = ROLc(right, 1);
1428 work = (leftt ^ right) & 0xaaaaaaaaL;
1429
1430 leftt ^= work;
1431 right ^= work;
1432 leftt = ROLc(leftt, 1);
1433 #else
1434 {
1435 ulong64 tmp;
1436 tmp = des_ip[0][byte(leftt, 0)] ^
1437 des_ip[1][byte(leftt, 1)] ^
1438 des_ip[2][byte(leftt, 2)] ^
1439 des_ip[3][byte(leftt, 3)] ^
1440 des_ip[4][byte(right, 0)] ^
1441 des_ip[5][byte(right, 1)] ^
1442 des_ip[6][byte(right, 2)] ^
1443 des_ip[7][byte(right, 3)];
1444 leftt = (ulong32)(tmp >> 32);
1445 right = (ulong32)(tmp & 0xFFFFFFFFUL);
1446 }
1447 #endif
1448
1449 for (cur_round = 0; cur_round < 8; cur_round++) {
1450 work = RORc(right, 4) ^ *keys++;
1451 leftt ^= SP7[work & 0x3fL]
1452 ^ SP5[(work >> 8) & 0x3fL]
1453 ^ SP3[(work >> 16) & 0x3fL]
1454 ^ SP1[(work >> 24) & 0x3fL];
1455 work = right ^ *keys++;
1456 leftt ^= SP8[ work & 0x3fL]
1457 ^ SP6[(work >> 8) & 0x3fL]
1458 ^ SP4[(work >> 16) & 0x3fL]
1459 ^ SP2[(work >> 24) & 0x3fL];
1460
1461 work = RORc(leftt, 4) ^ *keys++;
1462 right ^= SP7[ work & 0x3fL]
1463 ^ SP5[(work >> 8) & 0x3fL]
1464 ^ SP3[(work >> 16) & 0x3fL]
1465 ^ SP1[(work >> 24) & 0x3fL];
1466 work = leftt ^ *keys++;
1467 right ^= SP8[ work & 0x3fL]
1468 ^ SP6[(work >> 8) & 0x3fL]
1469 ^ SP4[(work >> 16) & 0x3fL]
1470 ^ SP2[(work >> 24) & 0x3fL];
1471 }
1472
1473 #ifdef LTC_SMALL_CODE
1474 right = RORc(right, 1);
1475 work = (leftt ^ right) & 0xaaaaaaaaL;
1476 leftt ^= work;
1477 right ^= work;
1478 leftt = RORc(leftt, 1);
1479 work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
1480 right ^= work;
1481 leftt ^= (work << 8);
1482 /* -- */
1483 work = ((leftt >> 2) ^ right) & 0x33333333L;
1484 right ^= work;
1485 leftt ^= (work << 2);
1486 work = ((right >> 16) ^ leftt) & 0x0000ffffL;
1487 leftt ^= work;
1488 right ^= (work << 16);
1489 work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
1490 leftt ^= work;
1491 right ^= (work << 4);
1492 #else
1493 {
1494 ulong64 tmp;
1495 tmp = des_fp[0][byte(leftt, 0)] ^
1496 des_fp[1][byte(leftt, 1)] ^
1497 des_fp[2][byte(leftt, 2)] ^
1498 des_fp[3][byte(leftt, 3)] ^
1499 des_fp[4][byte(right, 0)] ^
1500 des_fp[5][byte(right, 1)] ^
1501 des_fp[6][byte(right, 2)] ^
1502 des_fp[7][byte(right, 3)];
1503 leftt = (ulong32)(tmp >> 32);
1504 right = (ulong32)(tmp & 0xFFFFFFFFUL);
1505 }
1506 #endif
1507
1508 block[0] = right;
1509 block[1] = leftt;
1510 }
1511
1512 #ifdef LTC_CLEAN_STACK
1513 static void desfunc(ulong32 *block, const ulong32 *keys)
1514 {
1515 _desfunc(block, keys);
1516 burn_stack(sizeof(ulong32) * 4 + sizeof(int));
1517 }
1518 #endif
1519
1520 /**
1521 Initialize the LTC_DES block cipher
1522 @param key The symmetric key you wish to pass
1523 @param keylen The key length in bytes
1524 @param num_rounds The number of rounds desired (0 for default)
1525 @param skey The key in as scheduled by this function.
1526 @return CRYPT_OK if successful
1527 */
1528 int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
1529 {
1530 LTC_ARGCHK(key != NULL);
1531 LTC_ARGCHK(skey != NULL);
1532
1533 if (num_rounds != 0 && num_rounds != 16) {
1534 return CRYPT_INVALID_ROUNDS;
1535 }
1536
1537 if (keylen != 8) {
1538 return CRYPT_INVALID_KEYSIZE;
1539 }
1540
1541 deskey(key, EN0, skey->des.ek);
1542 deskey(key, DE1, skey->des.dk);
1543
1544 return CRYPT_OK;
1545 }
1546
1547 /**
1548 Initialize the 3LTC_DES-EDE block cipher
1549 @param key The symmetric key you wish to pass
1550 @param keylen The key length in bytes
1551 @param num_rounds The number of rounds desired (0 for default)
1552 @param skey The key in as scheduled by this function.
1553 @return CRYPT_OK if successful
1554 */
1555 int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
1556 {
1557 LTC_ARGCHK(key != NULL);
1558 LTC_ARGCHK(skey != NULL);
1559
1560 if(num_rounds != 0 && num_rounds != 16) {
1561 return CRYPT_INVALID_ROUNDS;
1562 }
1563
1564 if (keylen != 24) {
1565 return CRYPT_INVALID_KEYSIZE;
1566 }
1567
1568 deskey(key, EN0, skey->des3.ek[0]);
1569 deskey(key+8, DE1, skey->des3.ek[1]);
1570 deskey(key+16, EN0, skey->des3.ek[2]);
1571
1572 deskey(key, DE1, skey->des3.dk[2]);
1573 deskey(key+8, EN0, skey->des3.dk[1]);
1574 deskey(key+16, DE1, skey->des3.dk[0]);
1575
1576 return CRYPT_OK;
1577 }
1578
1579 /**
1580 Encrypts a block of text with LTC_DES
1581 @param pt The input plaintext (8 bytes)
1582 @param ct The output ciphertext (8 bytes)
1583 @param skey The key as scheduled
1584 @return CRYPT_OK if successful
1585 */
1586 int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
1587 {
1588 ulong32 work[2];
1589 LTC_ARGCHK(pt != NULL);
1590 LTC_ARGCHK(ct != NULL);
1591 LTC_ARGCHK(skey != NULL);
1592 LOAD32H(work[0], pt+0);
1593 LOAD32H(work[1], pt+4);
1594 desfunc(work, skey->des.ek);
1595 STORE32H(work[0],ct+0);
1596 STORE32H(work[1],ct+4);
1597 return CRYPT_OK;
1598 }
1599
1600 /**
1601 Decrypts a block of text with LTC_DES
1602 @param ct The input ciphertext (8 bytes)
1603 @param pt The output plaintext (8 bytes)
1604 @param skey The key as scheduled
1605 @return CRYPT_OK if successful
1606 */
1607 int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
1608 {
1609 ulong32 work[2];
1610 LTC_ARGCHK(pt != NULL);
1611 LTC_ARGCHK(ct != NULL);
1612 LTC_ARGCHK(skey != NULL);
1613 LOAD32H(work[0], ct+0);
1614 LOAD32H(work[1], ct+4);
1615 desfunc(work, skey->des.dk);
1616 STORE32H(work[0],pt+0);
1617 STORE32H(work[1],pt+4);
1618 return CRYPT_OK;
1619 }
1620
1621 /**
1622 Encrypts a block of text with 3LTC_DES-EDE
1623 @param pt The input plaintext (8 bytes)
1624 @param ct The output ciphertext (8 bytes)
1625 @param skey The key as scheduled
1626 @return CRYPT_OK if successful
1627 */
1628 int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
1629 {
1630 ulong32 work[2];
1631
1632 LTC_ARGCHK(pt != NULL);
1633 LTC_ARGCHK(ct != NULL);
1634 LTC_ARGCHK(skey != NULL);
1635 LOAD32H(work[0], pt+0);
1636 LOAD32H(work[1], pt+4);
1637 desfunc(work, skey->des3.ek[0]);
1638 desfunc(work, skey->des3.ek[1]);
1639 desfunc(work, skey->des3.ek[2]);
1640 STORE32H(work[0],ct+0);
1641 STORE32H(work[1],ct+4);
1642 return CRYPT_OK;
1643 }
1644
1645 /**
1646 Decrypts a block of text with 3LTC_DES-EDE
1647 @param ct The input ciphertext (8 bytes)
1648 @param pt The output plaintext (8 bytes)
1649 @param skey The key as scheduled
1650 @return CRYPT_OK if successful
1651 */
1652 int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
1653 {
1654 ulong32 work[2];
1655 LTC_ARGCHK(pt != NULL);
1656 LTC_ARGCHK(ct != NULL);
1657 LTC_ARGCHK(skey != NULL);
1658 LOAD32H(work[0], ct+0);
1659 LOAD32H(work[1], ct+4);
1660 desfunc(work, skey->des3.dk[0]);
1661 desfunc(work, skey->des3.dk[1]);
1662 desfunc(work, skey->des3.dk[2]);
1663 STORE32H(work[0],pt+0);
1664 STORE32H(work[1],pt+4);
1665 return CRYPT_OK;
1666 }
1667
1668 /**
1669 Performs a self-test of the LTC_DES block cipher
1670 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
1671 */
1672 int des_test(void)
1673 {
1674 #ifndef LTC_TEST
1675 return CRYPT_NOP;
1676 #else
1677 int err;
1678 static const struct des_test_case {
1679 int num, mode; /* mode 1 = encrypt */
1680 unsigned char key[8], txt[8], out[8];
1681 } cases[] = {
1682 { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A },
1683 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1684 { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } },
1685 { 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1686 { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 },
1687 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1688 { 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1689 { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 },
1690 { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1691 { 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1692 { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA },
1693 { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1694 { 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1695 { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F },
1696 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1697 { 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1698 { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 },
1699 { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1700 { 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1701 { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF },
1702 { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1703 { 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1704 { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F },
1705 { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1706 { 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1707 { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 },
1708 { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1709 {10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1710 { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A },
1711 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1712
1713 { 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A },
1714 { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 },
1715 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
1716 { 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1717 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1718 { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } },
1719 { 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1720 { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1721 { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } },
1722 { 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1723 { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1724 { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } },
1725 { 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1726 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1727 { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } },
1728 { 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1729 { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1730 { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } },
1731 { 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1732 { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1733 { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } },
1734 { 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1735 { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1736 { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } },
1737 { 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1738 { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1739 { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } },
1740 {10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
1741 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1742 { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } }
1743
1744 /*** more test cases you could add if you are not convinced (the above test cases aren't really too good):
1745
1746 key plaintext ciphertext
1747 0000000000000000 0000000000000000 8CA64DE9C1B123A7
1748 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58
1749 3000000000000000 1000000000000001 958E6E627A05557B
1750 1111111111111111 1111111111111111 F40379AB9E0EC533
1751 0123456789ABCDEF 1111111111111111 17668DFC7292532D
1752 1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD
1753 0000000000000000 0000000000000000 8CA64DE9C1B123A7
1754 FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4
1755 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B
1756 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271
1757 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A
1758 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A
1759 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095
1760 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B
1761 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09
1762 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A
1763 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F
1764 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088
1765 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77
1766 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A
1767 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56
1768 025816164629B007 480D39006EE762F2 A1F9915541020B56
1769 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556
1770 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC
1771 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A
1772 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41
1773 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
1774 0101010101010101 0123456789ABCDEF 617B3A0CE8F07100
1775 1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606
1776 E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7
1777 0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451
1778 FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE
1779 0123456789ABCDEF 0000000000000000 D5D44FF720683D0D
1780 FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2
1781
1782 http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt
1783 ***/
1784 };
1785 int i, y;
1786 unsigned char tmp[8];
1787 symmetric_key des;
1788
1789 for(i=0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++)
1790 {
1791 if ((err = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) {
1792 return err;
1793 }
1794 if (cases[i].mode != 0) {
1795 des_ecb_encrypt(cases[i].txt, tmp, &des);
1796 } else {
1797 des_ecb_decrypt(cases[i].txt, tmp, &des);
1798 }
1799
1800 if (XMEMCMP(cases[i].out, tmp, sizeof(tmp)) != 0) {
1801 return CRYPT_FAIL_TESTVECTOR;
1802 }
1803
1804 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
1805 for (y = 0; y < 8; y++) tmp[y] = 0;
1806 for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des);
1807 for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des);
1808 for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR;
1809 }
1810
1811 return CRYPT_OK;
1812 #endif
1813 }
1814
1815 int des3_test(void)
1816 {
1817 #ifndef LTC_TEST
1818 return CRYPT_NOP;
1819 #else
1820 unsigned char key[24], pt[8], ct[8], tmp[8];
1821 symmetric_key skey;
1822 int x, err;
1823
1824 if ((err = des_test()) != CRYPT_OK) {
1825 return err;
1826 }
1827
1828 for (x = 0; x < 8; x++) {
1829 pt[x] = x;
1830 }
1831
1832 for (x = 0; x < 24; x++) {
1833 key[x] = x;
1834 }
1835
1836 if ((err = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) {
1837 return err;
1838 }
1839
1840 des3_ecb_encrypt(pt, ct, &skey);
1841 des3_ecb_decrypt(ct, tmp, &skey);
1842
1843 if (XMEMCMP(pt, tmp, 8) != 0) {
1844 return CRYPT_FAIL_TESTVECTOR;
1845 }
1846
1847 return CRYPT_OK;
1848 #endif
1849 }
1850
1851 /** Terminate the context
1852 @param skey The scheduled key
1853 */
1854 void des_done(symmetric_key *skey)
1855 {
1856 }
1857
1858 /** Terminate the context
1859 @param skey The scheduled key
1860 */
1861 void des3_done(symmetric_key *skey)
1862 {
1863 }
1864
1865
1866 /**
1867 Gets suitable key size
1868 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
1869 @return CRYPT_OK if the input key size is acceptable.
1870 */
1871 int des_keysize(int *keysize)
1872 {
1873 LTC_ARGCHK(keysize != NULL);
1874 if(*keysize < 8) {
1875 return CRYPT_INVALID_KEYSIZE;
1876 }
1877 *keysize = 8;
1878 return CRYPT_OK;
1879 }
1880
1881 /**
1882 Gets suitable key size
1883 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
1884 @return CRYPT_OK if the input key size is acceptable.
1885 */
1886 int des3_keysize(int *keysize)
1887 {
1888 LTC_ARGCHK(keysize != NULL);
1889 if(*keysize < 24) {
1890 return CRYPT_INVALID_KEYSIZE;
1891 }
1892 *keysize = 24;
1893 return CRYPT_OK;
1894 }
1895
1896 #endif
1897
1898
1899 /* $Source$ */
1900 /* $Revision$ */
1901 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file kasumi.c
13 Implementation of the 3GPP Kasumi block cipher
14 Derived from the 3GPP standard source code
15 */
16
17 #include "tomcrypt.h"
18
19 #ifdef LTC_KASUMI
20
21 typedef unsigned u16;
22
23 #define ROL16(x, y) ((((x)<<(y)) | ((x)>>(16-(y)))) & 0xFFFF)
24
25 const struct ltc_cipher_descriptor kasumi_desc = {
26 "kasumi",
27 21,
28 16, 16, 8, 8,
29 &kasumi_setup,
30 &kasumi_ecb_encrypt,
31 &kasumi_ecb_decrypt,
32 &kasumi_test,
33 &kasumi_done,
34 &kasumi_keysize,
35 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
36 };
37
38 static u16 FI( u16 in, u16 subkey )
39 {
40 u16 nine, seven;
41 static const u16 S7[128] = {
42 54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18,123, 33,
43 55,113, 39,114, 21, 67, 65, 12, 47, 73, 46, 27, 25,111,124, 81,
44 53, 9,121, 79, 52, 60, 58, 48,101,127, 40,120,104, 70, 71, 43,
45 20,122, 72, 61, 23,109, 13,100, 77, 1, 16, 7, 82, 10,105, 98,
46 117,116, 76, 11, 89,106, 0,125,118, 99, 86, 69, 30, 57,126, 87,
47 112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66,
48 102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29,115, 44,
49 64,107,108, 24,110, 83, 36, 78, 42, 19, 15, 41, 88,119, 59, 3 };
50 static const u16 S9[512] = {
51 167,239,161,379,391,334, 9,338, 38,226, 48,358,452,385, 90,397,
52 183,253,147,331,415,340, 51,362,306,500,262, 82,216,159,356,177,
53 175,241,489, 37,206, 17, 0,333, 44,254,378, 58,143,220, 81,400,
54 95, 3,315,245, 54,235,218,405,472,264,172,494,371,290,399, 76,
55 165,197,395,121,257,480,423,212,240, 28,462,176,406,507,288,223,
56 501,407,249,265, 89,186,221,428,164, 74,440,196,458,421,350,163,
57 232,158,134,354, 13,250,491,142,191, 69,193,425,152,227,366,135,
58 344,300,276,242,437,320,113,278, 11,243, 87,317, 36, 93,496, 27,
59 487,446,482, 41, 68,156,457,131,326,403,339, 20, 39,115,442,124,
60 475,384,508, 53,112,170,479,151,126,169, 73,268,279,321,168,364,
61 363,292, 46,499,393,327,324, 24,456,267,157,460,488,426,309,229,
62 439,506,208,271,349,401,434,236, 16,209,359, 52, 56,120,199,277,
63 465,416,252,287,246, 6, 83,305,420,345,153,502, 65, 61,244,282,
64 173,222,418, 67,386,368,261,101,476,291,195,430, 49, 79,166,330,
65 280,383,373,128,382,408,155,495,367,388,274,107,459,417, 62,454,
66 132,225,203,316,234, 14,301, 91,503,286,424,211,347,307,140,374,
67 35,103,125,427, 19,214,453,146,498,314,444,230,256,329,198,285,
68 50,116, 78,410, 10,205,510,171,231, 45,139,467, 29, 86,505, 32,
69 72, 26,342,150,313,490,431,238,411,325,149,473, 40,119,174,355,
70 185,233,389, 71,448,273,372, 55,110,178,322, 12,469,392,369,190,
71 1,109,375,137,181, 88, 75,308,260,484, 98,272,370,275,412,111,
72 336,318, 4,504,492,259,304, 77,337,435, 21,357,303,332,483, 18,
73 47, 85, 25,497,474,289,100,269,296,478,270,106, 31,104,433, 84,
74 414,486,394, 96, 99,154,511,148,413,361,409,255,162,215,302,201,
75 266,351,343,144,441,365,108,298,251, 34,182,509,138,210,335,133,
76 311,352,328,141,396,346,123,319,450,281,429,228,443,481, 92,404,
77 485,422,248,297, 23,213,130,466, 22,217,283, 70,294,360,419,127,
78 312,377, 7,468,194, 2,117,295,463,258,224,447,247,187, 80,398,
79 284,353,105,390,299,471,470,184, 57,200,348, 63,204,188, 33,451,
80 97, 30,310,219, 94,160,129,493, 64,179,263,102,189,207,114,402,
81 438,477,387,122,192, 42,381, 5,145,118,180,449,293,323,136,380,
82 43, 66, 60,455,341,445,202,432, 8,237, 15,376,436,464, 59,461};
83
84 /* The sixteen bit input is split into two unequal halves, *
85 * nine bits and seven bits - as is the subkey */
86
87 nine = (u16)(in>>7)&0x1FF;
88 seven = (u16)(in&0x7F);
89
90 /* Now run the various operations */
91 nine = (u16)(S9[nine] ^ seven);
92 seven = (u16)(S7[seven] ^ (nine & 0x7F));
93 seven ^= (subkey>>9);
94 nine ^= (subkey&0x1FF);
95 nine = (u16)(S9[nine] ^ seven);
96 seven = (u16)(S7[seven] ^ (nine & 0x7F));
97 return (u16)(seven<<9) + nine;
98 }
99
100 static ulong32 FO( ulong32 in, int round_no, symmetric_key *key)
101 {
102 u16 left, right;
103
104 /* Split the input into two 16-bit words */
105 left = (u16)(in>>16);
106 right = (u16) in&0xFFFF;
107
108 /* Now apply the same basic transformation three times */
109 left ^= key->kasumi.KOi1[round_no];
110 left = FI( left, key->kasumi.KIi1[round_no] );
111 left ^= right;
112
113 right ^= key->kasumi.KOi2[round_no];
114 right = FI( right, key->kasumi.KIi2[round_no] );
115 right ^= left;
116
117 left ^= key->kasumi.KOi3[round_no];
118 left = FI( left, key->kasumi.KIi3[round_no] );
119 left ^= right;
120
121 return (((ulong32)right)<<16)+left;
122 }
123
124 static ulong32 FL( ulong32 in, int round_no, symmetric_key *key )
125 {
126 u16 l, r, a, b;
127 /* split out the left and right halves */
128 l = (u16)(in>>16);
129 r = (u16)(in)&0xFFFF;
130 /* do the FL() operations */
131 a = (u16) (l & key->kasumi.KLi1[round_no]);
132 r ^= ROL16(a,1);
133 b = (u16)(r | key->kasumi.KLi2[round_no]);
134 l ^= ROL16(b,1);
135 /* put the two halves back together */
136
137 return (((ulong32)l)<<16) + r;
138 }
139
140 int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
141 {
142 ulong32 left, right, temp;
143 int n;
144
145 LTC_ARGCHK(pt != NULL);
146 LTC_ARGCHK(ct != NULL);
147 LTC_ARGCHK(skey != NULL);
148
149 LOAD32H(left, pt);
150 LOAD32H(right, pt+4);
151
152 for (n = 0; n <= 7; ) {
153 temp = FL(left, n, skey);
154 temp = FO(temp, n++, skey);
155 right ^= temp;
156 temp = FO(right, n, skey);
157 temp = FL(temp, n++, skey);
158 left ^= temp;
159 }
160
161 STORE32H(left, ct);
162 STORE32H(right, ct+4);
163
164 return CRYPT_OK;
165 }
166
167 int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
168 {
169 ulong32 left, right, temp;
170 int n;
171
172 LTC_ARGCHK(pt != NULL);
173 LTC_ARGCHK(ct != NULL);
174 LTC_ARGCHK(skey != NULL);
175
176 LOAD32H(left, ct);
177 LOAD32H(right, ct+4);
178
179 for (n = 7; n >= 0; ) {
180 temp = FO(right, n, skey);
181 temp = FL(temp, n--, skey);
182 left ^= temp;
183 temp = FL(left, n, skey);
184 temp = FO(temp, n--, skey);
185 right ^= temp;
186 }
187
188 STORE32H(left, pt);
189 STORE32H(right, pt+4);
190
191 return CRYPT_OK;
192 }
193
194 int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
195 {
196 static const u16 C[8] = { 0x0123,0x4567,0x89AB,0xCDEF, 0xFEDC,0xBA98,0x7654,0x3210 };
197 u16 ukey[8], Kprime[8];
198 int n;
199
200 LTC_ARGCHK(key != NULL);
201 LTC_ARGCHK(skey != NULL);
202
203 if (keylen != 16) {
204 return CRYPT_INVALID_KEYSIZE;
205 }
206
207 if (num_rounds != 0 && num_rounds != 8) {
208 return CRYPT_INVALID_ROUNDS;
209 }
210
211 /* Start by ensuring the subkeys are endian correct on a 16-bit basis */
212 for (n = 0; n < 8; n++ ) {
213 ukey[n] = (((u16)key[2*n]) << 8) | key[2*n+1];
214 }
215
216 /* Now build the K'[] keys */
217 for (n = 0; n < 8; n++) {
218 Kprime[n] = ukey[n] ^ C[n];
219 }
220
221 /* Finally construct the various sub keys */
222 for(n = 0; n < 8; n++) {
223 skey->kasumi.KLi1[n] = ROL16(ukey[n],1);
224 skey->kasumi.KLi2[n] = Kprime[(n+2)&0x7];
225 skey->kasumi.KOi1[n] = ROL16(ukey[(n+1)&0x7],5);
226 skey->kasumi.KOi2[n] = ROL16(ukey[(n+5)&0x7],8);
227 skey->kasumi.KOi3[n] = ROL16(ukey[(n+6)&0x7],13);
228 skey->kasumi.KIi1[n] = Kprime[(n+4)&0x7];
229 skey->kasumi.KIi2[n] = Kprime[(n+3)&0x7];
230 skey->kasumi.KIi3[n] = Kprime[(n+7)&0x7];
231 }
232
233 return CRYPT_OK;
234 }
235
236 void kasumi_done(symmetric_key *skey)
237 {
238 }
239
240 int kasumi_keysize(int *keysize)
241 {
242 LTC_ARGCHK(keysize != NULL);
243 if (*keysize >= 16) {
244 *keysize = 16;
245 return CRYPT_OK;
246 } else {
247 return CRYPT_INVALID_KEYSIZE;
248 }
249 }
250
251 int kasumi_test(void)
252 {
253 #ifndef LTC_TEST
254 return CRYPT_NOP;
255 #else
256 static const struct {
257 unsigned char key[16], pt[8], ct[8];
258 } tests[] = {
259
260 {
261 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
262 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
263 { 0x4B, 0x58, 0xA7, 0x71, 0xAF, 0xC7, 0xE5, 0xE8 }
264 },
265
266 {
267 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
268 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
269 { 0x7E, 0xEF, 0x11, 0x3C, 0x95, 0xBB, 0x5A, 0x77 }
270 },
271
272 {
273 { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
274 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
275 { 0x5F, 0x14, 0x06, 0x86, 0xD7, 0xAD, 0x5A, 0x39 },
276 },
277
278 {
279 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
280 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
281 { 0x2E, 0x14, 0x91, 0xCF, 0x70, 0xAA, 0x46, 0x5D }
282 },
283
284 {
285 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 },
286 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
287 { 0xB5, 0x45, 0x86, 0xF4, 0xAB, 0x9A, 0xE5, 0x46 }
288 },
289
290 };
291 unsigned char buf[2][8];
292 symmetric_key key;
293 int err, x;
294
295 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
296 if ((err = kasumi_setup(tests[x].key, 16, 0, &key)) != CRYPT_OK) {
297 return err;
298 }
299 if ((err = kasumi_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
300 return err;
301 }
302 if ((err = kasumi_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
303 return err;
304 }
305 if (XMEMCMP(tests[x].pt, buf[1], 8) || XMEMCMP(tests[x].ct, buf[0], 8)) {
306 return CRYPT_FAIL_TESTVECTOR;
307 }
308 }
309 return CRYPT_OK;
310 #endif
311 }
312
313 #endif
314
315 /* $Source$ */
316 /* $Revision$ */
317 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file khazad.c
14 Khazad implementation derived from public domain source
15 Authors: Paulo S.L.M. Barreto and Vincent Rijmen.
16 */
17
18 #ifdef LTC_KHAZAD
19
20 const struct ltc_cipher_descriptor khazad_desc = {
21 "khazad",
22 18,
23 16, 16, 8, 8,
24 &khazad_setup,
25 &khazad_ecb_encrypt,
26 &khazad_ecb_decrypt,
27 &khazad_test,
28 &khazad_done,
29 &khazad_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 #define R 8
34 #define KEYSIZE 128
35 #define KEYSIZEB (KEYSIZE/8)
36 #define BLOCKSIZE 64
37 #define BLOCKSIZEB (BLOCKSIZE/8)
38
39 static const ulong64 T0[256] = {
40 CONST64(0xbad3d268bbb96a01), CONST64(0x54fc4d19e59a66b1), CONST64(0x2f71bc93e26514cd), CONST64(0x749ccdb925871b51),
41 CONST64(0x53f55102f7a257a4), CONST64(0xd3686bb8d0d6be03), CONST64(0xd26b6fbdd6deb504), CONST64(0x4dd72964b35285fe),
42 CONST64(0x50f05d0dfdba4aad), CONST64(0xace98a26cf09e063), CONST64(0x8d8a0e83091c9684), CONST64(0xbfdcc679a5914d1a),
43 CONST64(0x7090ddad3da7374d), CONST64(0x52f65507f1aa5ca3), CONST64(0x9ab352c87ba417e1), CONST64(0x4cd42d61b55a8ef9),
44 CONST64(0xea238f65460320ac), CONST64(0xd56273a6c4e68411), CONST64(0x97a466f155cc68c2), CONST64(0xd16e63b2dcc6a80d),
45 CONST64(0x3355ccffaa85d099), CONST64(0x51f35908fbb241aa), CONST64(0x5bed712ac7e20f9c), CONST64(0xa6f7a204f359ae55),
46 CONST64(0xde7f5f81febec120), CONST64(0x48d83d75ad7aa2e5), CONST64(0xa8e59a32d729cc7f), CONST64(0x99b65ec771bc0ae8),
47 CONST64(0xdb704b90e096e63b), CONST64(0x3256c8faac8ddb9e), CONST64(0xb7c4e65195d11522), CONST64(0xfc19d72b32b3aace),
48 CONST64(0xe338ab48704b7393), CONST64(0x9ebf42dc63843bfd), CONST64(0x91ae7eef41fc52d0), CONST64(0x9bb056cd7dac1ce6),
49 CONST64(0xe23baf4d76437894), CONST64(0xbbd0d66dbdb16106), CONST64(0x41c319589b32f1da), CONST64(0x6eb2a5cb7957e517),
50 CONST64(0xa5f2ae0bf941b35c), CONST64(0xcb400bc08016564b), CONST64(0x6bbdb1da677fc20c), CONST64(0x95a26efb59dc7ecc),
51 CONST64(0xa1febe1fe1619f40), CONST64(0xf308eb1810cbc3e3), CONST64(0xb1cefe4f81e12f30), CONST64(0x0206080a0c10160e),
52 CONST64(0xcc4917db922e675e), CONST64(0xc45137f3a26e3f66), CONST64(0x1d2774694ee8cf53), CONST64(0x143c504478a09c6c),
53 CONST64(0xc3582be8b0560e73), CONST64(0x63a591f2573f9a34), CONST64(0xda734f95e69eed3c), CONST64(0x5de76934d3d2358e),
54 CONST64(0x5fe1613edfc22380), CONST64(0xdc79578bf2aed72e), CONST64(0x7d87e99413cf486e), CONST64(0xcd4a13de94266c59),
55 CONST64(0x7f81e19e1fdf5e60), CONST64(0x5aee752fc1ea049b), CONST64(0x6cb4adc17547f319), CONST64(0x5ce46d31d5da3e89),
56 CONST64(0xf704fb0c08ebefff), CONST64(0x266a98bed42d47f2), CONST64(0xff1cdb2438abb7c7), CONST64(0xed2a937e543b11b9),
57 CONST64(0xe825876f4a1336a2), CONST64(0x9dba4ed3699c26f4), CONST64(0x6fb1a1ce7f5fee10), CONST64(0x8e8f028c03048b8d),
58 CONST64(0x192b647d56c8e34f), CONST64(0xa0fdba1ae7699447), CONST64(0xf00de7171ad3deea), CONST64(0x89861e97113cba98),
59 CONST64(0x0f113c332278692d), CONST64(0x07091c1b12383115), CONST64(0xafec8629c511fd6a), CONST64(0xfb10cb30208b9bdb),
60 CONST64(0x0818202830405838), CONST64(0x153f54417ea8976b), CONST64(0x0d1734392e687f23), CONST64(0x040c101418202c1c),
61 CONST64(0x0103040506080b07), CONST64(0x64ac8de94507ab21), CONST64(0xdf7c5b84f8b6ca27), CONST64(0x769ac5b329970d5f),
62 CONST64(0x798bf9800bef6472), CONST64(0xdd7a538ef4a6dc29), CONST64(0x3d47f4c98ef5b2b3), CONST64(0x163a584e74b08a62),
63 CONST64(0x3f41fcc382e5a4bd), CONST64(0x3759dcebb2a5fc85), CONST64(0x6db7a9c4734ff81e), CONST64(0x3848e0d890dd95a8),
64 CONST64(0xb9d6de67b1a17708), CONST64(0x7395d1a237bf2a44), CONST64(0xe926836a4c1b3da5), CONST64(0x355fd4e1beb5ea8b),
65 CONST64(0x55ff491ce3926db6), CONST64(0x7193d9a83baf3c4a), CONST64(0x7b8df18a07ff727c), CONST64(0x8c890a860f149d83),
66 CONST64(0x7296d5a731b72143), CONST64(0x88851a921734b19f), CONST64(0xf607ff090ee3e4f8), CONST64(0x2a7ea882fc4d33d6),
67 CONST64(0x3e42f8c684edafba), CONST64(0x5ee2653bd9ca2887), CONST64(0x27699cbbd2254cf5), CONST64(0x46ca0543890ac0cf),
68 CONST64(0x0c14303c28607424), CONST64(0x65af89ec430fa026), CONST64(0x68b8bdd56d67df05), CONST64(0x61a399f85b2f8c3a),
69 CONST64(0x03050c0f0a181d09), CONST64(0xc15e23e2bc46187d), CONST64(0x57f94116ef827bb8), CONST64(0xd6677fa9cefe9918),
70 CONST64(0xd976439aec86f035), CONST64(0x58e87d25cdfa1295), CONST64(0xd875479fea8efb32), CONST64(0x66aa85e34917bd2f),
71 CONST64(0xd7647bacc8f6921f), CONST64(0x3a4ee8d29ccd83a6), CONST64(0xc84507cf8a0e4b42), CONST64(0x3c44f0cc88fdb9b4),
72 CONST64(0xfa13cf35268390dc), CONST64(0x96a762f453c463c5), CONST64(0xa7f4a601f551a552), CONST64(0x98b55ac277b401ef),
73 CONST64(0xec29977b52331abe), CONST64(0xb8d5da62b7a97c0f), CONST64(0xc7543bfca876226f), CONST64(0xaeef822cc319f66d),
74 CONST64(0x69bbb9d06b6fd402), CONST64(0x4bdd317aa762bfec), CONST64(0xabe0963ddd31d176), CONST64(0xa9e69e37d121c778),
75 CONST64(0x67a981e64f1fb628), CONST64(0x0a1e28223c504e36), CONST64(0x47c901468f02cbc8), CONST64(0xf20bef1d16c3c8e4),
76 CONST64(0xb5c2ee5b99c1032c), CONST64(0x226688aacc0d6bee), CONST64(0xe532b356647b4981), CONST64(0xee2f9f715e230cb0),
77 CONST64(0xbedfc27ca399461d), CONST64(0x2b7dac87fa4538d1), CONST64(0x819e3ebf217ce2a0), CONST64(0x1236485a6c90a67e),
78 CONST64(0x839836b52d6cf4ae), CONST64(0x1b2d6c775ad8f541), CONST64(0x0e1238362470622a), CONST64(0x23658cafca0560e9),
79 CONST64(0xf502f30604fbf9f1), CONST64(0x45cf094c8312ddc6), CONST64(0x216384a5c61576e7), CONST64(0xce4f1fd19e3e7150),
80 CONST64(0x49db3970ab72a9e2), CONST64(0x2c74b09ce87d09c4), CONST64(0xf916c33a2c9b8dd5), CONST64(0xe637bf596e635488),
81 CONST64(0xb6c7e25493d91e25), CONST64(0x2878a088f05d25d8), CONST64(0x17395c4b72b88165), CONST64(0x829b32b02b64ffa9),
82 CONST64(0x1a2e68725cd0fe46), CONST64(0x8b80169d1d2cac96), CONST64(0xfe1fdf213ea3bcc0), CONST64(0x8a8312981b24a791),
83 CONST64(0x091b242d3648533f), CONST64(0xc94603ca8c064045), CONST64(0x879426a1354cd8b2), CONST64(0x4ed2256bb94a98f7),
84 CONST64(0xe13ea3427c5b659d), CONST64(0x2e72b896e46d1fca), CONST64(0xe431b75362734286), CONST64(0xe03da7477a536e9a),
85 CONST64(0xeb208b60400b2bab), CONST64(0x90ad7aea47f459d7), CONST64(0xa4f1aa0eff49b85b), CONST64(0x1e22786644f0d25a),
86 CONST64(0x85922eab395ccebc), CONST64(0x60a09dfd5d27873d), CONST64(0x0000000000000000), CONST64(0x256f94b1de355afb),
87 CONST64(0xf401f70302f3f2f6), CONST64(0xf10ee3121cdbd5ed), CONST64(0x94a16afe5fd475cb), CONST64(0x0b1d2c273a584531),
88 CONST64(0xe734bb5c686b5f8f), CONST64(0x759fc9bc238f1056), CONST64(0xef2c9b74582b07b7), CONST64(0x345cd0e4b8bde18c),
89 CONST64(0x3153c4f5a695c697), CONST64(0xd46177a3c2ee8f16), CONST64(0xd06d67b7dacea30a), CONST64(0x869722a43344d3b5),
90 CONST64(0x7e82e59b19d75567), CONST64(0xadea8e23c901eb64), CONST64(0xfd1ad32e34bba1c9), CONST64(0x297ba48df6552edf),
91 CONST64(0x3050c0f0a09dcd90), CONST64(0x3b4decd79ac588a1), CONST64(0x9fbc46d9658c30fa), CONST64(0xf815c73f2a9386d2),
92 CONST64(0xc6573ff9ae7e2968), CONST64(0x13354c5f6a98ad79), CONST64(0x060a181e14303a12), CONST64(0x050f14111e28271b),
93 CONST64(0xc55233f6a4663461), CONST64(0x113344556688bb77), CONST64(0x7799c1b62f9f0658), CONST64(0x7c84ed9115c74369),
94 CONST64(0x7a8ef58f01f7797b), CONST64(0x7888fd850de76f75), CONST64(0x365ad8eeb4adf782), CONST64(0x1c24706c48e0c454),
95 CONST64(0x394be4dd96d59eaf), CONST64(0x59eb7920cbf21992), CONST64(0x1828607850c0e848), CONST64(0x56fa4513e98a70bf),
96 CONST64(0xb3c8f6458df1393e), CONST64(0xb0cdfa4a87e92437), CONST64(0x246c90b4d83d51fc), CONST64(0x206080a0c01d7de0),
97 CONST64(0xb2cbf2408bf93239), CONST64(0x92ab72e04be44fd9), CONST64(0xa3f8b615ed71894e), CONST64(0xc05d27e7ba4e137a),
98 CONST64(0x44cc0d49851ad6c1), CONST64(0x62a695f751379133), CONST64(0x103040506080b070), CONST64(0xb4c1ea5e9fc9082b),
99 CONST64(0x84912aae3f54c5bb), CONST64(0x43c511529722e7d4), CONST64(0x93a876e54dec44de), CONST64(0xc25b2fedb65e0574),
100 CONST64(0x4ade357fa16ab4eb), CONST64(0xbddace73a9815b14), CONST64(0x8f8c0689050c808a), CONST64(0x2d77b499ee7502c3),
101 CONST64(0xbcd9ca76af895013), CONST64(0x9cb94ad66f942df3), CONST64(0x6abeb5df6177c90b), CONST64(0x40c01d5d9d3afadd),
102 CONST64(0xcf4c1bd498367a57), CONST64(0xa2fbb210eb798249), CONST64(0x809d3aba2774e9a7), CONST64(0x4fd1216ebf4293f0),
103 CONST64(0x1f217c6342f8d95d), CONST64(0xca430fc5861e5d4c), CONST64(0xaae39238db39da71), CONST64(0x42c61557912aecd3),
104 };
105
106 static const ulong64 T1[256] = {
107 CONST64(0xd3ba68d2b9bb016a), CONST64(0xfc54194d9ae5b166), CONST64(0x712f93bc65e2cd14), CONST64(0x9c74b9cd8725511b),
108 CONST64(0xf5530251a2f7a457), CONST64(0x68d3b86bd6d003be), CONST64(0x6bd2bd6fded604b5), CONST64(0xd74d642952b3fe85),
109 CONST64(0xf0500d5dbafdad4a), CONST64(0xe9ac268a09cf63e0), CONST64(0x8a8d830e1c098496), CONST64(0xdcbf79c691a51a4d),
110 CONST64(0x9070addda73d4d37), CONST64(0xf6520755aaf1a35c), CONST64(0xb39ac852a47be117), CONST64(0xd44c612d5ab5f98e),
111 CONST64(0x23ea658f0346ac20), CONST64(0x62d5a673e6c41184), CONST64(0xa497f166cc55c268), CONST64(0x6ed1b263c6dc0da8),
112 CONST64(0x5533ffcc85aa99d0), CONST64(0xf3510859b2fbaa41), CONST64(0xed5b2a71e2c79c0f), CONST64(0xf7a604a259f355ae),
113 CONST64(0x7fde815fbefe20c1), CONST64(0xd848753d7aade5a2), CONST64(0xe5a8329a29d77fcc), CONST64(0xb699c75ebc71e80a),
114 CONST64(0x70db904b96e03be6), CONST64(0x5632fac88dac9edb), CONST64(0xc4b751e6d1952215), CONST64(0x19fc2bd7b332ceaa),
115 CONST64(0x38e348ab4b709373), CONST64(0xbf9edc428463fd3b), CONST64(0xae91ef7efc41d052), CONST64(0xb09bcd56ac7de61c),
116 CONST64(0x3be24daf43769478), CONST64(0xd0bb6dd6b1bd0661), CONST64(0xc3415819329bdaf1), CONST64(0xb26ecba5577917e5),
117 CONST64(0xf2a50bae41f95cb3), CONST64(0x40cbc00b16804b56), CONST64(0xbd6bdab17f670cc2), CONST64(0xa295fb6edc59cc7e),
118 CONST64(0xfea11fbe61e1409f), CONST64(0x08f318ebcb10e3c3), CONST64(0xceb14ffee181302f), CONST64(0x06020a08100c0e16),
119 CONST64(0x49ccdb172e925e67), CONST64(0x51c4f3376ea2663f), CONST64(0x271d6974e84e53cf), CONST64(0x3c144450a0786c9c),
120 CONST64(0x58c3e82b56b0730e), CONST64(0xa563f2913f57349a), CONST64(0x73da954f9ee63ced), CONST64(0xe75d3469d2d38e35),
121 CONST64(0xe15f3e61c2df8023), CONST64(0x79dc8b57aef22ed7), CONST64(0x877d94e9cf136e48), CONST64(0x4acdde132694596c),
122 CONST64(0x817f9ee1df1f605e), CONST64(0xee5a2f75eac19b04), CONST64(0xb46cc1ad477519f3), CONST64(0xe45c316ddad5893e),
123 CONST64(0x04f70cfbeb08ffef), CONST64(0x6a26be982dd4f247), CONST64(0x1cff24dbab38c7b7), CONST64(0x2aed7e933b54b911),
124 CONST64(0x25e86f87134aa236), CONST64(0xba9dd34e9c69f426), CONST64(0xb16fcea15f7f10ee), CONST64(0x8f8e8c0204038d8b),
125 CONST64(0x2b197d64c8564fe3), CONST64(0xfda01aba69e74794), CONST64(0x0df017e7d31aeade), CONST64(0x8689971e3c1198ba),
126 CONST64(0x110f333c78222d69), CONST64(0x09071b1c38121531), CONST64(0xecaf298611c56afd), CONST64(0x10fb30cb8b20db9b),
127 CONST64(0x1808282040303858), CONST64(0x3f154154a87e6b97), CONST64(0x170d3934682e237f), CONST64(0x0c04141020181c2c),
128 CONST64(0x030105040806070b), CONST64(0xac64e98d074521ab), CONST64(0x7cdf845bb6f827ca), CONST64(0x9a76b3c597295f0d),
129 CONST64(0x8b7980f9ef0b7264), CONST64(0x7add8e53a6f429dc), CONST64(0x473dc9f4f58eb3b2), CONST64(0x3a164e58b074628a),
130 CONST64(0x413fc3fce582bda4), CONST64(0x5937ebdca5b285fc), CONST64(0xb76dc4a94f731ef8), CONST64(0x4838d8e0dd90a895),
131 CONST64(0xd6b967dea1b10877), CONST64(0x9573a2d1bf37442a), CONST64(0x26e96a831b4ca53d), CONST64(0x5f35e1d4b5be8bea),
132 CONST64(0xff551c4992e3b66d), CONST64(0x9371a8d9af3b4a3c), CONST64(0x8d7b8af1ff077c72), CONST64(0x898c860a140f839d),
133 CONST64(0x9672a7d5b7314321), CONST64(0x8588921a34179fb1), CONST64(0x07f609ffe30ef8e4), CONST64(0x7e2a82a84dfcd633),
134 CONST64(0x423ec6f8ed84baaf), CONST64(0xe25e3b65cad98728), CONST64(0x6927bb9c25d2f54c), CONST64(0xca4643050a89cfc0),
135 CONST64(0x140c3c3060282474), CONST64(0xaf65ec890f4326a0), CONST64(0xb868d5bd676d05df), CONST64(0xa361f8992f5b3a8c),
136 CONST64(0x05030f0c180a091d), CONST64(0x5ec1e22346bc7d18), CONST64(0xf957164182efb87b), CONST64(0x67d6a97ffece1899),
137 CONST64(0x76d99a4386ec35f0), CONST64(0xe858257dfacd9512), CONST64(0x75d89f478eea32fb), CONST64(0xaa66e38517492fbd),
138 CONST64(0x64d7ac7bf6c81f92), CONST64(0x4e3ad2e8cd9ca683), CONST64(0x45c8cf070e8a424b), CONST64(0x443cccf0fd88b4b9),
139 CONST64(0x13fa35cf8326dc90), CONST64(0xa796f462c453c563), CONST64(0xf4a701a651f552a5), CONST64(0xb598c25ab477ef01),
140 CONST64(0x29ec7b973352be1a), CONST64(0xd5b862daa9b70f7c), CONST64(0x54c7fc3b76a86f22), CONST64(0xefae2c8219c36df6),
141 CONST64(0xbb69d0b96f6b02d4), CONST64(0xdd4b7a3162a7ecbf), CONST64(0xe0ab3d9631dd76d1), CONST64(0xe6a9379e21d178c7),
142 CONST64(0xa967e6811f4f28b6), CONST64(0x1e0a2228503c364e), CONST64(0xc9474601028fc8cb), CONST64(0x0bf21defc316e4c8),
143 CONST64(0xc2b55beec1992c03), CONST64(0x6622aa880dccee6b), CONST64(0x32e556b37b648149), CONST64(0x2fee719f235eb00c),
144 CONST64(0xdfbe7cc299a31d46), CONST64(0x7d2b87ac45fad138), CONST64(0x9e81bf3e7c21a0e2), CONST64(0x36125a48906c7ea6),
145 CONST64(0x9883b5366c2daef4), CONST64(0x2d1b776cd85a41f5), CONST64(0x120e363870242a62), CONST64(0x6523af8c05cae960),
146 CONST64(0x02f506f3fb04f1f9), CONST64(0xcf454c091283c6dd), CONST64(0x6321a58415c6e776), CONST64(0x4fced11f3e9e5071),
147 CONST64(0xdb49703972abe2a9), CONST64(0x742c9cb07de8c409), CONST64(0x16f93ac39b2cd58d), CONST64(0x37e659bf636e8854),
148 CONST64(0xc7b654e2d993251e), CONST64(0x782888a05df0d825), CONST64(0x39174b5cb8726581), CONST64(0x9b82b032642ba9ff),
149 CONST64(0x2e1a7268d05c46fe), CONST64(0x808b9d162c1d96ac), CONST64(0x1ffe21dfa33ec0bc), CONST64(0x838a9812241b91a7),
150 CONST64(0x1b092d2448363f53), CONST64(0x46c9ca03068c4540), CONST64(0x9487a1264c35b2d8), CONST64(0xd24e6b254ab9f798),
151 CONST64(0x3ee142a35b7c9d65), CONST64(0x722e96b86de4ca1f), CONST64(0x31e453b773628642), CONST64(0x3de047a7537a9a6e),
152 CONST64(0x20eb608b0b40ab2b), CONST64(0xad90ea7af447d759), CONST64(0xf1a40eaa49ff5bb8), CONST64(0x221e6678f0445ad2),
153 CONST64(0x9285ab2e5c39bcce), CONST64(0xa060fd9d275d3d87), CONST64(0x0000000000000000), CONST64(0x6f25b19435defb5a),
154 CONST64(0x01f403f7f302f6f2), CONST64(0x0ef112e3db1cedd5), CONST64(0xa194fe6ad45fcb75), CONST64(0x1d0b272c583a3145),
155 CONST64(0x34e75cbb6b688f5f), CONST64(0x9f75bcc98f235610), CONST64(0x2cef749b2b58b707), CONST64(0x5c34e4d0bdb88ce1),
156 CONST64(0x5331f5c495a697c6), CONST64(0x61d4a377eec2168f), CONST64(0x6dd0b767ceda0aa3), CONST64(0x9786a4224433b5d3),
157 CONST64(0x827e9be5d7196755), CONST64(0xeaad238e01c964eb), CONST64(0x1afd2ed3bb34c9a1), CONST64(0x7b298da455f6df2e),
158 CONST64(0x5030f0c09da090cd), CONST64(0x4d3bd7ecc59aa188), CONST64(0xbc9fd9468c65fa30), CONST64(0x15f83fc7932ad286),
159 CONST64(0x57c6f93f7eae6829), CONST64(0x35135f4c986a79ad), CONST64(0x0a061e183014123a), CONST64(0x0f051114281e1b27),
160 CONST64(0x52c5f63366a46134), CONST64(0x33115544886677bb), CONST64(0x9977b6c19f2f5806), CONST64(0x847c91edc7156943),
161 CONST64(0x8e7a8ff5f7017b79), CONST64(0x887885fde70d756f), CONST64(0x5a36eed8adb482f7), CONST64(0x241c6c70e04854c4),
162 CONST64(0x4b39dde4d596af9e), CONST64(0xeb592079f2cb9219), CONST64(0x28187860c05048e8), CONST64(0xfa5613458ae9bf70),
163 CONST64(0xc8b345f6f18d3e39), CONST64(0xcdb04afae9873724), CONST64(0x6c24b4903dd8fc51), CONST64(0x6020a0801dc0e07d),
164 CONST64(0xcbb240f2f98b3932), CONST64(0xab92e072e44bd94f), CONST64(0xf8a315b671ed4e89), CONST64(0x5dc0e7274eba7a13),
165 CONST64(0xcc44490d1a85c1d6), CONST64(0xa662f79537513391), CONST64(0x30105040806070b0), CONST64(0xc1b45eeac99f2b08),
166 CONST64(0x9184ae2a543fbbc5), CONST64(0xc54352112297d4e7), CONST64(0xa893e576ec4dde44), CONST64(0x5bc2ed2f5eb67405),
167 CONST64(0xde4a7f356aa1ebb4), CONST64(0xdabd73ce81a9145b), CONST64(0x8c8f89060c058a80), CONST64(0x772d99b475eec302),
168 CONST64(0xd9bc76ca89af1350), CONST64(0xb99cd64a946ff32d), CONST64(0xbe6adfb577610bc9), CONST64(0xc0405d1d3a9dddfa),
169 CONST64(0x4ccfd41b3698577a), CONST64(0xfba210b279eb4982), CONST64(0x9d80ba3a7427a7e9), CONST64(0xd14f6e2142bff093),
170 CONST64(0x211f637cf8425dd9), CONST64(0x43cac50f1e864c5d), CONST64(0xe3aa389239db71da), CONST64(0xc64257152a91d3ec),
171 };
172
173 static const ulong64 T2[256] = {
174 CONST64(0xd268bad36a01bbb9), CONST64(0x4d1954fc66b1e59a), CONST64(0xbc932f7114cde265), CONST64(0xcdb9749c1b512587),
175 CONST64(0x510253f557a4f7a2), CONST64(0x6bb8d368be03d0d6), CONST64(0x6fbdd26bb504d6de), CONST64(0x29644dd785feb352),
176 CONST64(0x5d0d50f04aadfdba), CONST64(0x8a26ace9e063cf09), CONST64(0x0e838d8a9684091c), CONST64(0xc679bfdc4d1aa591),
177 CONST64(0xddad7090374d3da7), CONST64(0x550752f65ca3f1aa), CONST64(0x52c89ab317e17ba4), CONST64(0x2d614cd48ef9b55a),
178 CONST64(0x8f65ea2320ac4603), CONST64(0x73a6d5628411c4e6), CONST64(0x66f197a468c255cc), CONST64(0x63b2d16ea80ddcc6),
179 CONST64(0xccff3355d099aa85), CONST64(0x590851f341aafbb2), CONST64(0x712a5bed0f9cc7e2), CONST64(0xa204a6f7ae55f359),
180 CONST64(0x5f81de7fc120febe), CONST64(0x3d7548d8a2e5ad7a), CONST64(0x9a32a8e5cc7fd729), CONST64(0x5ec799b60ae871bc),
181 CONST64(0x4b90db70e63be096), CONST64(0xc8fa3256db9eac8d), CONST64(0xe651b7c4152295d1), CONST64(0xd72bfc19aace32b3),
182 CONST64(0xab48e3387393704b), CONST64(0x42dc9ebf3bfd6384), CONST64(0x7eef91ae52d041fc), CONST64(0x56cd9bb01ce67dac),
183 CONST64(0xaf4de23b78947643), CONST64(0xd66dbbd06106bdb1), CONST64(0x195841c3f1da9b32), CONST64(0xa5cb6eb2e5177957),
184 CONST64(0xae0ba5f2b35cf941), CONST64(0x0bc0cb40564b8016), CONST64(0xb1da6bbdc20c677f), CONST64(0x6efb95a27ecc59dc),
185 CONST64(0xbe1fa1fe9f40e161), CONST64(0xeb18f308c3e310cb), CONST64(0xfe4fb1ce2f3081e1), CONST64(0x080a0206160e0c10),
186 CONST64(0x17dbcc49675e922e), CONST64(0x37f3c4513f66a26e), CONST64(0x74691d27cf534ee8), CONST64(0x5044143c9c6c78a0),
187 CONST64(0x2be8c3580e73b056), CONST64(0x91f263a59a34573f), CONST64(0x4f95da73ed3ce69e), CONST64(0x69345de7358ed3d2),
188 CONST64(0x613e5fe12380dfc2), CONST64(0x578bdc79d72ef2ae), CONST64(0xe9947d87486e13cf), CONST64(0x13decd4a6c599426),
189 CONST64(0xe19e7f815e601fdf), CONST64(0x752f5aee049bc1ea), CONST64(0xadc16cb4f3197547), CONST64(0x6d315ce43e89d5da),
190 CONST64(0xfb0cf704efff08eb), CONST64(0x98be266a47f2d42d), CONST64(0xdb24ff1cb7c738ab), CONST64(0x937eed2a11b9543b),
191 CONST64(0x876fe82536a24a13), CONST64(0x4ed39dba26f4699c), CONST64(0xa1ce6fb1ee107f5f), CONST64(0x028c8e8f8b8d0304),
192 CONST64(0x647d192be34f56c8), CONST64(0xba1aa0fd9447e769), CONST64(0xe717f00ddeea1ad3), CONST64(0x1e978986ba98113c),
193 CONST64(0x3c330f11692d2278), CONST64(0x1c1b070931151238), CONST64(0x8629afecfd6ac511), CONST64(0xcb30fb109bdb208b),
194 CONST64(0x2028081858383040), CONST64(0x5441153f976b7ea8), CONST64(0x34390d177f232e68), CONST64(0x1014040c2c1c1820),
195 CONST64(0x040501030b070608), CONST64(0x8de964acab214507), CONST64(0x5b84df7cca27f8b6), CONST64(0xc5b3769a0d5f2997),
196 CONST64(0xf980798b64720bef), CONST64(0x538edd7adc29f4a6), CONST64(0xf4c93d47b2b38ef5), CONST64(0x584e163a8a6274b0),
197 CONST64(0xfcc33f41a4bd82e5), CONST64(0xdceb3759fc85b2a5), CONST64(0xa9c46db7f81e734f), CONST64(0xe0d8384895a890dd),
198 CONST64(0xde67b9d67708b1a1), CONST64(0xd1a273952a4437bf), CONST64(0x836ae9263da54c1b), CONST64(0xd4e1355fea8bbeb5),
199 CONST64(0x491c55ff6db6e392), CONST64(0xd9a871933c4a3baf), CONST64(0xf18a7b8d727c07ff), CONST64(0x0a868c899d830f14),
200 CONST64(0xd5a77296214331b7), CONST64(0x1a928885b19f1734), CONST64(0xff09f607e4f80ee3), CONST64(0xa8822a7e33d6fc4d),
201 CONST64(0xf8c63e42afba84ed), CONST64(0x653b5ee22887d9ca), CONST64(0x9cbb27694cf5d225), CONST64(0x054346cac0cf890a),
202 CONST64(0x303c0c1474242860), CONST64(0x89ec65afa026430f), CONST64(0xbdd568b8df056d67), CONST64(0x99f861a38c3a5b2f),
203 CONST64(0x0c0f03051d090a18), CONST64(0x23e2c15e187dbc46), CONST64(0x411657f97bb8ef82), CONST64(0x7fa9d6679918cefe),
204 CONST64(0x439ad976f035ec86), CONST64(0x7d2558e81295cdfa), CONST64(0x479fd875fb32ea8e), CONST64(0x85e366aabd2f4917),
205 CONST64(0x7bacd764921fc8f6), CONST64(0xe8d23a4e83a69ccd), CONST64(0x07cfc8454b428a0e), CONST64(0xf0cc3c44b9b488fd),
206 CONST64(0xcf35fa1390dc2683), CONST64(0x62f496a763c553c4), CONST64(0xa601a7f4a552f551), CONST64(0x5ac298b501ef77b4),
207 CONST64(0x977bec291abe5233), CONST64(0xda62b8d57c0fb7a9), CONST64(0x3bfcc754226fa876), CONST64(0x822caeeff66dc319),
208 CONST64(0xb9d069bbd4026b6f), CONST64(0x317a4bddbfeca762), CONST64(0x963dabe0d176dd31), CONST64(0x9e37a9e6c778d121),
209 CONST64(0x81e667a9b6284f1f), CONST64(0x28220a1e4e363c50), CONST64(0x014647c9cbc88f02), CONST64(0xef1df20bc8e416c3),
210 CONST64(0xee5bb5c2032c99c1), CONST64(0x88aa22666beecc0d), CONST64(0xb356e5324981647b), CONST64(0x9f71ee2f0cb05e23),
211 CONST64(0xc27cbedf461da399), CONST64(0xac872b7d38d1fa45), CONST64(0x3ebf819ee2a0217c), CONST64(0x485a1236a67e6c90),
212 CONST64(0x36b58398f4ae2d6c), CONST64(0x6c771b2df5415ad8), CONST64(0x38360e12622a2470), CONST64(0x8caf236560e9ca05),
213 CONST64(0xf306f502f9f104fb), CONST64(0x094c45cfddc68312), CONST64(0x84a5216376e7c615), CONST64(0x1fd1ce4f71509e3e),
214 CONST64(0x397049dba9e2ab72), CONST64(0xb09c2c7409c4e87d), CONST64(0xc33af9168dd52c9b), CONST64(0xbf59e63754886e63),
215 CONST64(0xe254b6c71e2593d9), CONST64(0xa088287825d8f05d), CONST64(0x5c4b1739816572b8), CONST64(0x32b0829bffa92b64),
216 CONST64(0x68721a2efe465cd0), CONST64(0x169d8b80ac961d2c), CONST64(0xdf21fe1fbcc03ea3), CONST64(0x12988a83a7911b24),
217 CONST64(0x242d091b533f3648), CONST64(0x03cac94640458c06), CONST64(0x26a18794d8b2354c), CONST64(0x256b4ed298f7b94a),
218 CONST64(0xa342e13e659d7c5b), CONST64(0xb8962e721fcae46d), CONST64(0xb753e43142866273), CONST64(0xa747e03d6e9a7a53),
219 CONST64(0x8b60eb202bab400b), CONST64(0x7aea90ad59d747f4), CONST64(0xaa0ea4f1b85bff49), CONST64(0x78661e22d25a44f0),
220 CONST64(0x2eab8592cebc395c), CONST64(0x9dfd60a0873d5d27), CONST64(0x0000000000000000), CONST64(0x94b1256f5afbde35),
221 CONST64(0xf703f401f2f602f3), CONST64(0xe312f10ed5ed1cdb), CONST64(0x6afe94a175cb5fd4), CONST64(0x2c270b1d45313a58),
222 CONST64(0xbb5ce7345f8f686b), CONST64(0xc9bc759f1056238f), CONST64(0x9b74ef2c07b7582b), CONST64(0xd0e4345ce18cb8bd),
223 CONST64(0xc4f53153c697a695), CONST64(0x77a3d4618f16c2ee), CONST64(0x67b7d06da30adace), CONST64(0x22a48697d3b53344),
224 CONST64(0xe59b7e82556719d7), CONST64(0x8e23adeaeb64c901), CONST64(0xd32efd1aa1c934bb), CONST64(0xa48d297b2edff655),
225 CONST64(0xc0f03050cd90a09d), CONST64(0xecd73b4d88a19ac5), CONST64(0x46d99fbc30fa658c), CONST64(0xc73ff81586d22a93),
226 CONST64(0x3ff9c6572968ae7e), CONST64(0x4c5f1335ad796a98), CONST64(0x181e060a3a121430), CONST64(0x1411050f271b1e28),
227 CONST64(0x33f6c5523461a466), CONST64(0x44551133bb776688), CONST64(0xc1b6779906582f9f), CONST64(0xed917c84436915c7),
228 CONST64(0xf58f7a8e797b01f7), CONST64(0xfd8578886f750de7), CONST64(0xd8ee365af782b4ad), CONST64(0x706c1c24c45448e0),
229 CONST64(0xe4dd394b9eaf96d5), CONST64(0x792059eb1992cbf2), CONST64(0x60781828e84850c0), CONST64(0x451356fa70bfe98a),
230 CONST64(0xf645b3c8393e8df1), CONST64(0xfa4ab0cd243787e9), CONST64(0x90b4246c51fcd83d), CONST64(0x80a020607de0c01d),
231 CONST64(0xf240b2cb32398bf9), CONST64(0x72e092ab4fd94be4), CONST64(0xb615a3f8894eed71), CONST64(0x27e7c05d137aba4e),
232 CONST64(0x0d4944ccd6c1851a), CONST64(0x95f762a691335137), CONST64(0x40501030b0706080), CONST64(0xea5eb4c1082b9fc9),
233 CONST64(0x2aae8491c5bb3f54), CONST64(0x115243c5e7d49722), CONST64(0x76e593a844de4dec), CONST64(0x2fedc25b0574b65e),
234 CONST64(0x357f4adeb4eba16a), CONST64(0xce73bdda5b14a981), CONST64(0x06898f8c808a050c), CONST64(0xb4992d7702c3ee75),
235 CONST64(0xca76bcd95013af89), CONST64(0x4ad69cb92df36f94), CONST64(0xb5df6abec90b6177), CONST64(0x1d5d40c0fadd9d3a),
236 CONST64(0x1bd4cf4c7a579836), CONST64(0xb210a2fb8249eb79), CONST64(0x3aba809de9a72774), CONST64(0x216e4fd193f0bf42),
237 CONST64(0x7c631f21d95d42f8), CONST64(0x0fc5ca435d4c861e), CONST64(0x9238aae3da71db39), CONST64(0x155742c6ecd3912a),
238 };
239
240 static const ulong64 T3[256] = {
241 CONST64(0x68d2d3ba016ab9bb), CONST64(0x194dfc54b1669ae5), CONST64(0x93bc712fcd1465e2), CONST64(0xb9cd9c74511b8725),
242 CONST64(0x0251f553a457a2f7), CONST64(0xb86b68d303bed6d0), CONST64(0xbd6f6bd204b5ded6), CONST64(0x6429d74dfe8552b3),
243 CONST64(0x0d5df050ad4abafd), CONST64(0x268ae9ac63e009cf), CONST64(0x830e8a8d84961c09), CONST64(0x79c6dcbf1a4d91a5),
244 CONST64(0xaddd90704d37a73d), CONST64(0x0755f652a35caaf1), CONST64(0xc852b39ae117a47b), CONST64(0x612dd44cf98e5ab5),
245 CONST64(0x658f23eaac200346), CONST64(0xa67362d51184e6c4), CONST64(0xf166a497c268cc55), CONST64(0xb2636ed10da8c6dc),
246 CONST64(0xffcc553399d085aa), CONST64(0x0859f351aa41b2fb), CONST64(0x2a71ed5b9c0fe2c7), CONST64(0x04a2f7a655ae59f3),
247 CONST64(0x815f7fde20c1befe), CONST64(0x753dd848e5a27aad), CONST64(0x329ae5a87fcc29d7), CONST64(0xc75eb699e80abc71),
248 CONST64(0x904b70db3be696e0), CONST64(0xfac856329edb8dac), CONST64(0x51e6c4b72215d195), CONST64(0x2bd719fcceaab332),
249 CONST64(0x48ab38e393734b70), CONST64(0xdc42bf9efd3b8463), CONST64(0xef7eae91d052fc41), CONST64(0xcd56b09be61cac7d),
250 CONST64(0x4daf3be294784376), CONST64(0x6dd6d0bb0661b1bd), CONST64(0x5819c341daf1329b), CONST64(0xcba5b26e17e55779),
251 CONST64(0x0baef2a55cb341f9), CONST64(0xc00b40cb4b561680), CONST64(0xdab1bd6b0cc27f67), CONST64(0xfb6ea295cc7edc59),
252 CONST64(0x1fbefea1409f61e1), CONST64(0x18eb08f3e3c3cb10), CONST64(0x4ffeceb1302fe181), CONST64(0x0a0806020e16100c),
253 CONST64(0xdb1749cc5e672e92), CONST64(0xf33751c4663f6ea2), CONST64(0x6974271d53cfe84e), CONST64(0x44503c146c9ca078),
254 CONST64(0xe82b58c3730e56b0), CONST64(0xf291a563349a3f57), CONST64(0x954f73da3ced9ee6), CONST64(0x3469e75d8e35d2d3),
255 CONST64(0x3e61e15f8023c2df), CONST64(0x8b5779dc2ed7aef2), CONST64(0x94e9877d6e48cf13), CONST64(0xde134acd596c2694),
256 CONST64(0x9ee1817f605edf1f), CONST64(0x2f75ee5a9b04eac1), CONST64(0xc1adb46c19f34775), CONST64(0x316de45c893edad5),
257 CONST64(0x0cfb04f7ffefeb08), CONST64(0xbe986a26f2472dd4), CONST64(0x24db1cffc7b7ab38), CONST64(0x7e932aedb9113b54),
258 CONST64(0x6f8725e8a236134a), CONST64(0xd34eba9df4269c69), CONST64(0xcea1b16f10ee5f7f), CONST64(0x8c028f8e8d8b0403),
259 CONST64(0x7d642b194fe3c856), CONST64(0x1abafda0479469e7), CONST64(0x17e70df0eaded31a), CONST64(0x971e868998ba3c11),
260 CONST64(0x333c110f2d697822), CONST64(0x1b1c090715313812), CONST64(0x2986ecaf6afd11c5), CONST64(0x30cb10fbdb9b8b20),
261 CONST64(0x2820180838584030), CONST64(0x41543f156b97a87e), CONST64(0x3934170d237f682e), CONST64(0x14100c041c2c2018),
262 CONST64(0x05040301070b0806), CONST64(0xe98dac6421ab0745), CONST64(0x845b7cdf27cab6f8), CONST64(0xb3c59a765f0d9729),
263 CONST64(0x80f98b797264ef0b), CONST64(0x8e537add29dca6f4), CONST64(0xc9f4473db3b2f58e), CONST64(0x4e583a16628ab074),
264 CONST64(0xc3fc413fbda4e582), CONST64(0xebdc593785fca5b2), CONST64(0xc4a9b76d1ef84f73), CONST64(0xd8e04838a895dd90),
265 CONST64(0x67ded6b90877a1b1), CONST64(0xa2d19573442abf37), CONST64(0x6a8326e9a53d1b4c), CONST64(0xe1d45f358beab5be),
266 CONST64(0x1c49ff55b66d92e3), CONST64(0xa8d993714a3caf3b), CONST64(0x8af18d7b7c72ff07), CONST64(0x860a898c839d140f),
267 CONST64(0xa7d596724321b731), CONST64(0x921a85889fb13417), CONST64(0x09ff07f6f8e4e30e), CONST64(0x82a87e2ad6334dfc),
268 CONST64(0xc6f8423ebaafed84), CONST64(0x3b65e25e8728cad9), CONST64(0xbb9c6927f54c25d2), CONST64(0x4305ca46cfc00a89),
269 CONST64(0x3c30140c24746028), CONST64(0xec89af6526a00f43), CONST64(0xd5bdb86805df676d), CONST64(0xf899a3613a8c2f5b),
270 CONST64(0x0f0c0503091d180a), CONST64(0xe2235ec17d1846bc), CONST64(0x1641f957b87b82ef), CONST64(0xa97f67d61899fece),
271 CONST64(0x9a4376d935f086ec), CONST64(0x257de8589512facd), CONST64(0x9f4775d832fb8eea), CONST64(0xe385aa662fbd1749),
272 CONST64(0xac7b64d71f92f6c8), CONST64(0xd2e84e3aa683cd9c), CONST64(0xcf0745c8424b0e8a), CONST64(0xccf0443cb4b9fd88),
273 CONST64(0x35cf13fadc908326), CONST64(0xf462a796c563c453), CONST64(0x01a6f4a752a551f5), CONST64(0xc25ab598ef01b477),
274 CONST64(0x7b9729ecbe1a3352), CONST64(0x62dad5b80f7ca9b7), CONST64(0xfc3b54c76f2276a8), CONST64(0x2c82efae6df619c3),
275 CONST64(0xd0b9bb6902d46f6b), CONST64(0x7a31dd4becbf62a7), CONST64(0x3d96e0ab76d131dd), CONST64(0x379ee6a978c721d1),
276 CONST64(0xe681a96728b61f4f), CONST64(0x22281e0a364e503c), CONST64(0x4601c947c8cb028f), CONST64(0x1def0bf2e4c8c316),
277 CONST64(0x5beec2b52c03c199), CONST64(0xaa886622ee6b0dcc), CONST64(0x56b332e581497b64), CONST64(0x719f2feeb00c235e),
278 CONST64(0x7cc2dfbe1d4699a3), CONST64(0x87ac7d2bd13845fa), CONST64(0xbf3e9e81a0e27c21), CONST64(0x5a4836127ea6906c),
279 CONST64(0xb5369883aef46c2d), CONST64(0x776c2d1b41f5d85a), CONST64(0x3638120e2a627024), CONST64(0xaf8c6523e96005ca),
280 CONST64(0x06f302f5f1f9fb04), CONST64(0x4c09cf45c6dd1283), CONST64(0xa5846321e77615c6), CONST64(0xd11f4fce50713e9e),
281 CONST64(0x7039db49e2a972ab), CONST64(0x9cb0742cc4097de8), CONST64(0x3ac316f9d58d9b2c), CONST64(0x59bf37e68854636e),
282 CONST64(0x54e2c7b6251ed993), CONST64(0x88a07828d8255df0), CONST64(0x4b5c39176581b872), CONST64(0xb0329b82a9ff642b),
283 CONST64(0x72682e1a46fed05c), CONST64(0x9d16808b96ac2c1d), CONST64(0x21df1ffec0bca33e), CONST64(0x9812838a91a7241b),
284 CONST64(0x2d241b093f534836), CONST64(0xca0346c94540068c), CONST64(0xa1269487b2d84c35), CONST64(0x6b25d24ef7984ab9),
285 CONST64(0x42a33ee19d655b7c), CONST64(0x96b8722eca1f6de4), CONST64(0x53b731e486427362), CONST64(0x47a73de09a6e537a),
286 CONST64(0x608b20ebab2b0b40), CONST64(0xea7aad90d759f447), CONST64(0x0eaaf1a45bb849ff), CONST64(0x6678221e5ad2f044),
287 CONST64(0xab2e9285bcce5c39), CONST64(0xfd9da0603d87275d), CONST64(0x0000000000000000), CONST64(0xb1946f25fb5a35de),
288 CONST64(0x03f701f4f6f2f302), CONST64(0x12e30ef1edd5db1c), CONST64(0xfe6aa194cb75d45f), CONST64(0x272c1d0b3145583a),
289 CONST64(0x5cbb34e78f5f6b68), CONST64(0xbcc99f7556108f23), CONST64(0x749b2cefb7072b58), CONST64(0xe4d05c348ce1bdb8),
290 CONST64(0xf5c4533197c695a6), CONST64(0xa37761d4168feec2), CONST64(0xb7676dd00aa3ceda), CONST64(0xa4229786b5d34433),
291 CONST64(0x9be5827e6755d719), CONST64(0x238eeaad64eb01c9), CONST64(0x2ed31afdc9a1bb34), CONST64(0x8da47b29df2e55f6),
292 CONST64(0xf0c0503090cd9da0), CONST64(0xd7ec4d3ba188c59a), CONST64(0xd946bc9ffa308c65), CONST64(0x3fc715f8d286932a),
293 CONST64(0xf93f57c668297eae), CONST64(0x5f4c351379ad986a), CONST64(0x1e180a06123a3014), CONST64(0x11140f051b27281e),
294 CONST64(0xf63352c5613466a4), CONST64(0x5544331177bb8866), CONST64(0xb6c1997758069f2f), CONST64(0x91ed847c6943c715),
295 CONST64(0x8ff58e7a7b79f701), CONST64(0x85fd8878756fe70d), CONST64(0xeed85a3682f7adb4), CONST64(0x6c70241c54c4e048),
296 CONST64(0xdde44b39af9ed596), CONST64(0x2079eb599219f2cb), CONST64(0x7860281848e8c050), CONST64(0x1345fa56bf708ae9),
297 CONST64(0x45f6c8b33e39f18d), CONST64(0x4afacdb03724e987), CONST64(0xb4906c24fc513dd8), CONST64(0xa0806020e07d1dc0),
298 CONST64(0x40f2cbb23932f98b), CONST64(0xe072ab92d94fe44b), CONST64(0x15b6f8a34e8971ed), CONST64(0xe7275dc07a134eba),
299 CONST64(0x490dcc44c1d61a85), CONST64(0xf795a66233913751), CONST64(0x5040301070b08060), CONST64(0x5eeac1b42b08c99f),
300 CONST64(0xae2a9184bbc5543f), CONST64(0x5211c543d4e72297), CONST64(0xe576a893de44ec4d), CONST64(0xed2f5bc274055eb6),
301 CONST64(0x7f35de4aebb46aa1), CONST64(0x73cedabd145b81a9), CONST64(0x89068c8f8a800c05), CONST64(0x99b4772dc30275ee),
302 CONST64(0x76cad9bc135089af), CONST64(0xd64ab99cf32d946f), CONST64(0xdfb5be6a0bc97761), CONST64(0x5d1dc040ddfa3a9d),
303 CONST64(0xd41b4ccf577a3698), CONST64(0x10b2fba2498279eb), CONST64(0xba3a9d80a7e97427), CONST64(0x6e21d14ff09342bf),
304 CONST64(0x637c211f5dd9f842), CONST64(0xc50f43ca4c5d1e86), CONST64(0x3892e3aa71da39db), CONST64(0x5715c642d3ec2a91),
305 };
306
307 static const ulong64 T4[256] = {
308 CONST64(0xbbb96a01bad3d268), CONST64(0xe59a66b154fc4d19), CONST64(0xe26514cd2f71bc93), CONST64(0x25871b51749ccdb9),
309 CONST64(0xf7a257a453f55102), CONST64(0xd0d6be03d3686bb8), CONST64(0xd6deb504d26b6fbd), CONST64(0xb35285fe4dd72964),
310 CONST64(0xfdba4aad50f05d0d), CONST64(0xcf09e063ace98a26), CONST64(0x091c96848d8a0e83), CONST64(0xa5914d1abfdcc679),
311 CONST64(0x3da7374d7090ddad), CONST64(0xf1aa5ca352f65507), CONST64(0x7ba417e19ab352c8), CONST64(0xb55a8ef94cd42d61),
312 CONST64(0x460320acea238f65), CONST64(0xc4e68411d56273a6), CONST64(0x55cc68c297a466f1), CONST64(0xdcc6a80dd16e63b2),
313 CONST64(0xaa85d0993355ccff), CONST64(0xfbb241aa51f35908), CONST64(0xc7e20f9c5bed712a), CONST64(0xf359ae55a6f7a204),
314 CONST64(0xfebec120de7f5f81), CONST64(0xad7aa2e548d83d75), CONST64(0xd729cc7fa8e59a32), CONST64(0x71bc0ae899b65ec7),
315 CONST64(0xe096e63bdb704b90), CONST64(0xac8ddb9e3256c8fa), CONST64(0x95d11522b7c4e651), CONST64(0x32b3aacefc19d72b),
316 CONST64(0x704b7393e338ab48), CONST64(0x63843bfd9ebf42dc), CONST64(0x41fc52d091ae7eef), CONST64(0x7dac1ce69bb056cd),
317 CONST64(0x76437894e23baf4d), CONST64(0xbdb16106bbd0d66d), CONST64(0x9b32f1da41c31958), CONST64(0x7957e5176eb2a5cb),
318 CONST64(0xf941b35ca5f2ae0b), CONST64(0x8016564bcb400bc0), CONST64(0x677fc20c6bbdb1da), CONST64(0x59dc7ecc95a26efb),
319 CONST64(0xe1619f40a1febe1f), CONST64(0x10cbc3e3f308eb18), CONST64(0x81e12f30b1cefe4f), CONST64(0x0c10160e0206080a),
320 CONST64(0x922e675ecc4917db), CONST64(0xa26e3f66c45137f3), CONST64(0x4ee8cf531d277469), CONST64(0x78a09c6c143c5044),
321 CONST64(0xb0560e73c3582be8), CONST64(0x573f9a3463a591f2), CONST64(0xe69eed3cda734f95), CONST64(0xd3d2358e5de76934),
322 CONST64(0xdfc223805fe1613e), CONST64(0xf2aed72edc79578b), CONST64(0x13cf486e7d87e994), CONST64(0x94266c59cd4a13de),
323 CONST64(0x1fdf5e607f81e19e), CONST64(0xc1ea049b5aee752f), CONST64(0x7547f3196cb4adc1), CONST64(0xd5da3e895ce46d31),
324 CONST64(0x08ebeffff704fb0c), CONST64(0xd42d47f2266a98be), CONST64(0x38abb7c7ff1cdb24), CONST64(0x543b11b9ed2a937e),
325 CONST64(0x4a1336a2e825876f), CONST64(0x699c26f49dba4ed3), CONST64(0x7f5fee106fb1a1ce), CONST64(0x03048b8d8e8f028c),
326 CONST64(0x56c8e34f192b647d), CONST64(0xe7699447a0fdba1a), CONST64(0x1ad3deeaf00de717), CONST64(0x113cba9889861e97),
327 CONST64(0x2278692d0f113c33), CONST64(0x1238311507091c1b), CONST64(0xc511fd6aafec8629), CONST64(0x208b9bdbfb10cb30),
328 CONST64(0x3040583808182028), CONST64(0x7ea8976b153f5441), CONST64(0x2e687f230d173439), CONST64(0x18202c1c040c1014),
329 CONST64(0x06080b0701030405), CONST64(0x4507ab2164ac8de9), CONST64(0xf8b6ca27df7c5b84), CONST64(0x29970d5f769ac5b3),
330 CONST64(0x0bef6472798bf980), CONST64(0xf4a6dc29dd7a538e), CONST64(0x8ef5b2b33d47f4c9), CONST64(0x74b08a62163a584e),
331 CONST64(0x82e5a4bd3f41fcc3), CONST64(0xb2a5fc853759dceb), CONST64(0x734ff81e6db7a9c4), CONST64(0x90dd95a83848e0d8),
332 CONST64(0xb1a17708b9d6de67), CONST64(0x37bf2a447395d1a2), CONST64(0x4c1b3da5e926836a), CONST64(0xbeb5ea8b355fd4e1),
333 CONST64(0xe3926db655ff491c), CONST64(0x3baf3c4a7193d9a8), CONST64(0x07ff727c7b8df18a), CONST64(0x0f149d838c890a86),
334 CONST64(0x31b721437296d5a7), CONST64(0x1734b19f88851a92), CONST64(0x0ee3e4f8f607ff09), CONST64(0xfc4d33d62a7ea882),
335 CONST64(0x84edafba3e42f8c6), CONST64(0xd9ca28875ee2653b), CONST64(0xd2254cf527699cbb), CONST64(0x890ac0cf46ca0543),
336 CONST64(0x286074240c14303c), CONST64(0x430fa02665af89ec), CONST64(0x6d67df0568b8bdd5), CONST64(0x5b2f8c3a61a399f8),
337 CONST64(0x0a181d0903050c0f), CONST64(0xbc46187dc15e23e2), CONST64(0xef827bb857f94116), CONST64(0xcefe9918d6677fa9),
338 CONST64(0xec86f035d976439a), CONST64(0xcdfa129558e87d25), CONST64(0xea8efb32d875479f), CONST64(0x4917bd2f66aa85e3),
339 CONST64(0xc8f6921fd7647bac), CONST64(0x9ccd83a63a4ee8d2), CONST64(0x8a0e4b42c84507cf), CONST64(0x88fdb9b43c44f0cc),
340 CONST64(0x268390dcfa13cf35), CONST64(0x53c463c596a762f4), CONST64(0xf551a552a7f4a601), CONST64(0x77b401ef98b55ac2),
341 CONST64(0x52331abeec29977b), CONST64(0xb7a97c0fb8d5da62), CONST64(0xa876226fc7543bfc), CONST64(0xc319f66daeef822c),
342 CONST64(0x6b6fd40269bbb9d0), CONST64(0xa762bfec4bdd317a), CONST64(0xdd31d176abe0963d), CONST64(0xd121c778a9e69e37),
343 CONST64(0x4f1fb62867a981e6), CONST64(0x3c504e360a1e2822), CONST64(0x8f02cbc847c90146), CONST64(0x16c3c8e4f20bef1d),
344 CONST64(0x99c1032cb5c2ee5b), CONST64(0xcc0d6bee226688aa), CONST64(0x647b4981e532b356), CONST64(0x5e230cb0ee2f9f71),
345 CONST64(0xa399461dbedfc27c), CONST64(0xfa4538d12b7dac87), CONST64(0x217ce2a0819e3ebf), CONST64(0x6c90a67e1236485a),
346 CONST64(0x2d6cf4ae839836b5), CONST64(0x5ad8f5411b2d6c77), CONST64(0x2470622a0e123836), CONST64(0xca0560e923658caf),
347 CONST64(0x04fbf9f1f502f306), CONST64(0x8312ddc645cf094c), CONST64(0xc61576e7216384a5), CONST64(0x9e3e7150ce4f1fd1),
348 CONST64(0xab72a9e249db3970), CONST64(0xe87d09c42c74b09c), CONST64(0x2c9b8dd5f916c33a), CONST64(0x6e635488e637bf59),
349 CONST64(0x93d91e25b6c7e254), CONST64(0xf05d25d82878a088), CONST64(0x72b8816517395c4b), CONST64(0x2b64ffa9829b32b0),
350 CONST64(0x5cd0fe461a2e6872), CONST64(0x1d2cac968b80169d), CONST64(0x3ea3bcc0fe1fdf21), CONST64(0x1b24a7918a831298),
351 CONST64(0x3648533f091b242d), CONST64(0x8c064045c94603ca), CONST64(0x354cd8b2879426a1), CONST64(0xb94a98f74ed2256b),
352 CONST64(0x7c5b659de13ea342), CONST64(0xe46d1fca2e72b896), CONST64(0x62734286e431b753), CONST64(0x7a536e9ae03da747),
353 CONST64(0x400b2babeb208b60), CONST64(0x47f459d790ad7aea), CONST64(0xff49b85ba4f1aa0e), CONST64(0x44f0d25a1e227866),
354 CONST64(0x395ccebc85922eab), CONST64(0x5d27873d60a09dfd), CONST64(0x0000000000000000), CONST64(0xde355afb256f94b1),
355 CONST64(0x02f3f2f6f401f703), CONST64(0x1cdbd5edf10ee312), CONST64(0x5fd475cb94a16afe), CONST64(0x3a5845310b1d2c27),
356 CONST64(0x686b5f8fe734bb5c), CONST64(0x238f1056759fc9bc), CONST64(0x582b07b7ef2c9b74), CONST64(0xb8bde18c345cd0e4),
357 CONST64(0xa695c6973153c4f5), CONST64(0xc2ee8f16d46177a3), CONST64(0xdacea30ad06d67b7), CONST64(0x3344d3b5869722a4),
358 CONST64(0x19d755677e82e59b), CONST64(0xc901eb64adea8e23), CONST64(0x34bba1c9fd1ad32e), CONST64(0xf6552edf297ba48d),
359 CONST64(0xa09dcd903050c0f0), CONST64(0x9ac588a13b4decd7), CONST64(0x658c30fa9fbc46d9), CONST64(0x2a9386d2f815c73f),
360 CONST64(0xae7e2968c6573ff9), CONST64(0x6a98ad7913354c5f), CONST64(0x14303a12060a181e), CONST64(0x1e28271b050f1411),
361 CONST64(0xa4663461c55233f6), CONST64(0x6688bb7711334455), CONST64(0x2f9f06587799c1b6), CONST64(0x15c743697c84ed91),
362 CONST64(0x01f7797b7a8ef58f), CONST64(0x0de76f757888fd85), CONST64(0xb4adf782365ad8ee), CONST64(0x48e0c4541c24706c),
363 CONST64(0x96d59eaf394be4dd), CONST64(0xcbf2199259eb7920), CONST64(0x50c0e84818286078), CONST64(0xe98a70bf56fa4513),
364 CONST64(0x8df1393eb3c8f645), CONST64(0x87e92437b0cdfa4a), CONST64(0xd83d51fc246c90b4), CONST64(0xc01d7de0206080a0),
365 CONST64(0x8bf93239b2cbf240), CONST64(0x4be44fd992ab72e0), CONST64(0xed71894ea3f8b615), CONST64(0xba4e137ac05d27e7),
366 CONST64(0x851ad6c144cc0d49), CONST64(0x5137913362a695f7), CONST64(0x6080b07010304050), CONST64(0x9fc9082bb4c1ea5e),
367 CONST64(0x3f54c5bb84912aae), CONST64(0x9722e7d443c51152), CONST64(0x4dec44de93a876e5), CONST64(0xb65e0574c25b2fed),
368 CONST64(0xa16ab4eb4ade357f), CONST64(0xa9815b14bddace73), CONST64(0x050c808a8f8c0689), CONST64(0xee7502c32d77b499),
369 CONST64(0xaf895013bcd9ca76), CONST64(0x6f942df39cb94ad6), CONST64(0x6177c90b6abeb5df), CONST64(0x9d3afadd40c01d5d),
370 CONST64(0x98367a57cf4c1bd4), CONST64(0xeb798249a2fbb210), CONST64(0x2774e9a7809d3aba), CONST64(0xbf4293f04fd1216e),
371 CONST64(0x42f8d95d1f217c63), CONST64(0x861e5d4cca430fc5), CONST64(0xdb39da71aae39238), CONST64(0x912aecd342c61557),
372 };
373
374 static const ulong64 T5[256] = {
375 CONST64(0xb9bb016ad3ba68d2), CONST64(0x9ae5b166fc54194d), CONST64(0x65e2cd14712f93bc), CONST64(0x8725511b9c74b9cd),
376 CONST64(0xa2f7a457f5530251), CONST64(0xd6d003be68d3b86b), CONST64(0xded604b56bd2bd6f), CONST64(0x52b3fe85d74d6429),
377 CONST64(0xbafdad4af0500d5d), CONST64(0x09cf63e0e9ac268a), CONST64(0x1c0984968a8d830e), CONST64(0x91a51a4ddcbf79c6),
378 CONST64(0xa73d4d379070addd), CONST64(0xaaf1a35cf6520755), CONST64(0xa47be117b39ac852), CONST64(0x5ab5f98ed44c612d),
379 CONST64(0x0346ac2023ea658f), CONST64(0xe6c4118462d5a673), CONST64(0xcc55c268a497f166), CONST64(0xc6dc0da86ed1b263),
380 CONST64(0x85aa99d05533ffcc), CONST64(0xb2fbaa41f3510859), CONST64(0xe2c79c0fed5b2a71), CONST64(0x59f355aef7a604a2),
381 CONST64(0xbefe20c17fde815f), CONST64(0x7aade5a2d848753d), CONST64(0x29d77fcce5a8329a), CONST64(0xbc71e80ab699c75e),
382 CONST64(0x96e03be670db904b), CONST64(0x8dac9edb5632fac8), CONST64(0xd1952215c4b751e6), CONST64(0xb332ceaa19fc2bd7),
383 CONST64(0x4b70937338e348ab), CONST64(0x8463fd3bbf9edc42), CONST64(0xfc41d052ae91ef7e), CONST64(0xac7de61cb09bcd56),
384 CONST64(0x437694783be24daf), CONST64(0xb1bd0661d0bb6dd6), CONST64(0x329bdaf1c3415819), CONST64(0x577917e5b26ecba5),
385 CONST64(0x41f95cb3f2a50bae), CONST64(0x16804b5640cbc00b), CONST64(0x7f670cc2bd6bdab1), CONST64(0xdc59cc7ea295fb6e),
386 CONST64(0x61e1409ffea11fbe), CONST64(0xcb10e3c308f318eb), CONST64(0xe181302fceb14ffe), CONST64(0x100c0e1606020a08),
387 CONST64(0x2e925e6749ccdb17), CONST64(0x6ea2663f51c4f337), CONST64(0xe84e53cf271d6974), CONST64(0xa0786c9c3c144450),
388 CONST64(0x56b0730e58c3e82b), CONST64(0x3f57349aa563f291), CONST64(0x9ee63ced73da954f), CONST64(0xd2d38e35e75d3469),
389 CONST64(0xc2df8023e15f3e61), CONST64(0xaef22ed779dc8b57), CONST64(0xcf136e48877d94e9), CONST64(0x2694596c4acdde13),
390 CONST64(0xdf1f605e817f9ee1), CONST64(0xeac19b04ee5a2f75), CONST64(0x477519f3b46cc1ad), CONST64(0xdad5893ee45c316d),
391 CONST64(0xeb08ffef04f70cfb), CONST64(0x2dd4f2476a26be98), CONST64(0xab38c7b71cff24db), CONST64(0x3b54b9112aed7e93),
392 CONST64(0x134aa23625e86f87), CONST64(0x9c69f426ba9dd34e), CONST64(0x5f7f10eeb16fcea1), CONST64(0x04038d8b8f8e8c02),
393 CONST64(0xc8564fe32b197d64), CONST64(0x69e74794fda01aba), CONST64(0xd31aeade0df017e7), CONST64(0x3c1198ba8689971e),
394 CONST64(0x78222d69110f333c), CONST64(0x3812153109071b1c), CONST64(0x11c56afdecaf2986), CONST64(0x8b20db9b10fb30cb),
395 CONST64(0x4030385818082820), CONST64(0xa87e6b973f154154), CONST64(0x682e237f170d3934), CONST64(0x20181c2c0c041410),
396 CONST64(0x0806070b03010504), CONST64(0x074521abac64e98d), CONST64(0xb6f827ca7cdf845b), CONST64(0x97295f0d9a76b3c5),
397 CONST64(0xef0b72648b7980f9), CONST64(0xa6f429dc7add8e53), CONST64(0xf58eb3b2473dc9f4), CONST64(0xb074628a3a164e58),
398 CONST64(0xe582bda4413fc3fc), CONST64(0xa5b285fc5937ebdc), CONST64(0x4f731ef8b76dc4a9), CONST64(0xdd90a8954838d8e0),
399 CONST64(0xa1b10877d6b967de), CONST64(0xbf37442a9573a2d1), CONST64(0x1b4ca53d26e96a83), CONST64(0xb5be8bea5f35e1d4),
400 CONST64(0x92e3b66dff551c49), CONST64(0xaf3b4a3c9371a8d9), CONST64(0xff077c728d7b8af1), CONST64(0x140f839d898c860a),
401 CONST64(0xb73143219672a7d5), CONST64(0x34179fb18588921a), CONST64(0xe30ef8e407f609ff), CONST64(0x4dfcd6337e2a82a8),
402 CONST64(0xed84baaf423ec6f8), CONST64(0xcad98728e25e3b65), CONST64(0x25d2f54c6927bb9c), CONST64(0x0a89cfc0ca464305),
403 CONST64(0x60282474140c3c30), CONST64(0x0f4326a0af65ec89), CONST64(0x676d05dfb868d5bd), CONST64(0x2f5b3a8ca361f899),
404 CONST64(0x180a091d05030f0c), CONST64(0x46bc7d185ec1e223), CONST64(0x82efb87bf9571641), CONST64(0xfece189967d6a97f),
405 CONST64(0x86ec35f076d99a43), CONST64(0xfacd9512e858257d), CONST64(0x8eea32fb75d89f47), CONST64(0x17492fbdaa66e385),
406 CONST64(0xf6c81f9264d7ac7b), CONST64(0xcd9ca6834e3ad2e8), CONST64(0x0e8a424b45c8cf07), CONST64(0xfd88b4b9443cccf0),
407 CONST64(0x8326dc9013fa35cf), CONST64(0xc453c563a796f462), CONST64(0x51f552a5f4a701a6), CONST64(0xb477ef01b598c25a),
408 CONST64(0x3352be1a29ec7b97), CONST64(0xa9b70f7cd5b862da), CONST64(0x76a86f2254c7fc3b), CONST64(0x19c36df6efae2c82),
409 CONST64(0x6f6b02d4bb69d0b9), CONST64(0x62a7ecbfdd4b7a31), CONST64(0x31dd76d1e0ab3d96), CONST64(0x21d178c7e6a9379e),
410 CONST64(0x1f4f28b6a967e681), CONST64(0x503c364e1e0a2228), CONST64(0x028fc8cbc9474601), CONST64(0xc316e4c80bf21def),
411 CONST64(0xc1992c03c2b55bee), CONST64(0x0dccee6b6622aa88), CONST64(0x7b64814932e556b3), CONST64(0x235eb00c2fee719f),
412 CONST64(0x99a31d46dfbe7cc2), CONST64(0x45fad1387d2b87ac), CONST64(0x7c21a0e29e81bf3e), CONST64(0x906c7ea636125a48),
413 CONST64(0x6c2daef49883b536), CONST64(0xd85a41f52d1b776c), CONST64(0x70242a62120e3638), CONST64(0x05cae9606523af8c),
414 CONST64(0xfb04f1f902f506f3), CONST64(0x1283c6ddcf454c09), CONST64(0x15c6e7766321a584), CONST64(0x3e9e50714fced11f),
415 CONST64(0x72abe2a9db497039), CONST64(0x7de8c409742c9cb0), CONST64(0x9b2cd58d16f93ac3), CONST64(0x636e885437e659bf),
416 CONST64(0xd993251ec7b654e2), CONST64(0x5df0d825782888a0), CONST64(0xb872658139174b5c), CONST64(0x642ba9ff9b82b032),
417 CONST64(0xd05c46fe2e1a7268), CONST64(0x2c1d96ac808b9d16), CONST64(0xa33ec0bc1ffe21df), CONST64(0x241b91a7838a9812),
418 CONST64(0x48363f531b092d24), CONST64(0x068c454046c9ca03), CONST64(0x4c35b2d89487a126), CONST64(0x4ab9f798d24e6b25),
419 CONST64(0x5b7c9d653ee142a3), CONST64(0x6de4ca1f722e96b8), CONST64(0x7362864231e453b7), CONST64(0x537a9a6e3de047a7),
420 CONST64(0x0b40ab2b20eb608b), CONST64(0xf447d759ad90ea7a), CONST64(0x49ff5bb8f1a40eaa), CONST64(0xf0445ad2221e6678),
421 CONST64(0x5c39bcce9285ab2e), CONST64(0x275d3d87a060fd9d), CONST64(0x0000000000000000), CONST64(0x35defb5a6f25b194),
422 CONST64(0xf302f6f201f403f7), CONST64(0xdb1cedd50ef112e3), CONST64(0xd45fcb75a194fe6a), CONST64(0x583a31451d0b272c),
423 CONST64(0x6b688f5f34e75cbb), CONST64(0x8f2356109f75bcc9), CONST64(0x2b58b7072cef749b), CONST64(0xbdb88ce15c34e4d0),
424 CONST64(0x95a697c65331f5c4), CONST64(0xeec2168f61d4a377), CONST64(0xceda0aa36dd0b767), CONST64(0x4433b5d39786a422),
425 CONST64(0xd7196755827e9be5), CONST64(0x01c964ebeaad238e), CONST64(0xbb34c9a11afd2ed3), CONST64(0x55f6df2e7b298da4),
426 CONST64(0x9da090cd5030f0c0), CONST64(0xc59aa1884d3bd7ec), CONST64(0x8c65fa30bc9fd946), CONST64(0x932ad28615f83fc7),
427 CONST64(0x7eae682957c6f93f), CONST64(0x986a79ad35135f4c), CONST64(0x3014123a0a061e18), CONST64(0x281e1b270f051114),
428 CONST64(0x66a4613452c5f633), CONST64(0x886677bb33115544), CONST64(0x9f2f58069977b6c1), CONST64(0xc7156943847c91ed),
429 CONST64(0xf7017b798e7a8ff5), CONST64(0xe70d756f887885fd), CONST64(0xadb482f75a36eed8), CONST64(0xe04854c4241c6c70),
430 CONST64(0xd596af9e4b39dde4), CONST64(0xf2cb9219eb592079), CONST64(0xc05048e828187860), CONST64(0x8ae9bf70fa561345),
431 CONST64(0xf18d3e39c8b345f6), CONST64(0xe9873724cdb04afa), CONST64(0x3dd8fc516c24b490), CONST64(0x1dc0e07d6020a080),
432 CONST64(0xf98b3932cbb240f2), CONST64(0xe44bd94fab92e072), CONST64(0x71ed4e89f8a315b6), CONST64(0x4eba7a135dc0e727),
433 CONST64(0x1a85c1d6cc44490d), CONST64(0x37513391a662f795), CONST64(0x806070b030105040), CONST64(0xc99f2b08c1b45eea),
434 CONST64(0x543fbbc59184ae2a), CONST64(0x2297d4e7c5435211), CONST64(0xec4dde44a893e576), CONST64(0x5eb674055bc2ed2f),
435 CONST64(0x6aa1ebb4de4a7f35), CONST64(0x81a9145bdabd73ce), CONST64(0x0c058a808c8f8906), CONST64(0x75eec302772d99b4),
436 CONST64(0x89af1350d9bc76ca), CONST64(0x946ff32db99cd64a), CONST64(0x77610bc9be6adfb5), CONST64(0x3a9dddfac0405d1d),
437 CONST64(0x3698577a4ccfd41b), CONST64(0x79eb4982fba210b2), CONST64(0x7427a7e99d80ba3a), CONST64(0x42bff093d14f6e21),
438 CONST64(0xf8425dd9211f637c), CONST64(0x1e864c5d43cac50f), CONST64(0x39db71dae3aa3892), CONST64(0x2a91d3ecc6425715),
439 };
440
441 static const ulong64 T6[256] = {
442 CONST64(0x6a01bbb9d268bad3), CONST64(0x66b1e59a4d1954fc), CONST64(0x14cde265bc932f71), CONST64(0x1b512587cdb9749c),
443 CONST64(0x57a4f7a2510253f5), CONST64(0xbe03d0d66bb8d368), CONST64(0xb504d6de6fbdd26b), CONST64(0x85feb35229644dd7),
444 CONST64(0x4aadfdba5d0d50f0), CONST64(0xe063cf098a26ace9), CONST64(0x9684091c0e838d8a), CONST64(0x4d1aa591c679bfdc),
445 CONST64(0x374d3da7ddad7090), CONST64(0x5ca3f1aa550752f6), CONST64(0x17e17ba452c89ab3), CONST64(0x8ef9b55a2d614cd4),
446 CONST64(0x20ac46038f65ea23), CONST64(0x8411c4e673a6d562), CONST64(0x68c255cc66f197a4), CONST64(0xa80ddcc663b2d16e),
447 CONST64(0xd099aa85ccff3355), CONST64(0x41aafbb2590851f3), CONST64(0x0f9cc7e2712a5bed), CONST64(0xae55f359a204a6f7),
448 CONST64(0xc120febe5f81de7f), CONST64(0xa2e5ad7a3d7548d8), CONST64(0xcc7fd7299a32a8e5), CONST64(0x0ae871bc5ec799b6),
449 CONST64(0xe63be0964b90db70), CONST64(0xdb9eac8dc8fa3256), CONST64(0x152295d1e651b7c4), CONST64(0xaace32b3d72bfc19),
450 CONST64(0x7393704bab48e338), CONST64(0x3bfd638442dc9ebf), CONST64(0x52d041fc7eef91ae), CONST64(0x1ce67dac56cd9bb0),
451 CONST64(0x78947643af4de23b), CONST64(0x6106bdb1d66dbbd0), CONST64(0xf1da9b32195841c3), CONST64(0xe5177957a5cb6eb2),
452 CONST64(0xb35cf941ae0ba5f2), CONST64(0x564b80160bc0cb40), CONST64(0xc20c677fb1da6bbd), CONST64(0x7ecc59dc6efb95a2),
453 CONST64(0x9f40e161be1fa1fe), CONST64(0xc3e310cbeb18f308), CONST64(0x2f3081e1fe4fb1ce), CONST64(0x160e0c10080a0206),
454 CONST64(0x675e922e17dbcc49), CONST64(0x3f66a26e37f3c451), CONST64(0xcf534ee874691d27), CONST64(0x9c6c78a05044143c),
455 CONST64(0x0e73b0562be8c358), CONST64(0x9a34573f91f263a5), CONST64(0xed3ce69e4f95da73), CONST64(0x358ed3d269345de7),
456 CONST64(0x2380dfc2613e5fe1), CONST64(0xd72ef2ae578bdc79), CONST64(0x486e13cfe9947d87), CONST64(0x6c59942613decd4a),
457 CONST64(0x5e601fdfe19e7f81), CONST64(0x049bc1ea752f5aee), CONST64(0xf3197547adc16cb4), CONST64(0x3e89d5da6d315ce4),
458 CONST64(0xefff08ebfb0cf704), CONST64(0x47f2d42d98be266a), CONST64(0xb7c738abdb24ff1c), CONST64(0x11b9543b937eed2a),
459 CONST64(0x36a24a13876fe825), CONST64(0x26f4699c4ed39dba), CONST64(0xee107f5fa1ce6fb1), CONST64(0x8b8d0304028c8e8f),
460 CONST64(0xe34f56c8647d192b), CONST64(0x9447e769ba1aa0fd), CONST64(0xdeea1ad3e717f00d), CONST64(0xba98113c1e978986),
461 CONST64(0x692d22783c330f11), CONST64(0x311512381c1b0709), CONST64(0xfd6ac5118629afec), CONST64(0x9bdb208bcb30fb10),
462 CONST64(0x5838304020280818), CONST64(0x976b7ea85441153f), CONST64(0x7f232e6834390d17), CONST64(0x2c1c18201014040c),
463 CONST64(0x0b07060804050103), CONST64(0xab2145078de964ac), CONST64(0xca27f8b65b84df7c), CONST64(0x0d5f2997c5b3769a),
464 CONST64(0x64720beff980798b), CONST64(0xdc29f4a6538edd7a), CONST64(0xb2b38ef5f4c93d47), CONST64(0x8a6274b0584e163a),
465 CONST64(0xa4bd82e5fcc33f41), CONST64(0xfc85b2a5dceb3759), CONST64(0xf81e734fa9c46db7), CONST64(0x95a890dde0d83848),
466 CONST64(0x7708b1a1de67b9d6), CONST64(0x2a4437bfd1a27395), CONST64(0x3da54c1b836ae926), CONST64(0xea8bbeb5d4e1355f),
467 CONST64(0x6db6e392491c55ff), CONST64(0x3c4a3bafd9a87193), CONST64(0x727c07fff18a7b8d), CONST64(0x9d830f140a868c89),
468 CONST64(0x214331b7d5a77296), CONST64(0xb19f17341a928885), CONST64(0xe4f80ee3ff09f607), CONST64(0x33d6fc4da8822a7e),
469 CONST64(0xafba84edf8c63e42), CONST64(0x2887d9ca653b5ee2), CONST64(0x4cf5d2259cbb2769), CONST64(0xc0cf890a054346ca),
470 CONST64(0x74242860303c0c14), CONST64(0xa026430f89ec65af), CONST64(0xdf056d67bdd568b8), CONST64(0x8c3a5b2f99f861a3),
471 CONST64(0x1d090a180c0f0305), CONST64(0x187dbc4623e2c15e), CONST64(0x7bb8ef82411657f9), CONST64(0x9918cefe7fa9d667),
472 CONST64(0xf035ec86439ad976), CONST64(0x1295cdfa7d2558e8), CONST64(0xfb32ea8e479fd875), CONST64(0xbd2f491785e366aa),
473 CONST64(0x921fc8f67bacd764), CONST64(0x83a69ccde8d23a4e), CONST64(0x4b428a0e07cfc845), CONST64(0xb9b488fdf0cc3c44),
474 CONST64(0x90dc2683cf35fa13), CONST64(0x63c553c462f496a7), CONST64(0xa552f551a601a7f4), CONST64(0x01ef77b45ac298b5),
475 CONST64(0x1abe5233977bec29), CONST64(0x7c0fb7a9da62b8d5), CONST64(0x226fa8763bfcc754), CONST64(0xf66dc319822caeef),
476 CONST64(0xd4026b6fb9d069bb), CONST64(0xbfeca762317a4bdd), CONST64(0xd176dd31963dabe0), CONST64(0xc778d1219e37a9e6),
477 CONST64(0xb6284f1f81e667a9), CONST64(0x4e363c5028220a1e), CONST64(0xcbc88f02014647c9), CONST64(0xc8e416c3ef1df20b),
478 CONST64(0x032c99c1ee5bb5c2), CONST64(0x6beecc0d88aa2266), CONST64(0x4981647bb356e532), CONST64(0x0cb05e239f71ee2f),
479 CONST64(0x461da399c27cbedf), CONST64(0x38d1fa45ac872b7d), CONST64(0xe2a0217c3ebf819e), CONST64(0xa67e6c90485a1236),
480 CONST64(0xf4ae2d6c36b58398), CONST64(0xf5415ad86c771b2d), CONST64(0x622a247038360e12), CONST64(0x60e9ca058caf2365),
481 CONST64(0xf9f104fbf306f502), CONST64(0xddc68312094c45cf), CONST64(0x76e7c61584a52163), CONST64(0x71509e3e1fd1ce4f),
482 CONST64(0xa9e2ab72397049db), CONST64(0x09c4e87db09c2c74), CONST64(0x8dd52c9bc33af916), CONST64(0x54886e63bf59e637),
483 CONST64(0x1e2593d9e254b6c7), CONST64(0x25d8f05da0882878), CONST64(0x816572b85c4b1739), CONST64(0xffa92b6432b0829b),
484 CONST64(0xfe465cd068721a2e), CONST64(0xac961d2c169d8b80), CONST64(0xbcc03ea3df21fe1f), CONST64(0xa7911b2412988a83),
485 CONST64(0x533f3648242d091b), CONST64(0x40458c0603cac946), CONST64(0xd8b2354c26a18794), CONST64(0x98f7b94a256b4ed2),
486 CONST64(0x659d7c5ba342e13e), CONST64(0x1fcae46db8962e72), CONST64(0x42866273b753e431), CONST64(0x6e9a7a53a747e03d),
487 CONST64(0x2bab400b8b60eb20), CONST64(0x59d747f47aea90ad), CONST64(0xb85bff49aa0ea4f1), CONST64(0xd25a44f078661e22),
488 CONST64(0xcebc395c2eab8592), CONST64(0x873d5d279dfd60a0), CONST64(0x0000000000000000), CONST64(0x5afbde3594b1256f),
489 CONST64(0xf2f602f3f703f401), CONST64(0xd5ed1cdbe312f10e), CONST64(0x75cb5fd46afe94a1), CONST64(0x45313a582c270b1d),
490 CONST64(0x5f8f686bbb5ce734), CONST64(0x1056238fc9bc759f), CONST64(0x07b7582b9b74ef2c), CONST64(0xe18cb8bdd0e4345c),
491 CONST64(0xc697a695c4f53153), CONST64(0x8f16c2ee77a3d461), CONST64(0xa30adace67b7d06d), CONST64(0xd3b5334422a48697),
492 CONST64(0x556719d7e59b7e82), CONST64(0xeb64c9018e23adea), CONST64(0xa1c934bbd32efd1a), CONST64(0x2edff655a48d297b),
493 CONST64(0xcd90a09dc0f03050), CONST64(0x88a19ac5ecd73b4d), CONST64(0x30fa658c46d99fbc), CONST64(0x86d22a93c73ff815),
494 CONST64(0x2968ae7e3ff9c657), CONST64(0xad796a984c5f1335), CONST64(0x3a121430181e060a), CONST64(0x271b1e281411050f),
495 CONST64(0x3461a46633f6c552), CONST64(0xbb77668844551133), CONST64(0x06582f9fc1b67799), CONST64(0x436915c7ed917c84),
496 CONST64(0x797b01f7f58f7a8e), CONST64(0x6f750de7fd857888), CONST64(0xf782b4add8ee365a), CONST64(0xc45448e0706c1c24),
497 CONST64(0x9eaf96d5e4dd394b), CONST64(0x1992cbf2792059eb), CONST64(0xe84850c060781828), CONST64(0x70bfe98a451356fa),
498 CONST64(0x393e8df1f645b3c8), CONST64(0x243787e9fa4ab0cd), CONST64(0x51fcd83d90b4246c), CONST64(0x7de0c01d80a02060),
499 CONST64(0x32398bf9f240b2cb), CONST64(0x4fd94be472e092ab), CONST64(0x894eed71b615a3f8), CONST64(0x137aba4e27e7c05d),
500 CONST64(0xd6c1851a0d4944cc), CONST64(0x9133513795f762a6), CONST64(0xb070608040501030), CONST64(0x082b9fc9ea5eb4c1),
501 CONST64(0xc5bb3f542aae8491), CONST64(0xe7d49722115243c5), CONST64(0x44de4dec76e593a8), CONST64(0x0574b65e2fedc25b),
502 CONST64(0xb4eba16a357f4ade), CONST64(0x5b14a981ce73bdda), CONST64(0x808a050c06898f8c), CONST64(0x02c3ee75b4992d77),
503 CONST64(0x5013af89ca76bcd9), CONST64(0x2df36f944ad69cb9), CONST64(0xc90b6177b5df6abe), CONST64(0xfadd9d3a1d5d40c0),
504 CONST64(0x7a5798361bd4cf4c), CONST64(0x8249eb79b210a2fb), CONST64(0xe9a727743aba809d), CONST64(0x93f0bf42216e4fd1),
505 CONST64(0xd95d42f87c631f21), CONST64(0x5d4c861e0fc5ca43), CONST64(0xda71db399238aae3), CONST64(0xecd3912a155742c6),
506 };
507
508 static const ulong64 T7[256] = {
509 CONST64(0x016ab9bb68d2d3ba), CONST64(0xb1669ae5194dfc54), CONST64(0xcd1465e293bc712f), CONST64(0x511b8725b9cd9c74),
510 CONST64(0xa457a2f70251f553), CONST64(0x03bed6d0b86b68d3), CONST64(0x04b5ded6bd6f6bd2), CONST64(0xfe8552b36429d74d),
511 CONST64(0xad4abafd0d5df050), CONST64(0x63e009cf268ae9ac), CONST64(0x84961c09830e8a8d), CONST64(0x1a4d91a579c6dcbf),
512 CONST64(0x4d37a73daddd9070), CONST64(0xa35caaf10755f652), CONST64(0xe117a47bc852b39a), CONST64(0xf98e5ab5612dd44c),
513 CONST64(0xac200346658f23ea), CONST64(0x1184e6c4a67362d5), CONST64(0xc268cc55f166a497), CONST64(0x0da8c6dcb2636ed1),
514 CONST64(0x99d085aaffcc5533), CONST64(0xaa41b2fb0859f351), CONST64(0x9c0fe2c72a71ed5b), CONST64(0x55ae59f304a2f7a6),
515 CONST64(0x20c1befe815f7fde), CONST64(0xe5a27aad753dd848), CONST64(0x7fcc29d7329ae5a8), CONST64(0xe80abc71c75eb699),
516 CONST64(0x3be696e0904b70db), CONST64(0x9edb8dacfac85632), CONST64(0x2215d19551e6c4b7), CONST64(0xceaab3322bd719fc),
517 CONST64(0x93734b7048ab38e3), CONST64(0xfd3b8463dc42bf9e), CONST64(0xd052fc41ef7eae91), CONST64(0xe61cac7dcd56b09b),
518 CONST64(0x947843764daf3be2), CONST64(0x0661b1bd6dd6d0bb), CONST64(0xdaf1329b5819c341), CONST64(0x17e55779cba5b26e),
519 CONST64(0x5cb341f90baef2a5), CONST64(0x4b561680c00b40cb), CONST64(0x0cc27f67dab1bd6b), CONST64(0xcc7edc59fb6ea295),
520 CONST64(0x409f61e11fbefea1), CONST64(0xe3c3cb1018eb08f3), CONST64(0x302fe1814ffeceb1), CONST64(0x0e16100c0a080602),
521 CONST64(0x5e672e92db1749cc), CONST64(0x663f6ea2f33751c4), CONST64(0x53cfe84e6974271d), CONST64(0x6c9ca07844503c14),
522 CONST64(0x730e56b0e82b58c3), CONST64(0x349a3f57f291a563), CONST64(0x3ced9ee6954f73da), CONST64(0x8e35d2d33469e75d),
523 CONST64(0x8023c2df3e61e15f), CONST64(0x2ed7aef28b5779dc), CONST64(0x6e48cf1394e9877d), CONST64(0x596c2694de134acd),
524 CONST64(0x605edf1f9ee1817f), CONST64(0x9b04eac12f75ee5a), CONST64(0x19f34775c1adb46c), CONST64(0x893edad5316de45c),
525 CONST64(0xffefeb080cfb04f7), CONST64(0xf2472dd4be986a26), CONST64(0xc7b7ab3824db1cff), CONST64(0xb9113b547e932aed),
526 CONST64(0xa236134a6f8725e8), CONST64(0xf4269c69d34eba9d), CONST64(0x10ee5f7fcea1b16f), CONST64(0x8d8b04038c028f8e),
527 CONST64(0x4fe3c8567d642b19), CONST64(0x479469e71abafda0), CONST64(0xeaded31a17e70df0), CONST64(0x98ba3c11971e8689),
528 CONST64(0x2d697822333c110f), CONST64(0x153138121b1c0907), CONST64(0x6afd11c52986ecaf), CONST64(0xdb9b8b2030cb10fb),
529 CONST64(0x3858403028201808), CONST64(0x6b97a87e41543f15), CONST64(0x237f682e3934170d), CONST64(0x1c2c201814100c04),
530 CONST64(0x070b080605040301), CONST64(0x21ab0745e98dac64), CONST64(0x27cab6f8845b7cdf), CONST64(0x5f0d9729b3c59a76),
531 CONST64(0x7264ef0b80f98b79), CONST64(0x29dca6f48e537add), CONST64(0xb3b2f58ec9f4473d), CONST64(0x628ab0744e583a16),
532 CONST64(0xbda4e582c3fc413f), CONST64(0x85fca5b2ebdc5937), CONST64(0x1ef84f73c4a9b76d), CONST64(0xa895dd90d8e04838),
533 CONST64(0x0877a1b167ded6b9), CONST64(0x442abf37a2d19573), CONST64(0xa53d1b4c6a8326e9), CONST64(0x8beab5bee1d45f35),
534 CONST64(0xb66d92e31c49ff55), CONST64(0x4a3caf3ba8d99371), CONST64(0x7c72ff078af18d7b), CONST64(0x839d140f860a898c),
535 CONST64(0x4321b731a7d59672), CONST64(0x9fb13417921a8588), CONST64(0xf8e4e30e09ff07f6), CONST64(0xd6334dfc82a87e2a),
536 CONST64(0xbaafed84c6f8423e), CONST64(0x8728cad93b65e25e), CONST64(0xf54c25d2bb9c6927), CONST64(0xcfc00a894305ca46),
537 CONST64(0x247460283c30140c), CONST64(0x26a00f43ec89af65), CONST64(0x05df676dd5bdb868), CONST64(0x3a8c2f5bf899a361),
538 CONST64(0x091d180a0f0c0503), CONST64(0x7d1846bce2235ec1), CONST64(0xb87b82ef1641f957), CONST64(0x1899fecea97f67d6),
539 CONST64(0x35f086ec9a4376d9), CONST64(0x9512facd257de858), CONST64(0x32fb8eea9f4775d8), CONST64(0x2fbd1749e385aa66),
540 CONST64(0x1f92f6c8ac7b64d7), CONST64(0xa683cd9cd2e84e3a), CONST64(0x424b0e8acf0745c8), CONST64(0xb4b9fd88ccf0443c),
541 CONST64(0xdc90832635cf13fa), CONST64(0xc563c453f462a796), CONST64(0x52a551f501a6f4a7), CONST64(0xef01b477c25ab598),
542 CONST64(0xbe1a33527b9729ec), CONST64(0x0f7ca9b762dad5b8), CONST64(0x6f2276a8fc3b54c7), CONST64(0x6df619c32c82efae),
543 CONST64(0x02d46f6bd0b9bb69), CONST64(0xecbf62a77a31dd4b), CONST64(0x76d131dd3d96e0ab), CONST64(0x78c721d1379ee6a9),
544 CONST64(0x28b61f4fe681a967), CONST64(0x364e503c22281e0a), CONST64(0xc8cb028f4601c947), CONST64(0xe4c8c3161def0bf2),
545 CONST64(0x2c03c1995beec2b5), CONST64(0xee6b0dccaa886622), CONST64(0x81497b6456b332e5), CONST64(0xb00c235e719f2fee),
546 CONST64(0x1d4699a37cc2dfbe), CONST64(0xd13845fa87ac7d2b), CONST64(0xa0e27c21bf3e9e81), CONST64(0x7ea6906c5a483612),
547 CONST64(0xaef46c2db5369883), CONST64(0x41f5d85a776c2d1b), CONST64(0x2a6270243638120e), CONST64(0xe96005caaf8c6523),
548 CONST64(0xf1f9fb0406f302f5), CONST64(0xc6dd12834c09cf45), CONST64(0xe77615c6a5846321), CONST64(0x50713e9ed11f4fce),
549 CONST64(0xe2a972ab7039db49), CONST64(0xc4097de89cb0742c), CONST64(0xd58d9b2c3ac316f9), CONST64(0x8854636e59bf37e6),
550 CONST64(0x251ed99354e2c7b6), CONST64(0xd8255df088a07828), CONST64(0x6581b8724b5c3917), CONST64(0xa9ff642bb0329b82),
551 CONST64(0x46fed05c72682e1a), CONST64(0x96ac2c1d9d16808b), CONST64(0xc0bca33e21df1ffe), CONST64(0x91a7241b9812838a),
552 CONST64(0x3f5348362d241b09), CONST64(0x4540068cca0346c9), CONST64(0xb2d84c35a1269487), CONST64(0xf7984ab96b25d24e),
553 CONST64(0x9d655b7c42a33ee1), CONST64(0xca1f6de496b8722e), CONST64(0x8642736253b731e4), CONST64(0x9a6e537a47a73de0),
554 CONST64(0xab2b0b40608b20eb), CONST64(0xd759f447ea7aad90), CONST64(0x5bb849ff0eaaf1a4), CONST64(0x5ad2f0446678221e),
555 CONST64(0xbcce5c39ab2e9285), CONST64(0x3d87275dfd9da060), CONST64(0x0000000000000000), CONST64(0xfb5a35deb1946f25),
556 CONST64(0xf6f2f30203f701f4), CONST64(0xedd5db1c12e30ef1), CONST64(0xcb75d45ffe6aa194), CONST64(0x3145583a272c1d0b),
557 CONST64(0x8f5f6b685cbb34e7), CONST64(0x56108f23bcc99f75), CONST64(0xb7072b58749b2cef), CONST64(0x8ce1bdb8e4d05c34),
558 CONST64(0x97c695a6f5c45331), CONST64(0x168feec2a37761d4), CONST64(0x0aa3cedab7676dd0), CONST64(0xb5d34433a4229786),
559 CONST64(0x6755d7199be5827e), CONST64(0x64eb01c9238eeaad), CONST64(0xc9a1bb342ed31afd), CONST64(0xdf2e55f68da47b29),
560 CONST64(0x90cd9da0f0c05030), CONST64(0xa188c59ad7ec4d3b), CONST64(0xfa308c65d946bc9f), CONST64(0xd286932a3fc715f8),
561 CONST64(0x68297eaef93f57c6), CONST64(0x79ad986a5f4c3513), CONST64(0x123a30141e180a06), CONST64(0x1b27281e11140f05),
562 CONST64(0x613466a4f63352c5), CONST64(0x77bb886655443311), CONST64(0x58069f2fb6c19977), CONST64(0x6943c71591ed847c),
563 CONST64(0x7b79f7018ff58e7a), CONST64(0x756fe70d85fd8878), CONST64(0x82f7adb4eed85a36), CONST64(0x54c4e0486c70241c),
564 CONST64(0xaf9ed596dde44b39), CONST64(0x9219f2cb2079eb59), CONST64(0x48e8c05078602818), CONST64(0xbf708ae91345fa56),
565 CONST64(0x3e39f18d45f6c8b3), CONST64(0x3724e9874afacdb0), CONST64(0xfc513dd8b4906c24), CONST64(0xe07d1dc0a0806020),
566 CONST64(0x3932f98b40f2cbb2), CONST64(0xd94fe44be072ab92), CONST64(0x4e8971ed15b6f8a3), CONST64(0x7a134ebae7275dc0),
567 CONST64(0xc1d61a85490dcc44), CONST64(0x33913751f795a662), CONST64(0x70b0806050403010), CONST64(0x2b08c99f5eeac1b4),
568 CONST64(0xbbc5543fae2a9184), CONST64(0xd4e722975211c543), CONST64(0xde44ec4de576a893), CONST64(0x74055eb6ed2f5bc2),
569 CONST64(0xebb46aa17f35de4a), CONST64(0x145b81a973cedabd), CONST64(0x8a800c0589068c8f), CONST64(0xc30275ee99b4772d),
570 CONST64(0x135089af76cad9bc), CONST64(0xf32d946fd64ab99c), CONST64(0x0bc97761dfb5be6a), CONST64(0xddfa3a9d5d1dc040),
571 CONST64(0x577a3698d41b4ccf), CONST64(0x498279eb10b2fba2), CONST64(0xa7e97427ba3a9d80), CONST64(0xf09342bf6e21d14f),
572 CONST64(0x5dd9f842637c211f), CONST64(0x4c5d1e86c50f43ca), CONST64(0x71da39db3892e3aa), CONST64(0xd3ec2a915715c642),
573 };
574
575 static const ulong64 c[R + 1] = {
576 CONST64(0xba542f7453d3d24d),
577 CONST64(0x50ac8dbf70529a4c),
578 CONST64(0xead597d133515ba6),
579 CONST64(0xde48a899db32b7fc),
580 CONST64(0xe39e919be2bb416e),
581 CONST64(0xa5cb6b95a1f3b102),
582 CONST64(0xccc41d14c363da5d),
583 CONST64(0x5fdc7dcd7f5a6c5c),
584 CONST64(0xf726ffede89d6f8e),
585 };
586
587 /**
588 Initialize the Khazad block cipher
589 @param key The symmetric key you wish to pass
590 @param keylen The key length in bytes
591 @param num_rounds The number of rounds desired (0 for default)
592 @param skey The key in as scheduled by this function.
593 @return CRYPT_OK if successful
594 */
595 int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
596 {
597 int r;
598 const ulong64 *S;
599 ulong64 K2, K1;
600
601 LTC_ARGCHK(key != NULL);
602 LTC_ARGCHK(skey != NULL);
603 if (keylen != 16) {
604 return CRYPT_INVALID_KEYSIZE;
605 }
606 if (num_rounds != 8 && num_rounds != 0) {
607 return CRYPT_INVALID_ROUNDS;
608 }
609
610 /* use 7th table */
611 S = T7;
612
613 /*
614 * map unsigned char array cipher key to initial key state (mu):
615 */
616 K2 =
617 ((ulong64)key[ 0] << 56) ^
618 ((ulong64)key[ 1] << 48) ^
619 ((ulong64)key[ 2] << 40) ^
620 ((ulong64)key[ 3] << 32) ^
621 ((ulong64)key[ 4] << 24) ^
622 ((ulong64)key[ 5] << 16) ^
623 ((ulong64)key[ 6] << 8) ^
624 ((ulong64)key[ 7] );
625 K1 =
626 ((ulong64)key[ 8] << 56) ^
627 ((ulong64)key[ 9] << 48) ^
628 ((ulong64)key[10] << 40) ^
629 ((ulong64)key[11] << 32) ^
630 ((ulong64)key[12] << 24) ^
631 ((ulong64)key[13] << 16) ^
632 ((ulong64)key[14] << 8) ^
633 ((ulong64)key[15] );
634
635 /*
636 * compute the round keys:
637 */
638 for (r = 0; r <= R; r++) {
639 /*
640 * K[r] = rho(c[r], K1) ^ K2;
641 */
642 skey->khazad.roundKeyEnc[r] =
643 T0[(int)(K1 >> 56) ] ^
644 T1[(int)(K1 >> 48) & 0xff] ^
645 T2[(int)(K1 >> 40) & 0xff] ^
646 T3[(int)(K1 >> 32) & 0xff] ^
647 T4[(int)(K1 >> 24) & 0xff] ^
648 T5[(int)(K1 >> 16) & 0xff] ^
649 T6[(int)(K1 >> 8) & 0xff] ^
650 T7[(int)(K1 ) & 0xff] ^
651 c[r] ^ K2;
652 K2 = K1; K1 = skey->khazad.roundKeyEnc[r];
653 }
654 /*
655 * compute the inverse key schedule:
656 * K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r})
657 */
658 skey->khazad.roundKeyDec[0] = skey->khazad.roundKeyEnc[R];
659 for (r = 1; r < R; r++) {
660 K1 = skey->khazad.roundKeyEnc[R - r];
661 skey->khazad.roundKeyDec[r] =
662 T0[(int)S[(int)(K1 >> 56) ] & 0xff] ^
663 T1[(int)S[(int)(K1 >> 48) & 0xff] & 0xff] ^
664 T2[(int)S[(int)(K1 >> 40) & 0xff] & 0xff] ^
665 T3[(int)S[(int)(K1 >> 32) & 0xff] & 0xff] ^
666 T4[(int)S[(int)(K1 >> 24) & 0xff] & 0xff] ^
667 T5[(int)S[(int)(K1 >> 16) & 0xff] & 0xff] ^
668 T6[(int)S[(int)(K1 >> 8) & 0xff] & 0xff] ^
669 T7[(int)S[(int)(K1 ) & 0xff] & 0xff];
670 }
671 skey->khazad.roundKeyDec[R] = skey->khazad.roundKeyEnc[0];
672
673 return CRYPT_OK;
674 }
675
676 static void khazad_crypt(const unsigned char *plaintext, unsigned char *ciphertext,
677 const ulong64 *roundKey) {
678 int r;
679 ulong64 state;
680 /*
681 * map plaintext block to cipher state (mu)
682 * and add initial round key (sigma[K^0]):
683 */
684 state =
685 ((ulong64)plaintext[0] << 56) ^
686 ((ulong64)plaintext[1] << 48) ^
687 ((ulong64)plaintext[2] << 40) ^
688 ((ulong64)plaintext[3] << 32) ^
689 ((ulong64)plaintext[4] << 24) ^
690 ((ulong64)plaintext[5] << 16) ^
691 ((ulong64)plaintext[6] << 8) ^
692 ((ulong64)plaintext[7] ) ^
693 roundKey[0];
694
695 /*
696 * R - 1 full rounds:
697 */
698 for (r = 1; r < R; r++) {
699 state =
700 T0[(int)(state >> 56) ] ^
701 T1[(int)(state >> 48) & 0xff] ^
702 T2[(int)(state >> 40) & 0xff] ^
703 T3[(int)(state >> 32) & 0xff] ^
704 T4[(int)(state >> 24) & 0xff] ^
705 T5[(int)(state >> 16) & 0xff] ^
706 T6[(int)(state >> 8) & 0xff] ^
707 T7[(int)(state ) & 0xff] ^
708 roundKey[r];
709 }
710
711 /*
712 * last round:
713 */
714 state =
715 (T0[(int)(state >> 56) ] & CONST64(0xff00000000000000)) ^
716 (T1[(int)(state >> 48) & 0xff] & CONST64(0x00ff000000000000)) ^
717 (T2[(int)(state >> 40) & 0xff] & CONST64(0x0000ff0000000000)) ^
718 (T3[(int)(state >> 32) & 0xff] & CONST64(0x000000ff00000000)) ^
719 (T4[(int)(state >> 24) & 0xff] & CONST64(0x00000000ff000000)) ^
720 (T5[(int)(state >> 16) & 0xff] & CONST64(0x0000000000ff0000)) ^
721 (T6[(int)(state >> 8) & 0xff] & CONST64(0x000000000000ff00)) ^
722 (T7[(int)(state ) & 0xff] & CONST64(0x00000000000000ff)) ^
723 roundKey[R];
724
725 /*
726 * map cipher state to ciphertext block (mu^{-1}):
727 */
728 ciphertext[0] = (unsigned char)(state >> 56);
729 ciphertext[1] = (unsigned char)(state >> 48);
730 ciphertext[2] = (unsigned char)(state >> 40);
731 ciphertext[3] = (unsigned char)(state >> 32);
732 ciphertext[4] = (unsigned char)(state >> 24);
733 ciphertext[5] = (unsigned char)(state >> 16);
734 ciphertext[6] = (unsigned char)(state >> 8);
735 ciphertext[7] = (unsigned char)(state );
736 }
737
738 /**
739 Encrypts a block of text with Khazad
740 @param pt The input plaintext (8 bytes)
741 @param ct The output ciphertext (8 bytes)
742 @param skey The key as scheduled
743 @return CRYPT_OK if successful
744 */
745 int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
746 {
747 LTC_ARGCHK(pt != NULL);
748 LTC_ARGCHK(ct != NULL);
749 LTC_ARGCHK(skey != NULL);
750 khazad_crypt(pt, ct, skey->khazad.roundKeyEnc);
751 return CRYPT_OK;
752 }
753
754 /**
755 Decrypts a block of text with Khazad
756 @param ct The input ciphertext (8 bytes)
757 @param pt The output plaintext (8 bytes)
758 @param skey The key as scheduled
759 @return CRYPT_OK if successful
760 */
761 int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
762 {
763 LTC_ARGCHK(pt != NULL);
764 LTC_ARGCHK(ct != NULL);
765 LTC_ARGCHK(skey != NULL);
766 khazad_crypt(ct, pt, skey->khazad.roundKeyDec);
767 return CRYPT_OK;
768 }
769
770 /**
771 Performs a self-test of the Khazad block cipher
772 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
773 */
774 int khazad_test(void)
775 {
776 #ifndef LTC_TEST
777 return CRYPT_NOP;
778 #else
779 static const struct test {
780 unsigned char pt[8], ct[8], key[16];
781 } tests[] = {
782 {
783 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
784 { 0x49, 0xA4, 0xCE, 0x32, 0xAC, 0x19, 0x0E, 0x3F },
785 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
787 }, {
788 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
789 { 0x64, 0x5D, 0x77, 0x3E, 0x40, 0xAB, 0xDD, 0x53 },
790 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
792 }, {
793 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
794 { 0x9E, 0x39, 0x98, 0x64, 0xF7, 0x8E, 0xCA, 0x02 },
795 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
797 }, {
798 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
799 { 0xA9, 0xDF, 0x3D, 0x2C, 0x64, 0xD3, 0xEA, 0x28 },
800 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
802 }
803 };
804 int x, y;
805 unsigned char buf[2][8];
806 symmetric_key skey;
807
808 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
809 khazad_setup(tests[x].key, 16, 0, &skey);
810 khazad_ecb_encrypt(tests[x].pt, buf[0], &skey);
811 khazad_ecb_decrypt(buf[0], buf[1], &skey);
812 if (XMEMCMP(buf[0], tests[x].ct, 8) || XMEMCMP(buf[1], tests[x].pt, 8)) {
813 return CRYPT_FAIL_TESTVECTOR;
814 }
815
816 for (y = 0; y < 1000; y++) khazad_ecb_encrypt(buf[0], buf[0], &skey);
817 for (y = 0; y < 1000; y++) khazad_ecb_decrypt(buf[0], buf[0], &skey);
818 if (XMEMCMP(buf[0], tests[x].ct, 8)) {
819 return CRYPT_FAIL_TESTVECTOR;
820 }
821
822 }
823 return CRYPT_OK;
824 #endif
825 }
826
827 /** Terminate the context
828 @param skey The scheduled key
829 */
830 void khazad_done(symmetric_key *skey)
831 {
832 }
833
834 /**
835 Gets suitable key size
836 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
837 @return CRYPT_OK if the input key size is acceptable.
838 */
839 int khazad_keysize(int *keysize)
840 {
841 LTC_ARGCHK(keysize != NULL);
842 if (*keysize >= 16) {
843 *keysize = 16;
844 return CRYPT_OK;
845 } else {
846 return CRYPT_INVALID_KEYSIZE;
847 }
848 }
849
850 #endif
851
852 /* $Source$ */
853 /* $Revision$ */
854 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file kseed.c
13 seed implementation of SEED derived from RFC4269
14 Tom St Denis
15 */
16
17 #include "tomcrypt.h"
18
19 #ifdef LTC_KSEED
20
21 const struct ltc_cipher_descriptor kseed_desc = {
22 "seed",
23 20,
24 16, 16, 16, 16,
25 &kseed_setup,
26 &kseed_ecb_encrypt,
27 &kseed_ecb_decrypt,
28 &kseed_test,
29 &kseed_done,
30 &kseed_keysize,
31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
32 };
33
34 static const ulong32 SS0[256] = {
35 0x2989A1A8UL,0x05858184UL,0x16C6D2D4UL,0x13C3D3D0UL,0x14445054UL,0x1D0D111CUL,0x2C8CA0ACUL,0x25052124UL,
36 0x1D4D515CUL,0x03434340UL,0x18081018UL,0x1E0E121CUL,0x11415150UL,0x3CCCF0FCUL,0x0ACAC2C8UL,0x23436360UL,
37 0x28082028UL,0x04444044UL,0x20002020UL,0x1D8D919CUL,0x20C0E0E0UL,0x22C2E2E0UL,0x08C8C0C8UL,0x17071314UL,
38 0x2585A1A4UL,0x0F8F838CUL,0x03030300UL,0x3B4B7378UL,0x3B8BB3B8UL,0x13031310UL,0x12C2D2D0UL,0x2ECEE2ECUL,
39 0x30407070UL,0x0C8C808CUL,0x3F0F333CUL,0x2888A0A8UL,0x32023230UL,0x1DCDD1DCUL,0x36C6F2F4UL,0x34447074UL,
40 0x2CCCE0ECUL,0x15859194UL,0x0B0B0308UL,0x17475354UL,0x1C4C505CUL,0x1B4B5358UL,0x3D8DB1BCUL,0x01010100UL,
41 0x24042024UL,0x1C0C101CUL,0x33437370UL,0x18889098UL,0x10001010UL,0x0CCCC0CCUL,0x32C2F2F0UL,0x19C9D1D8UL,
42 0x2C0C202CUL,0x27C7E3E4UL,0x32427270UL,0x03838380UL,0x1B8B9398UL,0x11C1D1D0UL,0x06868284UL,0x09C9C1C8UL,
43 0x20406060UL,0x10405050UL,0x2383A3A0UL,0x2BCBE3E8UL,0x0D0D010CUL,0x3686B2B4UL,0x1E8E929CUL,0x0F4F434CUL,
44 0x3787B3B4UL,0x1A4A5258UL,0x06C6C2C4UL,0x38487078UL,0x2686A2A4UL,0x12021210UL,0x2F8FA3ACUL,0x15C5D1D4UL,
45 0x21416160UL,0x03C3C3C0UL,0x3484B0B4UL,0x01414140UL,0x12425250UL,0x3D4D717CUL,0x0D8D818CUL,0x08080008UL,
46 0x1F0F131CUL,0x19899198UL,0x00000000UL,0x19091118UL,0x04040004UL,0x13435350UL,0x37C7F3F4UL,0x21C1E1E0UL,
47 0x3DCDF1FCUL,0x36467274UL,0x2F0F232CUL,0x27072324UL,0x3080B0B0UL,0x0B8B8388UL,0x0E0E020CUL,0x2B8BA3A8UL,
48 0x2282A2A0UL,0x2E4E626CUL,0x13839390UL,0x0D4D414CUL,0x29496168UL,0x3C4C707CUL,0x09090108UL,0x0A0A0208UL,
49 0x3F8FB3BCUL,0x2FCFE3ECUL,0x33C3F3F0UL,0x05C5C1C4UL,0x07878384UL,0x14041014UL,0x3ECEF2FCUL,0x24446064UL,
50 0x1ECED2DCUL,0x2E0E222CUL,0x0B4B4348UL,0x1A0A1218UL,0x06060204UL,0x21012120UL,0x2B4B6368UL,0x26466264UL,
51 0x02020200UL,0x35C5F1F4UL,0x12829290UL,0x0A8A8288UL,0x0C0C000CUL,0x3383B3B0UL,0x3E4E727CUL,0x10C0D0D0UL,
52 0x3A4A7278UL,0x07474344UL,0x16869294UL,0x25C5E1E4UL,0x26062224UL,0x00808080UL,0x2D8DA1ACUL,0x1FCFD3DCUL,
53 0x2181A1A0UL,0x30003030UL,0x37073334UL,0x2E8EA2ACUL,0x36063234UL,0x15051114UL,0x22022220UL,0x38083038UL,
54 0x34C4F0F4UL,0x2787A3A4UL,0x05454144UL,0x0C4C404CUL,0x01818180UL,0x29C9E1E8UL,0x04848084UL,0x17879394UL,
55 0x35053134UL,0x0BCBC3C8UL,0x0ECEC2CCUL,0x3C0C303CUL,0x31417170UL,0x11011110UL,0x07C7C3C4UL,0x09898188UL,
56 0x35457174UL,0x3BCBF3F8UL,0x1ACAD2D8UL,0x38C8F0F8UL,0x14849094UL,0x19495158UL,0x02828280UL,0x04C4C0C4UL,
57 0x3FCFF3FCUL,0x09494148UL,0x39093138UL,0x27476364UL,0x00C0C0C0UL,0x0FCFC3CCUL,0x17C7D3D4UL,0x3888B0B8UL,
58 0x0F0F030CUL,0x0E8E828CUL,0x02424240UL,0x23032320UL,0x11819190UL,0x2C4C606CUL,0x1BCBD3D8UL,0x2484A0A4UL,
59 0x34043034UL,0x31C1F1F0UL,0x08484048UL,0x02C2C2C0UL,0x2F4F636CUL,0x3D0D313CUL,0x2D0D212CUL,0x00404040UL,
60 0x3E8EB2BCUL,0x3E0E323CUL,0x3C8CB0BCUL,0x01C1C1C0UL,0x2A8AA2A8UL,0x3A8AB2B8UL,0x0E4E424CUL,0x15455154UL,
61 0x3B0B3338UL,0x1CCCD0DCUL,0x28486068UL,0x3F4F737CUL,0x1C8C909CUL,0x18C8D0D8UL,0x0A4A4248UL,0x16465254UL,
62 0x37477374UL,0x2080A0A0UL,0x2DCDE1ECUL,0x06464244UL,0x3585B1B4UL,0x2B0B2328UL,0x25456164UL,0x3ACAF2F8UL,
63 0x23C3E3E0UL,0x3989B1B8UL,0x3181B1B0UL,0x1F8F939CUL,0x1E4E525CUL,0x39C9F1F8UL,0x26C6E2E4UL,0x3282B2B0UL,
64 0x31013130UL,0x2ACAE2E8UL,0x2D4D616CUL,0x1F4F535CUL,0x24C4E0E4UL,0x30C0F0F0UL,0x0DCDC1CCUL,0x08888088UL,
65 0x16061214UL,0x3A0A3238UL,0x18485058UL,0x14C4D0D4UL,0x22426260UL,0x29092128UL,0x07070304UL,0x33033330UL,
66 0x28C8E0E8UL,0x1B0B1318UL,0x05050104UL,0x39497178UL,0x10809090UL,0x2A4A6268UL,0x2A0A2228UL,0x1A8A9298UL
67 };
68
69 static const ulong32 SS1[256] = {
70 0x38380830UL,0xE828C8E0UL,0x2C2D0D21UL,0xA42686A2UL,0xCC0FCFC3UL,0xDC1ECED2UL,0xB03383B3UL,0xB83888B0UL,
71 0xAC2F8FA3UL,0x60204060UL,0x54154551UL,0xC407C7C3UL,0x44044440UL,0x6C2F4F63UL,0x682B4B63UL,0x581B4B53UL,
72 0xC003C3C3UL,0x60224262UL,0x30330333UL,0xB43585B1UL,0x28290921UL,0xA02080A0UL,0xE022C2E2UL,0xA42787A3UL,
73 0xD013C3D3UL,0x90118191UL,0x10110111UL,0x04060602UL,0x1C1C0C10UL,0xBC3C8CB0UL,0x34360632UL,0x480B4B43UL,
74 0xEC2FCFE3UL,0x88088880UL,0x6C2C4C60UL,0xA82888A0UL,0x14170713UL,0xC404C4C0UL,0x14160612UL,0xF434C4F0UL,
75 0xC002C2C2UL,0x44054541UL,0xE021C1E1UL,0xD416C6D2UL,0x3C3F0F33UL,0x3C3D0D31UL,0x8C0E8E82UL,0x98188890UL,
76 0x28280820UL,0x4C0E4E42UL,0xF436C6F2UL,0x3C3E0E32UL,0xA42585A1UL,0xF839C9F1UL,0x0C0D0D01UL,0xDC1FCFD3UL,
77 0xD818C8D0UL,0x282B0B23UL,0x64264662UL,0x783A4A72UL,0x24270723UL,0x2C2F0F23UL,0xF031C1F1UL,0x70324272UL,
78 0x40024242UL,0xD414C4D0UL,0x40014141UL,0xC000C0C0UL,0x70334373UL,0x64274763UL,0xAC2C8CA0UL,0x880B8B83UL,
79 0xF437C7F3UL,0xAC2D8DA1UL,0x80008080UL,0x1C1F0F13UL,0xC80ACAC2UL,0x2C2C0C20UL,0xA82A8AA2UL,0x34340430UL,
80 0xD012C2D2UL,0x080B0B03UL,0xEC2ECEE2UL,0xE829C9E1UL,0x5C1D4D51UL,0x94148490UL,0x18180810UL,0xF838C8F0UL,
81 0x54174753UL,0xAC2E8EA2UL,0x08080800UL,0xC405C5C1UL,0x10130313UL,0xCC0DCDC1UL,0x84068682UL,0xB83989B1UL,
82 0xFC3FCFF3UL,0x7C3D4D71UL,0xC001C1C1UL,0x30310131UL,0xF435C5F1UL,0x880A8A82UL,0x682A4A62UL,0xB03181B1UL,
83 0xD011C1D1UL,0x20200020UL,0xD417C7D3UL,0x00020202UL,0x20220222UL,0x04040400UL,0x68284860UL,0x70314171UL,
84 0x04070703UL,0xD81BCBD3UL,0x9C1D8D91UL,0x98198991UL,0x60214161UL,0xBC3E8EB2UL,0xE426C6E2UL,0x58194951UL,
85 0xDC1DCDD1UL,0x50114151UL,0x90108090UL,0xDC1CCCD0UL,0x981A8A92UL,0xA02383A3UL,0xA82B8BA3UL,0xD010C0D0UL,
86 0x80018181UL,0x0C0F0F03UL,0x44074743UL,0x181A0A12UL,0xE023C3E3UL,0xEC2CCCE0UL,0x8C0D8D81UL,0xBC3F8FB3UL,
87 0x94168692UL,0x783B4B73UL,0x5C1C4C50UL,0xA02282A2UL,0xA02181A1UL,0x60234363UL,0x20230323UL,0x4C0D4D41UL,
88 0xC808C8C0UL,0x9C1E8E92UL,0x9C1C8C90UL,0x383A0A32UL,0x0C0C0C00UL,0x2C2E0E22UL,0xB83A8AB2UL,0x6C2E4E62UL,
89 0x9C1F8F93UL,0x581A4A52UL,0xF032C2F2UL,0x90128292UL,0xF033C3F3UL,0x48094941UL,0x78384870UL,0xCC0CCCC0UL,
90 0x14150511UL,0xF83BCBF3UL,0x70304070UL,0x74354571UL,0x7C3F4F73UL,0x34350531UL,0x10100010UL,0x00030303UL,
91 0x64244460UL,0x6C2D4D61UL,0xC406C6C2UL,0x74344470UL,0xD415C5D1UL,0xB43484B0UL,0xE82ACAE2UL,0x08090901UL,
92 0x74364672UL,0x18190911UL,0xFC3ECEF2UL,0x40004040UL,0x10120212UL,0xE020C0E0UL,0xBC3D8DB1UL,0x04050501UL,
93 0xF83ACAF2UL,0x00010101UL,0xF030C0F0UL,0x282A0A22UL,0x5C1E4E52UL,0xA82989A1UL,0x54164652UL,0x40034343UL,
94 0x84058581UL,0x14140410UL,0x88098981UL,0x981B8B93UL,0xB03080B0UL,0xE425C5E1UL,0x48084840UL,0x78394971UL,
95 0x94178793UL,0xFC3CCCF0UL,0x1C1E0E12UL,0x80028282UL,0x20210121UL,0x8C0C8C80UL,0x181B0B13UL,0x5C1F4F53UL,
96 0x74374773UL,0x54144450UL,0xB03282B2UL,0x1C1D0D11UL,0x24250521UL,0x4C0F4F43UL,0x00000000UL,0x44064642UL,
97 0xEC2DCDE1UL,0x58184850UL,0x50124252UL,0xE82BCBE3UL,0x7C3E4E72UL,0xD81ACAD2UL,0xC809C9C1UL,0xFC3DCDF1UL,
98 0x30300030UL,0x94158591UL,0x64254561UL,0x3C3C0C30UL,0xB43686B2UL,0xE424C4E0UL,0xB83B8BB3UL,0x7C3C4C70UL,
99 0x0C0E0E02UL,0x50104050UL,0x38390931UL,0x24260622UL,0x30320232UL,0x84048480UL,0x68294961UL,0x90138393UL,
100 0x34370733UL,0xE427C7E3UL,0x24240420UL,0xA42484A0UL,0xC80BCBC3UL,0x50134353UL,0x080A0A02UL,0x84078783UL,
101 0xD819C9D1UL,0x4C0C4C40UL,0x80038383UL,0x8C0F8F83UL,0xCC0ECEC2UL,0x383B0B33UL,0x480A4A42UL,0xB43787B3UL
102 };
103
104 static const ulong32 SS2[256] = {
105 0xA1A82989UL,0x81840585UL,0xD2D416C6UL,0xD3D013C3UL,0x50541444UL,0x111C1D0DUL,0xA0AC2C8CUL,0x21242505UL,
106 0x515C1D4DUL,0x43400343UL,0x10181808UL,0x121C1E0EUL,0x51501141UL,0xF0FC3CCCUL,0xC2C80ACAUL,0x63602343UL,
107 0x20282808UL,0x40440444UL,0x20202000UL,0x919C1D8DUL,0xE0E020C0UL,0xE2E022C2UL,0xC0C808C8UL,0x13141707UL,
108 0xA1A42585UL,0x838C0F8FUL,0x03000303UL,0x73783B4BUL,0xB3B83B8BUL,0x13101303UL,0xD2D012C2UL,0xE2EC2ECEUL,
109 0x70703040UL,0x808C0C8CUL,0x333C3F0FUL,0xA0A82888UL,0x32303202UL,0xD1DC1DCDUL,0xF2F436C6UL,0x70743444UL,
110 0xE0EC2CCCUL,0x91941585UL,0x03080B0BUL,0x53541747UL,0x505C1C4CUL,0x53581B4BUL,0xB1BC3D8DUL,0x01000101UL,
111 0x20242404UL,0x101C1C0CUL,0x73703343UL,0x90981888UL,0x10101000UL,0xC0CC0CCCUL,0xF2F032C2UL,0xD1D819C9UL,
112 0x202C2C0CUL,0xE3E427C7UL,0x72703242UL,0x83800383UL,0x93981B8BUL,0xD1D011C1UL,0x82840686UL,0xC1C809C9UL,
113 0x60602040UL,0x50501040UL,0xA3A02383UL,0xE3E82BCBUL,0x010C0D0DUL,0xB2B43686UL,0x929C1E8EUL,0x434C0F4FUL,
114 0xB3B43787UL,0x52581A4AUL,0xC2C406C6UL,0x70783848UL,0xA2A42686UL,0x12101202UL,0xA3AC2F8FUL,0xD1D415C5UL,
115 0x61602141UL,0xC3C003C3UL,0xB0B43484UL,0x41400141UL,0x52501242UL,0x717C3D4DUL,0x818C0D8DUL,0x00080808UL,
116 0x131C1F0FUL,0x91981989UL,0x00000000UL,0x11181909UL,0x00040404UL,0x53501343UL,0xF3F437C7UL,0xE1E021C1UL,
117 0xF1FC3DCDUL,0x72743646UL,0x232C2F0FUL,0x23242707UL,0xB0B03080UL,0x83880B8BUL,0x020C0E0EUL,0xA3A82B8BUL,
118 0xA2A02282UL,0x626C2E4EUL,0x93901383UL,0x414C0D4DUL,0x61682949UL,0x707C3C4CUL,0x01080909UL,0x02080A0AUL,
119 0xB3BC3F8FUL,0xE3EC2FCFUL,0xF3F033C3UL,0xC1C405C5UL,0x83840787UL,0x10141404UL,0xF2FC3ECEUL,0x60642444UL,
120 0xD2DC1ECEUL,0x222C2E0EUL,0x43480B4BUL,0x12181A0AUL,0x02040606UL,0x21202101UL,0x63682B4BUL,0x62642646UL,
121 0x02000202UL,0xF1F435C5UL,0x92901282UL,0x82880A8AUL,0x000C0C0CUL,0xB3B03383UL,0x727C3E4EUL,0xD0D010C0UL,
122 0x72783A4AUL,0x43440747UL,0x92941686UL,0xE1E425C5UL,0x22242606UL,0x80800080UL,0xA1AC2D8DUL,0xD3DC1FCFUL,
123 0xA1A02181UL,0x30303000UL,0x33343707UL,0xA2AC2E8EUL,0x32343606UL,0x11141505UL,0x22202202UL,0x30383808UL,
124 0xF0F434C4UL,0xA3A42787UL,0x41440545UL,0x404C0C4CUL,0x81800181UL,0xE1E829C9UL,0x80840484UL,0x93941787UL,
125 0x31343505UL,0xC3C80BCBUL,0xC2CC0ECEUL,0x303C3C0CUL,0x71703141UL,0x11101101UL,0xC3C407C7UL,0x81880989UL,
126 0x71743545UL,0xF3F83BCBUL,0xD2D81ACAUL,0xF0F838C8UL,0x90941484UL,0x51581949UL,0x82800282UL,0xC0C404C4UL,
127 0xF3FC3FCFUL,0x41480949UL,0x31383909UL,0x63642747UL,0xC0C000C0UL,0xC3CC0FCFUL,0xD3D417C7UL,0xB0B83888UL,
128 0x030C0F0FUL,0x828C0E8EUL,0x42400242UL,0x23202303UL,0x91901181UL,0x606C2C4CUL,0xD3D81BCBUL,0xA0A42484UL,
129 0x30343404UL,0xF1F031C1UL,0x40480848UL,0xC2C002C2UL,0x636C2F4FUL,0x313C3D0DUL,0x212C2D0DUL,0x40400040UL,
130 0xB2BC3E8EUL,0x323C3E0EUL,0xB0BC3C8CUL,0xC1C001C1UL,0xA2A82A8AUL,0xB2B83A8AUL,0x424C0E4EUL,0x51541545UL,
131 0x33383B0BUL,0xD0DC1CCCUL,0x60682848UL,0x737C3F4FUL,0x909C1C8CUL,0xD0D818C8UL,0x42480A4AUL,0x52541646UL,
132 0x73743747UL,0xA0A02080UL,0xE1EC2DCDUL,0x42440646UL,0xB1B43585UL,0x23282B0BUL,0x61642545UL,0xF2F83ACAUL,
133 0xE3E023C3UL,0xB1B83989UL,0xB1B03181UL,0x939C1F8FUL,0x525C1E4EUL,0xF1F839C9UL,0xE2E426C6UL,0xB2B03282UL,
134 0x31303101UL,0xE2E82ACAUL,0x616C2D4DUL,0x535C1F4FUL,0xE0E424C4UL,0xF0F030C0UL,0xC1CC0DCDUL,0x80880888UL,
135 0x12141606UL,0x32383A0AUL,0x50581848UL,0xD0D414C4UL,0x62602242UL,0x21282909UL,0x03040707UL,0x33303303UL,
136 0xE0E828C8UL,0x13181B0BUL,0x01040505UL,0x71783949UL,0x90901080UL,0x62682A4AUL,0x22282A0AUL,0x92981A8AUL
137 };
138
139 static const ulong32 SS3[256] = {
140 0x08303838UL,0xC8E0E828UL,0x0D212C2DUL,0x86A2A426UL,0xCFC3CC0FUL,0xCED2DC1EUL,0x83B3B033UL,0x88B0B838UL,
141 0x8FA3AC2FUL,0x40606020UL,0x45515415UL,0xC7C3C407UL,0x44404404UL,0x4F636C2FUL,0x4B63682BUL,0x4B53581BUL,
142 0xC3C3C003UL,0x42626022UL,0x03333033UL,0x85B1B435UL,0x09212829UL,0x80A0A020UL,0xC2E2E022UL,0x87A3A427UL,
143 0xC3D3D013UL,0x81919011UL,0x01111011UL,0x06020406UL,0x0C101C1CUL,0x8CB0BC3CUL,0x06323436UL,0x4B43480BUL,
144 0xCFE3EC2FUL,0x88808808UL,0x4C606C2CUL,0x88A0A828UL,0x07131417UL,0xC4C0C404UL,0x06121416UL,0xC4F0F434UL,
145 0xC2C2C002UL,0x45414405UL,0xC1E1E021UL,0xC6D2D416UL,0x0F333C3FUL,0x0D313C3DUL,0x8E828C0EUL,0x88909818UL,
146 0x08202828UL,0x4E424C0EUL,0xC6F2F436UL,0x0E323C3EUL,0x85A1A425UL,0xC9F1F839UL,0x0D010C0DUL,0xCFD3DC1FUL,
147 0xC8D0D818UL,0x0B23282BUL,0x46626426UL,0x4A72783AUL,0x07232427UL,0x0F232C2FUL,0xC1F1F031UL,0x42727032UL,
148 0x42424002UL,0xC4D0D414UL,0x41414001UL,0xC0C0C000UL,0x43737033UL,0x47636427UL,0x8CA0AC2CUL,0x8B83880BUL,
149 0xC7F3F437UL,0x8DA1AC2DUL,0x80808000UL,0x0F131C1FUL,0xCAC2C80AUL,0x0C202C2CUL,0x8AA2A82AUL,0x04303434UL,
150 0xC2D2D012UL,0x0B03080BUL,0xCEE2EC2EUL,0xC9E1E829UL,0x4D515C1DUL,0x84909414UL,0x08101818UL,0xC8F0F838UL,
151 0x47535417UL,0x8EA2AC2EUL,0x08000808UL,0xC5C1C405UL,0x03131013UL,0xCDC1CC0DUL,0x86828406UL,0x89B1B839UL,
152 0xCFF3FC3FUL,0x4D717C3DUL,0xC1C1C001UL,0x01313031UL,0xC5F1F435UL,0x8A82880AUL,0x4A62682AUL,0x81B1B031UL,
153 0xC1D1D011UL,0x00202020UL,0xC7D3D417UL,0x02020002UL,0x02222022UL,0x04000404UL,0x48606828UL,0x41717031UL,
154 0x07030407UL,0xCBD3D81BUL,0x8D919C1DUL,0x89919819UL,0x41616021UL,0x8EB2BC3EUL,0xC6E2E426UL,0x49515819UL,
155 0xCDD1DC1DUL,0x41515011UL,0x80909010UL,0xCCD0DC1CUL,0x8A92981AUL,0x83A3A023UL,0x8BA3A82BUL,0xC0D0D010UL,
156 0x81818001UL,0x0F030C0FUL,0x47434407UL,0x0A12181AUL,0xC3E3E023UL,0xCCE0EC2CUL,0x8D818C0DUL,0x8FB3BC3FUL,
157 0x86929416UL,0x4B73783BUL,0x4C505C1CUL,0x82A2A022UL,0x81A1A021UL,0x43636023UL,0x03232023UL,0x4D414C0DUL,
158 0xC8C0C808UL,0x8E929C1EUL,0x8C909C1CUL,0x0A32383AUL,0x0C000C0CUL,0x0E222C2EUL,0x8AB2B83AUL,0x4E626C2EUL,
159 0x8F939C1FUL,0x4A52581AUL,0xC2F2F032UL,0x82929012UL,0xC3F3F033UL,0x49414809UL,0x48707838UL,0xCCC0CC0CUL,
160 0x05111415UL,0xCBF3F83BUL,0x40707030UL,0x45717435UL,0x4F737C3FUL,0x05313435UL,0x00101010UL,0x03030003UL,
161 0x44606424UL,0x4D616C2DUL,0xC6C2C406UL,0x44707434UL,0xC5D1D415UL,0x84B0B434UL,0xCAE2E82AUL,0x09010809UL,
162 0x46727436UL,0x09111819UL,0xCEF2FC3EUL,0x40404000UL,0x02121012UL,0xC0E0E020UL,0x8DB1BC3DUL,0x05010405UL,
163 0xCAF2F83AUL,0x01010001UL,0xC0F0F030UL,0x0A22282AUL,0x4E525C1EUL,0x89A1A829UL,0x46525416UL,0x43434003UL,
164 0x85818405UL,0x04101414UL,0x89818809UL,0x8B93981BUL,0x80B0B030UL,0xC5E1E425UL,0x48404808UL,0x49717839UL,
165 0x87939417UL,0xCCF0FC3CUL,0x0E121C1EUL,0x82828002UL,0x01212021UL,0x8C808C0CUL,0x0B13181BUL,0x4F535C1FUL,
166 0x47737437UL,0x44505414UL,0x82B2B032UL,0x0D111C1DUL,0x05212425UL,0x4F434C0FUL,0x00000000UL,0x46424406UL,
167 0xCDE1EC2DUL,0x48505818UL,0x42525012UL,0xCBE3E82BUL,0x4E727C3EUL,0xCAD2D81AUL,0xC9C1C809UL,0xCDF1FC3DUL,
168 0x00303030UL,0x85919415UL,0x45616425UL,0x0C303C3CUL,0x86B2B436UL,0xC4E0E424UL,0x8BB3B83BUL,0x4C707C3CUL,
169 0x0E020C0EUL,0x40505010UL,0x09313839UL,0x06222426UL,0x02323032UL,0x84808404UL,0x49616829UL,0x83939013UL,
170 0x07333437UL,0xC7E3E427UL,0x04202424UL,0x84A0A424UL,0xCBC3C80BUL,0x43535013UL,0x0A02080AUL,0x87838407UL,
171 0xC9D1D819UL,0x4C404C0CUL,0x83838003UL,0x8F838C0FUL,0xCEC2CC0EUL,0x0B33383BUL,0x4A42480AUL,0x87B3B437UL
172 };
173
174 static const ulong32 KCi[16] = {
175 0x9E3779B9,0x3C6EF373,
176 0x78DDE6E6,0xF1BBCDCC,
177 0xE3779B99,0xC6EF3733,
178 0x8DDE6E67,0x1BBCDCCF,
179 0x3779B99E,0x6EF3733C,
180 0xDDE6E678,0xBBCDCCF1,
181 0x779B99E3,0xEF3733C6,
182 0xDE6E678D,0xBCDCCF1B
183 };
184
185 #define G(x) (SS3[((x)>>24)&255] ^ SS2[((x)>>16)&255] ^ SS1[((x)>>8)&255] ^ SS0[(x)&255])
186
187 #define F(L1, L2, R1, R2, K1, K2) \
188 T2 = G((R1 ^ K1) ^ (R2 ^ K2)); \
189 T = G( G(T2 + (R1 ^ K1)) + T2); \
190 L2 ^= T; \
191 L1 ^= (T + G(T2 + (R1 ^ K1))); \
192
193 /**
194 Initialize the SEED block cipher
195 @param key The symmetric key you wish to pass
196 @param keylen The key length in bytes
197 @param num_rounds The number of rounds desired (0 for default)
198 @param skey The key in as scheduled by this function.
199 @return CRYPT_OK if successful
200 */
201 int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
202 {
203 int i;
204 ulong32 tmp, k1, k2, k3, k4;
205
206 if (keylen != 16) {
207 return CRYPT_INVALID_KEYSIZE;
208 }
209
210 if (num_rounds != 16 && num_rounds != 0) {
211 return CRYPT_INVALID_ROUNDS;
212 }
213
214 /* load key */
215 LOAD32H(k1, key);
216 LOAD32H(k2, key+4);
217 LOAD32H(k3, key+8);
218 LOAD32H(k4, key+12);
219
220 for (i = 0; i < 16; i++) {
221 skey->kseed.K[2*i+0] = G(k1 + k3 - KCi[i]);
222 skey->kseed.K[2*i+1] = G(k2 - k4 + KCi[i]);
223 if (i&1) {
224 tmp = k3;
225 k3 = ((k3 << 8) | (k4 >> 24)) & 0xFFFFFFFF;
226 k4 = ((k4 << 8) | (tmp >> 24)) & 0xFFFFFFFF;
227 } else {
228 tmp = k1;
229 k1 = ((k1 >> 8) | (k2 << 24)) & 0xFFFFFFFF;
230 k2 = ((k2 >> 8) | (tmp << 24)) & 0xFFFFFFFF;
231 }
232 /* reverse keys for decrypt */
233 skey->kseed.dK[2*(15-i)+0] = skey->kseed.K[2*i+0];
234 skey->kseed.dK[2*(15-i)+1] = skey->kseed.K[2*i+1];
235 }
236
237 return CRYPT_OK;
238 }
239
240 static void rounds(ulong32 *P, ulong32 *K)
241 {
242 ulong32 T, T2;
243 int i;
244 for (i = 0; i < 16; i += 2) {
245 F(P[0], P[1], P[2], P[3], K[0], K[1]);
246 F(P[2], P[3], P[0], P[1], K[2], K[3]);
247 K += 4;
248 }
249 }
250
251 /**
252 Encrypts a block of text with SEED
253 @param pt The input plaintext (16 bytes)
254 @param ct The output ciphertext (16 bytes)
255 @param skey The key as scheduled
256 @return CRYPT_OK if successful
257 */
258 int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
259 {
260 ulong32 P[4];
261 LOAD32H(P[0], pt);
262 LOAD32H(P[1], pt+4);
263 LOAD32H(P[2], pt+8);
264 LOAD32H(P[3], pt+12);
265 rounds(P, skey->kseed.K);
266 STORE32H(P[2], ct);
267 STORE32H(P[3], ct+4);
268 STORE32H(P[0], ct+8);
269 STORE32H(P[1], ct+12);
270 return CRYPT_OK;
271 }
272
273 /**
274 Decrypts a block of text with SEED
275 @param ct The input ciphertext (16 bytes)
276 @param pt The output plaintext (16 bytes)
277 @param skey The key as scheduled
278 @return CRYPT_OK if successful
279 */
280 int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
281 {
282 ulong32 P[4];
283 LOAD32H(P[0], ct);
284 LOAD32H(P[1], ct+4);
285 LOAD32H(P[2], ct+8);
286 LOAD32H(P[3], ct+12);
287 rounds(P, skey->kseed.dK);
288 STORE32H(P[2], pt);
289 STORE32H(P[3], pt+4);
290 STORE32H(P[0], pt+8);
291 STORE32H(P[1], pt+12);
292 return CRYPT_OK;
293 }
294
295 /** Terminate the context
296 @param skey The scheduled key
297 */
298 void kseed_done(symmetric_key *skey)
299 {
300 }
301
302 /**
303 Performs a self-test of the SEED block cipher
304 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
305 */
306 int kseed_test(void)
307 {
308 #if !defined(LTC_TEST)
309 return CRYPT_NOP;
310 #else
311 static const struct test {
312 unsigned char pt[16], ct[16], key[16];
313 } tests[] = {
314
315 {
316 { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
317 { 0x5E,0xBA,0xC6,0xE0,0x05,0x4E,0x16,0x68,0x19,0xAF,0xF1,0xCC,0x6D,0x34,0x6C,0xDB },
318 { 0 },
319 },
320
321 {
322 { 0 },
323 { 0xC1,0x1F,0x22,0xF2,0x01,0x40,0x50,0x50,0x84,0x48,0x35,0x97,0xE4,0x37,0x0F,0x43 },
324 { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
325 },
326
327 {
328 { 0x83,0xA2,0xF8,0xA2,0x88,0x64,0x1F,0xB9,0xA4,0xE9,0xA5,0xCC,0x2F,0x13,0x1C,0x7D },
329 { 0xEE,0x54,0xD1,0x3E,0xBC,0xAE,0x70,0x6D,0x22,0x6B,0xC3,0x14,0x2C,0xD4,0x0D,0x4A },
330 { 0x47,0x06,0x48,0x08,0x51,0xE6,0x1B,0xE8,0x5D,0x74,0xBF,0xB3,0xFD,0x95,0x61,0x85 },
331 },
332
333 {
334 { 0xB4,0x1E,0x6B,0xE2,0xEB,0xA8,0x4A,0x14,0x8E,0x2E,0xED,0x84,0x59,0x3C,0x5E,0xC7 },
335 { 0x9B,0x9B,0x7B,0xFC,0xD1,0x81,0x3C,0xB9,0x5D,0x0B,0x36,0x18,0xF4,0x0F,0x51,0x22 },
336 { 0x28,0xDB,0xC3,0xBC,0x49,0xFF,0xD8,0x7D,0xCF,0xA5,0x09,0xB1,0x1D,0x42,0x2B,0xE7 },
337 }
338 };
339 int x;
340 unsigned char buf[2][16];
341 symmetric_key skey;
342
343 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
344 kseed_setup(tests[x].key, 16, 0, &skey);
345 kseed_ecb_encrypt(tests[x].pt, buf[0], &skey);
346 kseed_ecb_decrypt(buf[0], buf[1], &skey);
347 if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) {
348 #if 0
349 int i, j;
350 printf ("\n\nLTC_KSEED failed for x=%d, I got:\n", x);
351 for (i = 0; i < 2; i++) {
352 const unsigned char *expected, *actual;
353 expected = (i ? tests[x].pt : tests[x].ct);
354 actual = buf[i];
355 printf ("expected actual (%s)\n", (i ? "plaintext" : "ciphertext"));
356 for (j = 0; j < 16; j++) {
357 const char *eq = (expected[j] == actual[j] ? "==" : "!=");
358 printf (" %02x %s %02x\n", expected[j], eq, actual[j]);
359 }
360 printf ("\n");
361 }
362 #endif
363 return CRYPT_FAIL_TESTVECTOR;
364 }
365 }
366 return CRYPT_OK;
367 #endif
368 }
369
370 /**
371 Gets suitable key size
372 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
373 @return CRYPT_OK if the input key size is acceptable.
374 */
375 int kseed_keysize(int *keysize)
376 {
377 LTC_ARGCHK(keysize != NULL);
378 if (*keysize >= 16) {
379 *keysize = 16;
380 } else {
381 return CRYPT_INVALID_KEYSIZE;
382 }
383 return CRYPT_OK;
384 }
385
386 #endif
387
388 /* $Source$ */
389 /* $Revision$ */
390 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file multi2.c
13 Multi-2 implementation (not public domain, hence the default disable)
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_MULTI2
18
19 static void pi1(ulong32 *p)
20 {
21 p[1] ^= p[0];
22 }
23
24 static void pi2(ulong32 *p, ulong32 *k)
25 {
26 ulong32 t;
27 t = (p[1] + k[0]) & 0xFFFFFFFFUL;
28 t = (ROL(t, 1) + t - 1) & 0xFFFFFFFFUL;
29 t = (ROL(t, 4) ^ t) & 0xFFFFFFFFUL;
30 p[0] ^= t;
31 }
32
33 static void pi3(ulong32 *p, ulong32 *k)
34 {
35 ulong32 t;
36 t = p[0] + k[1];
37 t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL;
38 t = (ROL(t, 8) ^ t) & 0xFFFFFFFFUL;
39 t = (t + k[2]) & 0xFFFFFFFFUL;
40 t = (ROL(t, 1) - t) & 0xFFFFFFFFUL;
41 t = ROL(t, 16) ^ (p[0] | t);
42 p[1] ^= t;
43 }
44
45 static void pi4(ulong32 *p, ulong32 *k)
46 {
47 ulong32 t;
48 t = (p[1] + k[3]) & 0xFFFFFFFFUL;
49 t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL;
50 p[0] ^= t;
51 }
52
53 static void setup(ulong32 *dk, ulong32 *k, ulong32 *uk)
54 {
55 int n, t;
56 ulong32 p[2];
57
58 p[0] = dk[0]; p[1] = dk[1];
59
60 t = 4;
61 n = 0;
62 pi1(p);
63 pi2(p, k);
64 uk[n++] = p[0];
65 pi3(p, k);
66 uk[n++] = p[1];
67 pi4(p, k);
68 uk[n++] = p[0];
69 pi1(p);
70 uk[n++] = p[1];
71 pi2(p, k+t);
72 uk[n++] = p[0];
73 pi3(p, k+t);
74 uk[n++] = p[1];
75 pi4(p, k+t);
76 uk[n++] = p[0];
77 pi1(p);
78 uk[n++] = p[1];
79 }
80
81 static void encrypt(ulong32 *p, int N, ulong32 *uk)
82 {
83 int n, t;
84 for (t = n = 0; ; ) {
85 pi1(p); if (++n == N) break;
86 pi2(p, uk+t); if (++n == N) break;
87 pi3(p, uk+t); if (++n == N) break;
88 pi4(p, uk+t); if (++n == N) break;
89 t ^= 4;
90 }
91 }
92
93 static void decrypt(ulong32 *p, int N, ulong32 *uk)
94 {
95 int n, t;
96 for (t = 4*(((N-1)>>2)&1), n = N; ; ) {
97 switch (n<=4 ? n : ((n-1)%4)+1) {
98 case 4: pi4(p, uk+t); --n;
99 case 3: pi3(p, uk+t); --n;
100 case 2: pi2(p, uk+t); --n;
101 case 1: pi1(p); --n; break;
102 case 0: return;
103 }
104 t ^= 4;
105 }
106 }
107
108 const struct ltc_cipher_descriptor multi2_desc = {
109 "multi2",
110 22,
111 40, 40, 8, 128,
112 &multi2_setup,
113 &multi2_ecb_encrypt,
114 &multi2_ecb_decrypt,
115 &multi2_test,
116 &multi2_done,
117 &multi2_keysize,
118 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
119 };
120
121 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
122 {
123 ulong32 sk[8], dk[2];
124 int x;
125
126 LTC_ARGCHK(key != NULL);
127 LTC_ARGCHK(skey != NULL);
128
129 if (keylen != 40) return CRYPT_INVALID_KEYSIZE;
130 if (num_rounds == 0) num_rounds = 128;
131
132 skey->multi2.N = num_rounds;
133 for (x = 0; x < 8; x++) {
134 LOAD32H(sk[x], key + x*4);
135 }
136 LOAD32H(dk[0], key + 32);
137 LOAD32H(dk[1], key + 36);
138 setup(dk, sk, skey->multi2.uk);
139
140 zeromem(sk, sizeof(sk));
141 zeromem(dk, sizeof(dk));
142 return CRYPT_OK;
143 }
144
145 /**
146 Encrypts a block of text with multi2
147 @param pt The input plaintext (8 bytes)
148 @param ct The output ciphertext (8 bytes)
149 @param skey The key as scheduled
150 @return CRYPT_OK if successful
151 */
152 int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
153 {
154 ulong32 p[2];
155 LTC_ARGCHK(pt != NULL);
156 LTC_ARGCHK(ct != NULL);
157 LTC_ARGCHK(skey != NULL);
158 LOAD32H(p[0], pt);
159 LOAD32H(p[1], pt+4);
160 encrypt(p, skey->multi2.N, skey->multi2.uk);
161 STORE32H(p[0], ct);
162 STORE32H(p[1], ct+4);
163 return CRYPT_OK;
164 }
165
166 /**
167 Decrypts a block of text with multi2
168 @param ct The input ciphertext (8 bytes)
169 @param pt The output plaintext (8 bytes)
170 @param skey The key as scheduled
171 @return CRYPT_OK if successful
172 */
173 int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
174 {
175 ulong32 p[2];
176 LTC_ARGCHK(pt != NULL);
177 LTC_ARGCHK(ct != NULL);
178 LTC_ARGCHK(skey != NULL);
179 LOAD32H(p[0], ct);
180 LOAD32H(p[1], ct+4);
181 decrypt(p, skey->multi2.N, skey->multi2.uk);
182 STORE32H(p[0], pt);
183 STORE32H(p[1], pt+4);
184 return CRYPT_OK;
185 }
186
187 /**
188 Performs a self-test of the multi2 block cipher
189 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
190 */
191 int multi2_test(void)
192 {
193 static const struct {
194 unsigned char key[40];
195 unsigned char pt[8], ct[8];
196 int rounds;
197 } tests[] = {
198 {
199 {
200 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00,
204
205 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00,
209
210 0x01, 0x23, 0x45, 0x67,
211 0x89, 0xAB, 0xCD, 0xEF
212 },
213 {
214 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x01,
216 },
217 {
218 0xf8, 0x94, 0x40, 0x84,
219 0x5e, 0x11, 0xcf, 0x89
220 },
221 128,
222 },
223 {
224 {
225 0x35, 0x91, 0x9d, 0x96,
226 0x07, 0x02, 0xe2, 0xce,
227 0x8d, 0x0b, 0x58, 0x3c,
228 0xc9, 0xc8, 0x9d, 0x59,
229 0xa2, 0xae, 0x96, 0x4e,
230 0x87, 0x82, 0x45, 0xed,
231 0x3f, 0x2e, 0x62, 0xd6,
232 0x36, 0x35, 0xd0, 0x67,
233
234 0xb1, 0x27, 0xb9, 0x06,
235 0xe7, 0x56, 0x22, 0x38,
236 },
237 {
238 0x1f, 0xb4, 0x60, 0x60,
239 0xd0, 0xb3, 0x4f, 0xa5
240 },
241 {
242 0xca, 0x84, 0xa9, 0x34,
243 0x75, 0xc8, 0x60, 0xe5
244 },
245 216,
246 }
247 };
248 unsigned char buf[8];
249 symmetric_key skey;
250 int err, x;
251
252 for (x = 1; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
253 if ((err = multi2_setup(tests[x].key, 40, tests[x].rounds, &skey)) != CRYPT_OK) {
254 return err;
255 }
256 if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) {
257 return err;
258 }
259
260 if (XMEMCMP(buf, tests[x].ct, 8)) {
261 return CRYPT_FAIL_TESTVECTOR;
262 }
263
264 if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) {
265 return err;
266 }
267 if (XMEMCMP(buf, tests[x].pt, 8)) {
268 return CRYPT_FAIL_TESTVECTOR;
269 }
270 }
271
272 for (x = 128; x < 256; ++x) {
273 unsigned char ct[8];
274
275 if ((err = multi2_setup(tests[0].key, 40, x, &skey)) != CRYPT_OK) {
276 return err;
277 }
278 if ((err = multi2_ecb_encrypt(tests[0].pt, ct, &skey)) != CRYPT_OK) {
279 return err;
280 }
281 if ((err = multi2_ecb_decrypt(ct, buf, &skey)) != CRYPT_OK) {
282 return err;
283 }
284 if (XMEMCMP(buf, tests[0].pt, 8)) {
285 return CRYPT_FAIL_TESTVECTOR;
286 }
287 }
288
289 return CRYPT_OK;
290 }
291
292 /** Terminate the context
293 @param skey The scheduled key
294 */
295 void multi2_done(symmetric_key *skey)
296 {
297 }
298
299 /**
300 Gets suitable key size
301 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
302 @return CRYPT_OK if the input key size is acceptable.
303 */
304 int multi2_keysize(int *keysize)
305 {
306 LTC_ARGCHK(keysize != NULL);
307 if (*keysize >= 40) {
308 *keysize = 40;
309 } else {
310 return CRYPT_INVALID_KEYSIZE;
311 }
312 return CRYPT_OK;
313 }
314
315 #endif
316
317 /* $Source$ */
318 /* $Revision$ */
319 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @file noekeon.c
12 Implementation of the Noekeon block cipher by Tom St Denis
13 */
14 #include "tomcrypt.h"
15
16 #ifdef LTC_NOEKEON
17
18 const struct ltc_cipher_descriptor noekeon_desc =
19 {
20 "noekeon",
21 16,
22 16, 16, 16, 16,
23 &noekeon_setup,
24 &noekeon_ecb_encrypt,
25 &noekeon_ecb_decrypt,
26 &noekeon_test,
27 &noekeon_done,
28 &noekeon_keysize,
29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
30 };
31
32 static const ulong32 RC[] = {
33 0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL,
34 0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL,
35 0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL,
36 0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL,
37 0x000000d4UL
38 };
39
40 #define kTHETA(a, b, c, d) \
41 temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
42 b ^= temp; d ^= temp; \
43 temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
44 a ^= temp; c ^= temp;
45
46 #define THETA(k, a, b, c, d) \
47 temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
48 b ^= temp ^ k[1]; d ^= temp ^ k[3]; \
49 temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
50 a ^= temp ^ k[0]; c ^= temp ^ k[2];
51
52 #define GAMMA(a, b, c, d) \
53 b ^= ~(d|c); \
54 a ^= c&b; \
55 temp = d; d = a; a = temp;\
56 c ^= a ^ b ^ d; \
57 b ^= ~(d|c); \
58 a ^= c&b;
59
60 #define PI1(a, b, c, d) \
61 b = ROLc(b, 1); c = ROLc(c, 5); d = ROLc(d, 2);
62
63 #define PI2(a, b, c, d) \
64 b = RORc(b, 1); c = RORc(c, 5); d = RORc(d, 2);
65
66 /**
67 Initialize the Noekeon block cipher
68 @param key The symmetric key you wish to pass
69 @param keylen The key length in bytes
70 @param num_rounds The number of rounds desired (0 for default)
71 @param skey The key in as scheduled by this function.
72 @return CRYPT_OK if successful
73 */
74 int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
75 {
76 ulong32 temp;
77
78 LTC_ARGCHK(key != NULL);
79 LTC_ARGCHK(skey != NULL);
80
81 if (keylen != 16) {
82 return CRYPT_INVALID_KEYSIZE;
83 }
84
85 if (num_rounds != 16 && num_rounds != 0) {
86 return CRYPT_INVALID_ROUNDS;
87 }
88
89 LOAD32H(skey->noekeon.K[0],&key[0]);
90 LOAD32H(skey->noekeon.K[1],&key[4]);
91 LOAD32H(skey->noekeon.K[2],&key[8]);
92 LOAD32H(skey->noekeon.K[3],&key[12]);
93
94 LOAD32H(skey->noekeon.dK[0],&key[0]);
95 LOAD32H(skey->noekeon.dK[1],&key[4]);
96 LOAD32H(skey->noekeon.dK[2],&key[8]);
97 LOAD32H(skey->noekeon.dK[3],&key[12]);
98
99 kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]);
100
101 return CRYPT_OK;
102 }
103
104 /**
105 Encrypts a block of text with Noekeon
106 @param pt The input plaintext (16 bytes)
107 @param ct The output ciphertext (16 bytes)
108 @param skey The key as scheduled
109 @return CRYPT_OK if successful
110 */
111 #ifdef LTC_CLEAN_STACK
112 static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
113 #else
114 int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
115 #endif
116 {
117 ulong32 a,b,c,d,temp;
118 int r;
119
120 LTC_ARGCHK(skey != NULL);
121 LTC_ARGCHK(pt != NULL);
122 LTC_ARGCHK(ct != NULL);
123
124 LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]);
125 LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]);
126
127 #define ROUND(i) \
128 a ^= RC[i]; \
129 THETA(skey->noekeon.K, a,b,c,d); \
130 PI1(a,b,c,d); \
131 GAMMA(a,b,c,d); \
132 PI2(a,b,c,d);
133
134 for (r = 0; r < 16; ++r) {
135 ROUND(r);
136 }
137
138 #undef ROUND
139
140 a ^= RC[16];
141 THETA(skey->noekeon.K, a, b, c, d);
142
143 STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
144 STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
145
146 return CRYPT_OK;
147 }
148
149 #ifdef LTC_CLEAN_STACK
150 int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
151 {
152 int err = _noekeon_ecb_encrypt(pt, ct, skey);
153 burn_stack(sizeof(ulong32) * 5 + sizeof(int));
154 return err;
155 }
156 #endif
157
158 /**
159 Decrypts a block of text with Noekeon
160 @param ct The input ciphertext (16 bytes)
161 @param pt The output plaintext (16 bytes)
162 @param skey The key as scheduled
163 @return CRYPT_OK if successful
164 */
165 #ifdef LTC_CLEAN_STACK
166 static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
167 #else
168 int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
169 #endif
170 {
171 ulong32 a,b,c,d, temp;
172 int r;
173
174 LTC_ARGCHK(skey != NULL);
175 LTC_ARGCHK(pt != NULL);
176 LTC_ARGCHK(ct != NULL);
177
178 LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]);
179 LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]);
180
181
182 #define ROUND(i) \
183 THETA(skey->noekeon.dK, a,b,c,d); \
184 a ^= RC[i]; \
185 PI1(a,b,c,d); \
186 GAMMA(a,b,c,d); \
187 PI2(a,b,c,d);
188
189 for (r = 16; r > 0; --r) {
190 ROUND(r);
191 }
192
193 #undef ROUND
194
195 THETA(skey->noekeon.dK, a,b,c,d);
196 a ^= RC[0];
197 STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
198 STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
199 return CRYPT_OK;
200 }
201
202 #ifdef LTC_CLEAN_STACK
203 int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
204 {
205 int err = _noekeon_ecb_decrypt(ct, pt, skey);
206 burn_stack(sizeof(ulong32) * 5 + sizeof(int));
207 return err;
208 }
209 #endif
210
211 /**
212 Performs a self-test of the Noekeon block cipher
213 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
214 */
215 int noekeon_test(void)
216 {
217 #ifndef LTC_TEST
218 return CRYPT_NOP;
219 #else
220 static const struct {
221 int keylen;
222 unsigned char key[16], pt[16], ct[16];
223 } tests[] = {
224 {
225 16,
226 { 0xAA, 0x3C, 0x8C, 0x86, 0xD9, 0x8B, 0xF8, 0xBE, 0x21, 0xE0, 0x36, 0x09, 0x78, 0xFB, 0xE4, 0x90 },
227 { 0xE4, 0x96, 0x6C, 0xD3, 0x13, 0xA0, 0x6C, 0xAF, 0xD0, 0x23, 0xC9, 0xFD, 0x45, 0x32, 0x23, 0x16 },
228 { 0xA6, 0xEC, 0xB8, 0xA8, 0x61, 0xFD, 0x62, 0xD9, 0x13, 0x02, 0xFE, 0x9E, 0x47, 0x01, 0x3F, 0xC3 }
229 },
230 {
231 16,
232 { 0xED, 0x43, 0xD1, 0x87, 0x21, 0x7E, 0xE0, 0x97, 0x3D, 0x76, 0xC3, 0x37, 0x2E, 0x7D, 0xAE, 0xD3 },
233 { 0xE3, 0x38, 0x32, 0xCC, 0xF2, 0x2F, 0x2F, 0x0A, 0x4A, 0x8B, 0x8F, 0x18, 0x12, 0x20, 0x17, 0xD3 },
234 { 0x94, 0xA5, 0xDF, 0xF5, 0xAE, 0x1C, 0xBB, 0x22, 0xAD, 0xEB, 0xA7, 0x0D, 0xB7, 0x82, 0x90, 0xA0 }
235 },
236 {
237 16,
238 { 0x6F, 0xDC, 0x23, 0x38, 0xF2, 0x10, 0xFB, 0xD3, 0xC1, 0x8C, 0x02, 0xF6, 0xB4, 0x6A, 0xD5, 0xA8 },
239 { 0xDB, 0x29, 0xED, 0xB5, 0x5F, 0xB3, 0x60, 0x3A, 0x92, 0xA8, 0xEB, 0x9C, 0x6D, 0x9D, 0x3E, 0x8F },
240 { 0x78, 0xF3, 0x6F, 0xF8, 0x9E, 0xBB, 0x8C, 0x6A, 0xE8, 0x10, 0xF7, 0x00, 0x22, 0x15, 0x30, 0x3D }
241 },
242 {
243 16,
244 { 0x2C, 0x0C, 0x02, 0xEF, 0x6B, 0xC4, 0xF2, 0x0B, 0x2E, 0xB9, 0xE0, 0xBF, 0xD9, 0x36, 0xC2, 0x4E },
245 { 0x84, 0xE2, 0xFE, 0x64, 0xB1, 0xB9, 0xFE, 0x76, 0xA8, 0x3F, 0x45, 0xC7, 0x40, 0x7A, 0xAF, 0xEE },
246 { 0x2A, 0x08, 0xD6, 0xA2, 0x1C, 0x63, 0x08, 0xB0, 0xF8, 0xBC, 0xB3, 0xA1, 0x66, 0xF7, 0xAE, 0xCF }
247 },
248 {
249 16,
250 { 0x6F, 0x30, 0xF8, 0x9F, 0xDA, 0x6E, 0xA0, 0x91, 0x04, 0x0F, 0x6C, 0x8B, 0x7D, 0xF7, 0x2A, 0x4B },
251 { 0x65, 0xB6, 0xA6, 0xD0, 0x42, 0x14, 0x08, 0x60, 0x34, 0x8D, 0x37, 0x2F, 0x01, 0xF0, 0x46, 0xBE },
252 { 0x66, 0xAC, 0x0B, 0x62, 0x1D, 0x68, 0x11, 0xF5, 0x27, 0xB1, 0x13, 0x5D, 0xF3, 0x2A, 0xE9, 0x18 }
253 },
254 {
255 16,
256 { 0xCA, 0xA4, 0x16, 0xB7, 0x1C, 0x92, 0x2E, 0xAD, 0xEB, 0xA7, 0xDB, 0x69, 0x92, 0xCB, 0x35, 0xEF },
257 { 0x81, 0x6F, 0x8E, 0x4D, 0x96, 0xC6, 0xB3, 0x67, 0x83, 0xF5, 0x63, 0xC7, 0x20, 0x6D, 0x40, 0x23 },
258 { 0x44, 0xF7, 0x63, 0x62, 0xF0, 0x43, 0xBB, 0x67, 0x4A, 0x75, 0x12, 0x42, 0x46, 0x29, 0x28, 0x19 }
259 },
260 {
261 16,
262 { 0x6B, 0xCF, 0x22, 0x2F, 0xE0, 0x1B, 0xB0, 0xAA, 0xD8, 0x3C, 0x91, 0x99, 0x18, 0xB2, 0x28, 0xE8 },
263 { 0x7C, 0x37, 0xC7, 0xD0, 0xAC, 0x92, 0x29, 0xF1, 0x60, 0x82, 0x93, 0x89, 0xAA, 0x61, 0xAA, 0xA9 },
264 { 0xE5, 0x89, 0x1B, 0xB3, 0xFE, 0x8B, 0x0C, 0xA1, 0xA6, 0xC7, 0xBE, 0x12, 0x73, 0x0F, 0xC1, 0x19 }
265 },
266 {
267 16,
268 { 0xE6, 0xD0, 0xF1, 0x03, 0x2E, 0xDE, 0x70, 0x8D, 0xD8, 0x9E, 0x36, 0x5C, 0x05, 0x52, 0xE7, 0x0D },
269 { 0xE2, 0x42, 0xE7, 0x92, 0x0E, 0xF7, 0x82, 0xA2, 0xB8, 0x21, 0x8D, 0x26, 0xBA, 0x2D, 0xE6, 0x32 },
270 { 0x1E, 0xDD, 0x75, 0x22, 0xB9, 0x36, 0x8A, 0x0F, 0x32, 0xFD, 0xD4, 0x48, 0x65, 0x12, 0x5A, 0x2F }
271 }
272 };
273 symmetric_key key;
274 unsigned char tmp[2][16];
275 int err, i, y;
276
277 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
278 zeromem(&key, sizeof(key));
279 if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
280 return err;
281 }
282
283 noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key);
284 noekeon_ecb_decrypt(tmp[0], tmp[1], &key);
285 if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
286 #if 0
287 printf("\n\nTest %d failed\n", i);
288 if (XMEMCMP(tmp[0], tests[i].ct, 16)) {
289 printf("CT: ");
290 for (i = 0; i < 16; i++) {
291 printf("%02x ", tmp[0][i]);
292 }
293 printf("\n");
294 } else {
295 printf("PT: ");
296 for (i = 0; i < 16; i++) {
297 printf("%02x ", tmp[1][i]);
298 }
299 printf("\n");
300 }
301 #endif
302 return CRYPT_FAIL_TESTVECTOR;
303 }
304
305 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
306 for (y = 0; y < 16; y++) tmp[0][y] = 0;
307 for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key);
308 for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key);
309 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
310 }
311 return CRYPT_OK;
312 #endif
313 }
314
315 /** Terminate the context
316 @param skey The scheduled key
317 */
318 void noekeon_done(symmetric_key *skey)
319 {
320 }
321
322 /**
323 Gets suitable key size
324 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
325 @return CRYPT_OK if the input key size is acceptable.
326 */
327 int noekeon_keysize(int *keysize)
328 {
329 LTC_ARGCHK(keysize != NULL);
330 if (*keysize < 16) {
331 return CRYPT_INVALID_KEYSIZE;
332 } else {
333 *keysize = 16;
334 return CRYPT_OK;
335 }
336 }
337
338 #endif
339
340
341 /* $Source$ */
342 /* $Revision$ */
343 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**********************************************************************\
11 * To commemorate the 1996 RSA Data Security Conference, the following *
12 * code is released into the public domain by its author. Prost! *
13 * *
14 * This cipher uses 16-bit words and little-endian byte ordering. *
15 * I wonder which processor it was optimized for? *
16 * *
17 * Thanks to CodeView, SoftIce, and D86 for helping bring this code to *
18 * the public. *
19 \**********************************************************************/
20 #include <tomcrypt.h>
21
22 /**
23 @file rc2.c
24 Implementation of LTC_RC2
25 */
26
27 #ifdef LTC_RC2
28
29 const struct ltc_cipher_descriptor rc2_desc = {
30 "rc2",
31 12, 8, 128, 8, 16,
32 &rc2_setup,
33 &rc2_ecb_encrypt,
34 &rc2_ecb_decrypt,
35 &rc2_test,
36 &rc2_done,
37 &rc2_keysize,
38 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
39 };
40
41 /* 256-entry permutation table, probably derived somehow from pi */
42 static const unsigned char permute[256] = {
43 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
44 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
45 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
46 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
47 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
48 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
49 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
50 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
51 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
52 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
53 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
54 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
55 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
56 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
57 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
58 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
59 };
60
61 /**
62 Initialize the LTC_RC2 block cipher
63 @param key The symmetric key you wish to pass
64 @param keylen The key length in bytes
65 @param num_rounds The number of rounds desired (0 for default)
66 @param skey The key in as scheduled by this function.
67 @return CRYPT_OK if successful
68 */
69 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
70 {
71 unsigned *xkey = skey->rc2.xkey;
72 unsigned char tmp[128];
73 unsigned T8, TM;
74 int i, bits;
75
76 LTC_ARGCHK(key != NULL);
77 LTC_ARGCHK(skey != NULL);
78
79 if (keylen < 8 || keylen > 128) {
80 return CRYPT_INVALID_KEYSIZE;
81 }
82
83 if (num_rounds != 0 && num_rounds != 16) {
84 return CRYPT_INVALID_ROUNDS;
85 }
86
87 for (i = 0; i < keylen; i++) {
88 tmp[i] = key[i] & 255;
89 }
90
91 /* Phase 1: Expand input key to 128 bytes */
92 if (keylen < 128) {
93 for (i = keylen; i < 128; i++) {
94 tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255];
95 }
96 }
97
98 /* Phase 2 - reduce effective key size to "bits" */
99 bits = keylen<<3;
100 T8 = (unsigned)(bits+7)>>3;
101 TM = (255 >> (unsigned)(7 & -bits));
102 tmp[128 - T8] = permute[tmp[128 - T8] & TM];
103 for (i = 127 - T8; i >= 0; i--) {
104 tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]];
105 }
106
107 /* Phase 3 - copy to xkey in little-endian order */
108 for (i = 0; i < 64; i++) {
109 xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8);
110 }
111
112 #ifdef LTC_CLEAN_STACK
113 zeromem(tmp, sizeof(tmp));
114 #endif
115
116 return CRYPT_OK;
117 }
118
119 /**********************************************************************\
120 * Encrypt an 8-byte block of plaintext using the given key. *
121 \**********************************************************************/
122 /**
123 Encrypts a block of text with LTC_RC2
124 @param pt The input plaintext (8 bytes)
125 @param ct The output ciphertext (8 bytes)
126 @param skey The key as scheduled
127 @return CRYPT_OK if successful
128 */
129 #ifdef LTC_CLEAN_STACK
130 static int _rc2_ecb_encrypt( const unsigned char *pt,
131 unsigned char *ct,
132 symmetric_key *skey)
133 #else
134 int rc2_ecb_encrypt( const unsigned char *pt,
135 unsigned char *ct,
136 symmetric_key *skey)
137 #endif
138 {
139 unsigned *xkey;
140 unsigned x76, x54, x32, x10, i;
141
142 LTC_ARGCHK(pt != NULL);
143 LTC_ARGCHK(ct != NULL);
144 LTC_ARGCHK(skey != NULL);
145
146 xkey = skey->rc2.xkey;
147
148 x76 = ((unsigned)pt[7] << 8) + (unsigned)pt[6];
149 x54 = ((unsigned)pt[5] << 8) + (unsigned)pt[4];
150 x32 = ((unsigned)pt[3] << 8) + (unsigned)pt[2];
151 x10 = ((unsigned)pt[1] << 8) + (unsigned)pt[0];
152
153 for (i = 0; i < 16; i++) {
154 x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF;
155 x10 = ((x10 << 1) | (x10 >> 15));
156
157 x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF;
158 x32 = ((x32 << 2) | (x32 >> 14));
159
160 x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF;
161 x54 = ((x54 << 3) | (x54 >> 13));
162
163 x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF;
164 x76 = ((x76 << 5) | (x76 >> 11));
165
166 if (i == 4 || i == 10) {
167 x10 = (x10 + xkey[x76 & 63]) & 0xFFFF;
168 x32 = (x32 + xkey[x10 & 63]) & 0xFFFF;
169 x54 = (x54 + xkey[x32 & 63]) & 0xFFFF;
170 x76 = (x76 + xkey[x54 & 63]) & 0xFFFF;
171 }
172 }
173
174 ct[0] = (unsigned char)x10;
175 ct[1] = (unsigned char)(x10 >> 8);
176 ct[2] = (unsigned char)x32;
177 ct[3] = (unsigned char)(x32 >> 8);
178 ct[4] = (unsigned char)x54;
179 ct[5] = (unsigned char)(x54 >> 8);
180 ct[6] = (unsigned char)x76;
181 ct[7] = (unsigned char)(x76 >> 8);
182
183 return CRYPT_OK;
184 }
185
186 #ifdef LTC_CLEAN_STACK
187 int rc2_ecb_encrypt( const unsigned char *pt,
188 unsigned char *ct,
189 symmetric_key *skey)
190 {
191 int err = _rc2_ecb_encrypt(pt, ct, skey);
192 burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
193 return err;
194 }
195 #endif
196
197 /**********************************************************************\
198 * Decrypt an 8-byte block of ciphertext using the given key. *
199 \**********************************************************************/
200 /**
201 Decrypts a block of text with LTC_RC2
202 @param ct The input ciphertext (8 bytes)
203 @param pt The output plaintext (8 bytes)
204 @param skey The key as scheduled
205 @return CRYPT_OK if successful
206 */
207 #ifdef LTC_CLEAN_STACK
208 static int _rc2_ecb_decrypt( const unsigned char *ct,
209 unsigned char *pt,
210 symmetric_key *skey)
211 #else
212 int rc2_ecb_decrypt( const unsigned char *ct,
213 unsigned char *pt,
214 symmetric_key *skey)
215 #endif
216 {
217 unsigned x76, x54, x32, x10;
218 unsigned *xkey;
219 int i;
220
221 LTC_ARGCHK(pt != NULL);
222 LTC_ARGCHK(ct != NULL);
223 LTC_ARGCHK(skey != NULL);
224
225 xkey = skey->rc2.xkey;
226
227 x76 = ((unsigned)ct[7] << 8) + (unsigned)ct[6];
228 x54 = ((unsigned)ct[5] << 8) + (unsigned)ct[4];
229 x32 = ((unsigned)ct[3] << 8) + (unsigned)ct[2];
230 x10 = ((unsigned)ct[1] << 8) + (unsigned)ct[0];
231
232 for (i = 15; i >= 0; i--) {
233 if (i == 4 || i == 10) {
234 x76 = (x76 - xkey[x54 & 63]) & 0xFFFF;
235 x54 = (x54 - xkey[x32 & 63]) & 0xFFFF;
236 x32 = (x32 - xkey[x10 & 63]) & 0xFFFF;
237 x10 = (x10 - xkey[x76 & 63]) & 0xFFFF;
238 }
239
240 x76 = ((x76 << 11) | (x76 >> 5));
241 x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF;
242
243 x54 = ((x54 << 13) | (x54 >> 3));
244 x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF;
245
246 x32 = ((x32 << 14) | (x32 >> 2));
247 x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF;
248
249 x10 = ((x10 << 15) | (x10 >> 1));
250 x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF;
251 }
252
253 pt[0] = (unsigned char)x10;
254 pt[1] = (unsigned char)(x10 >> 8);
255 pt[2] = (unsigned char)x32;
256 pt[3] = (unsigned char)(x32 >> 8);
257 pt[4] = (unsigned char)x54;
258 pt[5] = (unsigned char)(x54 >> 8);
259 pt[6] = (unsigned char)x76;
260 pt[7] = (unsigned char)(x76 >> 8);
261
262 return CRYPT_OK;
263 }
264
265 #ifdef LTC_CLEAN_STACK
266 int rc2_ecb_decrypt( const unsigned char *ct,
267 unsigned char *pt,
268 symmetric_key *skey)
269 {
270 int err = _rc2_ecb_decrypt(ct, pt, skey);
271 burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
272 return err;
273 }
274 #endif
275
276 /**
277 Performs a self-test of the LTC_RC2 block cipher
278 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
279 */
280 int rc2_test(void)
281 {
282 #ifndef LTC_TEST
283 return CRYPT_NOP;
284 #else
285 static const struct {
286 int keylen;
287 unsigned char key[16], pt[8], ct[8];
288 } tests[] = {
289
290 { 8,
291 { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
293 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
294 { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 }
295
296 },
297 { 16,
298 { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
299 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 },
300 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
301 { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 }
302 }
303 };
304 int x, y, err;
305 symmetric_key skey;
306 unsigned char tmp[2][8];
307
308 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
309 zeromem(tmp, sizeof(tmp));
310 if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
311 return err;
312 }
313
314 rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey);
315 rc2_ecb_decrypt(tmp[0], tmp[1], &skey);
316
317 if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) {
318 return CRYPT_FAIL_TESTVECTOR;
319 }
320
321 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
322 for (y = 0; y < 8; y++) tmp[0][y] = 0;
323 for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey);
324 for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey);
325 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
326 }
327 return CRYPT_OK;
328 #endif
329 }
330
331 /** Terminate the context
332 @param skey The scheduled key
333 */
334 void rc2_done(symmetric_key *skey)
335 {
336 }
337
338 /**
339 Gets suitable key size
340 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
341 @return CRYPT_OK if the input key size is acceptable.
342 */
343 int rc2_keysize(int *keysize)
344 {
345 LTC_ARGCHK(keysize != NULL);
346 if (*keysize < 8) {
347 return CRYPT_INVALID_KEYSIZE;
348 } else if (*keysize > 128) {
349 *keysize = 128;
350 }
351 return CRYPT_OK;
352 }
353
354 #endif
355
356
357
358
359 /* $Source$ */
360 /* $Revision$ */
361 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file rc5.c
13 LTC_RC5 code by Tom St Denis
14 */
15
16 #include "tomcrypt.h"
17
18 #ifdef LTC_RC5
19
20 const struct ltc_cipher_descriptor rc5_desc =
21 {
22 "rc5",
23 2,
24 8, 128, 8, 12,
25 &rc5_setup,
26 &rc5_ecb_encrypt,
27 &rc5_ecb_decrypt,
28 &rc5_test,
29 &rc5_done,
30 &rc5_keysize,
31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
32 };
33
34 static const ulong32 stab[50] = {
35 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL,
36 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL,
37 0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL,
38 0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL,
39 0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL,
40 0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL, 0xe96a3d2fUL, 0x87a1b6e8UL, 0x25d930a1UL, 0xc410aa5aUL,
41 0x62482413UL, 0x007f9dccUL
42 };
43
44 /**
45 Initialize the LTC_RC5 block cipher
46 @param key The symmetric key you wish to pass
47 @param keylen The key length in bytes
48 @param num_rounds The number of rounds desired (0 for default)
49 @param skey The key in as scheduled by this function.
50 @return CRYPT_OK if successful
51 */
52 #ifdef LTC_CLEAN_STACK
53 static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
54 #else
55 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
56 #endif
57 {
58 ulong32 L[64], *S, A, B, i, j, v, s, t, l;
59
60 LTC_ARGCHK(skey != NULL);
61 LTC_ARGCHK(key != NULL);
62
63 /* test parameters */
64 if (num_rounds == 0) {
65 num_rounds = rc5_desc.default_rounds;
66 }
67
68 if (num_rounds < 12 || num_rounds > 24) {
69 return CRYPT_INVALID_ROUNDS;
70 }
71
72 /* key must be between 64 and 1024 bits */
73 if (keylen < 8 || keylen > 128) {
74 return CRYPT_INVALID_KEYSIZE;
75 }
76
77 skey->rc5.rounds = num_rounds;
78 S = skey->rc5.K;
79
80 /* copy the key into the L array */
81 for (A = i = j = 0; i < (ulong32)keylen; ) {
82 A = (A << 8) | ((ulong32)(key[i++] & 255));
83 if ((i & 3) == 0) {
84 L[j++] = BSWAP(A);
85 A = 0;
86 }
87 }
88
89 if ((keylen & 3) != 0) {
90 A <<= (ulong32)((8 * (4 - (keylen&3))));
91 L[j++] = BSWAP(A);
92 }
93
94 /* setup the S array */
95 t = (ulong32)(2 * (num_rounds + 1));
96 XMEMCPY(S, stab, t * sizeof(*S));
97
98 /* mix buffer */
99 s = 3 * MAX(t, j);
100 l = j;
101 for (A = B = i = j = v = 0; v < s; v++) {
102 A = S[i] = ROLc(S[i] + A + B, 3);
103 B = L[j] = ROL(L[j] + A + B, (A+B));
104 if (++i == t) { i = 0; }
105 if (++j == l) { j = 0; }
106 }
107 return CRYPT_OK;
108 }
109
110 #ifdef LTC_CLEAN_STACK
111 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
112 {
113 int x;
114 x = _rc5_setup(key, keylen, num_rounds, skey);
115 burn_stack(sizeof(ulong32) * 122 + sizeof(int));
116 return x;
117 }
118 #endif
119
120 /**
121 Encrypts a block of text with LTC_RC5
122 @param pt The input plaintext (8 bytes)
123 @param ct The output ciphertext (8 bytes)
124 @param skey The key as scheduled
125 @return CRYPT_OK if successful
126 */
127 #ifdef LTC_CLEAN_STACK
128 static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
129 #else
130 int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
131 #endif
132 {
133 ulong32 A, B, *K;
134 int r;
135 LTC_ARGCHK(skey != NULL);
136 LTC_ARGCHK(pt != NULL);
137 LTC_ARGCHK(ct != NULL);
138
139 LOAD32L(A, &pt[0]);
140 LOAD32L(B, &pt[4]);
141 A += skey->rc5.K[0];
142 B += skey->rc5.K[1];
143 K = skey->rc5.K + 2;
144
145 if ((skey->rc5.rounds & 1) == 0) {
146 for (r = 0; r < skey->rc5.rounds; r += 2) {
147 A = ROL(A ^ B, B) + K[0];
148 B = ROL(B ^ A, A) + K[1];
149 A = ROL(A ^ B, B) + K[2];
150 B = ROL(B ^ A, A) + K[3];
151 K += 4;
152 }
153 } else {
154 for (r = 0; r < skey->rc5.rounds; r++) {
155 A = ROL(A ^ B, B) + K[0];
156 B = ROL(B ^ A, A) + K[1];
157 K += 2;
158 }
159 }
160 STORE32L(A, &ct[0]);
161 STORE32L(B, &ct[4]);
162
163 return CRYPT_OK;
164 }
165
166 #ifdef LTC_CLEAN_STACK
167 int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
168 {
169 int err = _rc5_ecb_encrypt(pt, ct, skey);
170 burn_stack(sizeof(ulong32) * 2 + sizeof(int));
171 return err;
172 }
173 #endif
174
175 /**
176 Decrypts a block of text with LTC_RC5
177 @param ct The input ciphertext (8 bytes)
178 @param pt The output plaintext (8 bytes)
179 @param skey The key as scheduled
180 @return CRYPT_OK if successful
181 */
182 #ifdef LTC_CLEAN_STACK
183 static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
184 #else
185 int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
186 #endif
187 {
188 ulong32 A, B, *K;
189 int r;
190 LTC_ARGCHK(skey != NULL);
191 LTC_ARGCHK(pt != NULL);
192 LTC_ARGCHK(ct != NULL);
193
194 LOAD32L(A, &ct[0]);
195 LOAD32L(B, &ct[4]);
196 K = skey->rc5.K + (skey->rc5.rounds << 1);
197
198 if ((skey->rc5.rounds & 1) == 0) {
199 K -= 2;
200 for (r = skey->rc5.rounds - 1; r >= 0; r -= 2) {
201 B = ROR(B - K[3], A) ^ A;
202 A = ROR(A - K[2], B) ^ B;
203 B = ROR(B - K[1], A) ^ A;
204 A = ROR(A - K[0], B) ^ B;
205 K -= 4;
206 }
207 } else {
208 for (r = skey->rc5.rounds - 1; r >= 0; r--) {
209 B = ROR(B - K[1], A) ^ A;
210 A = ROR(A - K[0], B) ^ B;
211 K -= 2;
212 }
213 }
214 A -= skey->rc5.K[0];
215 B -= skey->rc5.K[1];
216 STORE32L(A, &pt[0]);
217 STORE32L(B, &pt[4]);
218
219 return CRYPT_OK;
220 }
221
222 #ifdef LTC_CLEAN_STACK
223 int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
224 {
225 int err = _rc5_ecb_decrypt(ct, pt, skey);
226 burn_stack(sizeof(ulong32) * 2 + sizeof(int));
227 return err;
228 }
229 #endif
230
231 /**
232 Performs a self-test of the LTC_RC5 block cipher
233 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
234 */
235 int rc5_test(void)
236 {
237 #ifndef LTC_TEST
238 return CRYPT_NOP;
239 #else
240 static const struct {
241 unsigned char key[16], pt[8], ct[8];
242 } tests[] = {
243 {
244 { 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51,
245 0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 },
246 { 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d },
247 { 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 }
248 },
249 {
250 { 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f,
251 0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 },
252 { 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 },
253 { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }
254 },
255 {
256 { 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f,
257 0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf },
258 { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 },
259 { 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc }
260 }
261 };
262 unsigned char tmp[2][8];
263 int x, y, err;
264 symmetric_key key;
265
266 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
267 /* setup key */
268 if ((err = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) {
269 return err;
270 }
271
272 /* encrypt and decrypt */
273 rc5_ecb_encrypt(tests[x].pt, tmp[0], &key);
274 rc5_ecb_decrypt(tmp[0], tmp[1], &key);
275
276 /* compare */
277 if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) {
278 return CRYPT_FAIL_TESTVECTOR;
279 }
280
281 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
282 for (y = 0; y < 8; y++) tmp[0][y] = 0;
283 for (y = 0; y < 1000; y++) rc5_ecb_encrypt(tmp[0], tmp[0], &key);
284 for (y = 0; y < 1000; y++) rc5_ecb_decrypt(tmp[0], tmp[0], &key);
285 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
286 }
287 return CRYPT_OK;
288 #endif
289 }
290
291 /** Terminate the context
292 @param skey The scheduled key
293 */
294 void rc5_done(symmetric_key *skey)
295 {
296 }
297
298 /**
299 Gets suitable key size
300 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
301 @return CRYPT_OK if the input key size is acceptable.
302 */
303 int rc5_keysize(int *keysize)
304 {
305 LTC_ARGCHK(keysize != NULL);
306 if (*keysize < 8) {
307 return CRYPT_INVALID_KEYSIZE;
308 } else if (*keysize > 128) {
309 *keysize = 128;
310 }
311 return CRYPT_OK;
312 }
313
314 #endif
315
316
317
318
319 /* $Source$ */
320 /* $Revision$ */
321 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file rc6.c
13 LTC_RC6 code by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_RC6
18
19 const struct ltc_cipher_descriptor rc6_desc =
20 {
21 "rc6",
22 3,
23 8, 128, 16, 20,
24 &rc6_setup,
25 &rc6_ecb_encrypt,
26 &rc6_ecb_decrypt,
27 &rc6_test,
28 &rc6_done,
29 &rc6_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 static const ulong32 stab[44] = {
34 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL,
35 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL,
36 0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL,
37 0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL,
38 0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL,
39 0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL };
40
41 /**
42 Initialize the LTC_RC6 block cipher
43 @param key The symmetric key you wish to pass
44 @param keylen The key length in bytes
45 @param num_rounds The number of rounds desired (0 for default)
46 @param skey The key in as scheduled by this function.
47 @return CRYPT_OK if successful
48 */
49 #ifdef LTC_CLEAN_STACK
50 static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
51 #else
52 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
53 #endif
54 {
55 ulong32 L[64], S[50], A, B, i, j, v, s, l;
56
57 LTC_ARGCHK(key != NULL);
58 LTC_ARGCHK(skey != NULL);
59
60 /* test parameters */
61 if (num_rounds != 0 && num_rounds != 20) {
62 return CRYPT_INVALID_ROUNDS;
63 }
64
65 /* key must be between 64 and 1024 bits */
66 if (keylen < 8 || keylen > 128) {
67 return CRYPT_INVALID_KEYSIZE;
68 }
69
70 /* copy the key into the L array */
71 for (A = i = j = 0; i < (ulong32)keylen; ) {
72 A = (A << 8) | ((ulong32)(key[i++] & 255));
73 if (!(i & 3)) {
74 L[j++] = BSWAP(A);
75 A = 0;
76 }
77 }
78
79 /* handle odd sized keys */
80 if (keylen & 3) {
81 A <<= (8 * (4 - (keylen&3)));
82 L[j++] = BSWAP(A);
83 }
84
85 /* setup the S array */
86 XMEMCPY(S, stab, 44 * sizeof(stab[0]));
87
88 /* mix buffer */
89 s = 3 * MAX(44, j);
90 l = j;
91 for (A = B = i = j = v = 0; v < s; v++) {
92 A = S[i] = ROLc(S[i] + A + B, 3);
93 B = L[j] = ROL(L[j] + A + B, (A+B));
94 if (++i == 44) { i = 0; }
95 if (++j == l) { j = 0; }
96 }
97
98 /* copy to key */
99 for (i = 0; i < 44; i++) {
100 skey->rc6.K[i] = S[i];
101 }
102 return CRYPT_OK;
103 }
104
105 #ifdef LTC_CLEAN_STACK
106 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
107 {
108 int x;
109 x = _rc6_setup(key, keylen, num_rounds, skey);
110 burn_stack(sizeof(ulong32) * 122);
111 return x;
112 }
113 #endif
114
115 /**
116 Encrypts a block of text with LTC_RC6
117 @param pt The input plaintext (16 bytes)
118 @param ct The output ciphertext (16 bytes)
119 @param skey The key as scheduled
120 */
121 #ifdef LTC_CLEAN_STACK
122 static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
123 #else
124 int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
125 #endif
126 {
127 ulong32 a,b,c,d,t,u, *K;
128 int r;
129
130 LTC_ARGCHK(skey != NULL);
131 LTC_ARGCHK(pt != NULL);
132 LTC_ARGCHK(ct != NULL);
133 LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]);
134
135 b += skey->rc6.K[0];
136 d += skey->rc6.K[1];
137
138 #define RND(a,b,c,d) \
139 t = (b * (b + b + 1)); t = ROLc(t, 5); \
140 u = (d * (d + d + 1)); u = ROLc(u, 5); \
141 a = ROL(a^t,u) + K[0]; \
142 c = ROL(c^u,t) + K[1]; K += 2;
143
144 K = skey->rc6.K + 2;
145 for (r = 0; r < 20; r += 4) {
146 RND(a,b,c,d);
147 RND(b,c,d,a);
148 RND(c,d,a,b);
149 RND(d,a,b,c);
150 }
151
152 #undef RND
153
154 a += skey->rc6.K[42];
155 c += skey->rc6.K[43];
156 STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
157 return CRYPT_OK;
158 }
159
160 #ifdef LTC_CLEAN_STACK
161 int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
162 {
163 int err = _rc6_ecb_encrypt(pt, ct, skey);
164 burn_stack(sizeof(ulong32) * 6 + sizeof(int));
165 return err;
166 }
167 #endif
168
169 /**
170 Decrypts a block of text with LTC_RC6
171 @param ct The input ciphertext (16 bytes)
172 @param pt The output plaintext (16 bytes)
173 @param skey The key as scheduled
174 */
175 #ifdef LTC_CLEAN_STACK
176 static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
177 #else
178 int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
179 #endif
180 {
181 ulong32 a,b,c,d,t,u, *K;
182 int r;
183
184 LTC_ARGCHK(skey != NULL);
185 LTC_ARGCHK(pt != NULL);
186 LTC_ARGCHK(ct != NULL);
187
188 LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]);
189 a -= skey->rc6.K[42];
190 c -= skey->rc6.K[43];
191
192 #define RND(a,b,c,d) \
193 t = (b * (b + b + 1)); t = ROLc(t, 5); \
194 u = (d * (d + d + 1)); u = ROLc(u, 5); \
195 c = ROR(c - K[1], t) ^ u; \
196 a = ROR(a - K[0], u) ^ t; K -= 2;
197
198 K = skey->rc6.K + 40;
199
200 for (r = 0; r < 20; r += 4) {
201 RND(d,a,b,c);
202 RND(c,d,a,b);
203 RND(b,c,d,a);
204 RND(a,b,c,d);
205 }
206
207 #undef RND
208
209 b -= skey->rc6.K[0];
210 d -= skey->rc6.K[1];
211 STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
212
213 return CRYPT_OK;
214 }
215
216 #ifdef LTC_CLEAN_STACK
217 int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
218 {
219 int err = _rc6_ecb_decrypt(ct, pt, skey);
220 burn_stack(sizeof(ulong32) * 6 + sizeof(int));
221 return err;
222 }
223 #endif
224
225 /**
226 Performs a self-test of the LTC_RC6 block cipher
227 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
228 */
229 int rc6_test(void)
230 {
231 #ifndef LTC_TEST
232 return CRYPT_NOP;
233 #else
234 static const struct {
235 int keylen;
236 unsigned char key[32], pt[16], ct[16];
237 } tests[] = {
238 {
239 16,
240 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
241 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
244 { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
245 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
246 { 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23,
247 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 }
248 },
249 {
250 24,
251 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
252 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
253 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
255 { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
256 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
257 { 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04,
258 0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 }
259 },
260 {
261 32,
262 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
263 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
264 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
265 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe },
266 { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
267 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
268 { 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89,
269 0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 }
270 }
271 };
272 unsigned char tmp[2][16];
273 int x, y, err;
274 symmetric_key key;
275
276 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
277 /* setup key */
278 if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
279 return err;
280 }
281
282 /* encrypt and decrypt */
283 rc6_ecb_encrypt(tests[x].pt, tmp[0], &key);
284 rc6_ecb_decrypt(tmp[0], tmp[1], &key);
285
286 /* compare */
287 if (XMEMCMP(tmp[0], tests[x].ct, 16) || XMEMCMP(tmp[1], tests[x].pt, 16)) {
288 #if 0
289 printf("\n\nFailed test %d\n", x);
290 if (XMEMCMP(tmp[0], tests[x].ct, 16)) {
291 printf("Ciphertext: ");
292 for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]);
293 printf("\nExpected : ");
294 for (y = 0; y < 16; y++) printf("%02x ", tests[x].ct[y]);
295 printf("\n");
296 }
297 if (XMEMCMP(tmp[1], tests[x].pt, 16)) {
298 printf("Plaintext: ");
299 for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]);
300 printf("\nExpected : ");
301 for (y = 0; y < 16; y++) printf("%02x ", tests[x].pt[y]);
302 printf("\n");
303 }
304 #endif
305 return CRYPT_FAIL_TESTVECTOR;
306 }
307
308 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
309 for (y = 0; y < 16; y++) tmp[0][y] = 0;
310 for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key);
311 for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key);
312 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
313 }
314 return CRYPT_OK;
315 #endif
316 }
317
318 /** Terminate the context
319 @param skey The scheduled key
320 */
321 void rc6_done(symmetric_key *skey)
322 {
323 }
324
325 /**
326 Gets suitable key size
327 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
328 @return CRYPT_OK if the input key size is acceptable.
329 */
330 int rc6_keysize(int *keysize)
331 {
332 LTC_ARGCHK(keysize != NULL);
333 if (*keysize < 8) {
334 return CRYPT_INVALID_KEYSIZE;
335 } else if (*keysize > 128) {
336 *keysize = 128;
337 }
338 return CRYPT_OK;
339 }
340
341 #endif /*LTC_RC6*/
342
343
344
345 /* $Source$ */
346 /* $Revision$ */
347 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /*******************************************************************************
12 *
13 * FILE: safer.c
14 *
15 * LTC_DESCRIPTION: block-cipher algorithm LTC_SAFER (Secure And Fast Encryption
16 * Routine) in its four versions: LTC_SAFER K-64, LTC_SAFER K-128,
17 * LTC_SAFER SK-64 and LTC_SAFER SK-128.
18 *
19 * AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
20 * Signal and Information Processing Laboratory
21 * Swiss Federal Institute of Technology
22 * CH-8092 Zuerich, Switzerland
23 *
24 * DATE: September 9, 1995
25 *
26 * CHANGE HISTORY:
27 *
28 *******************************************************************************/
29
30 #include <tomcrypt.h>
31
32 #ifdef LTC_SAFER
33
34 const struct ltc_cipher_descriptor
35 safer_k64_desc = {
36 "safer-k64",
37 8, 8, 8, 8, LTC_SAFER_K64_DEFAULT_NOF_ROUNDS,
38 &safer_k64_setup,
39 &safer_ecb_encrypt,
40 &safer_ecb_decrypt,
41 &safer_k64_test,
42 &safer_done,
43 &safer_64_keysize,
44 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
45 },
46
47 safer_sk64_desc = {
48 "safer-sk64",
49 9, 8, 8, 8, LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS,
50 &safer_sk64_setup,
51 &safer_ecb_encrypt,
52 &safer_ecb_decrypt,
53 &safer_sk64_test,
54 &safer_done,
55 &safer_64_keysize,
56 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
57 },
58
59 safer_k128_desc = {
60 "safer-k128",
61 10, 16, 16, 8, LTC_SAFER_K128_DEFAULT_NOF_ROUNDS,
62 &safer_k128_setup,
63 &safer_ecb_encrypt,
64 &safer_ecb_decrypt,
65 &safer_sk128_test,
66 &safer_done,
67 &safer_128_keysize,
68 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
69 },
70
71 safer_sk128_desc = {
72 "safer-sk128",
73 11, 16, 16, 8, LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS,
74 &safer_sk128_setup,
75 &safer_ecb_encrypt,
76 &safer_ecb_decrypt,
77 &safer_sk128_test,
78 &safer_done,
79 &safer_128_keysize,
80 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
81 };
82
83 /******************* Constants ************************************************/
84 /* #define TAB_LEN 256 */
85
86 /******************* Assertions ***********************************************/
87
88 /******************* Macros ***************************************************/
89 #define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\
90 |(unsigned int)((x) & 0xFF) >> (8 - (n))))
91 #define EXP(x) safer_ebox[(x) & 0xFF]
92 #define LOG(x) safer_lbox[(x) & 0xFF]
93 #define PHT(x, y) { y += x; x += y; }
94 #define IPHT(x, y) { x -= y; y -= x; }
95
96 /******************* Types ****************************************************/
97 extern const unsigned char safer_ebox[], safer_lbox[];
98
99 #ifdef LTC_CLEAN_STACK
100 static void _Safer_Expand_Userkey(const unsigned char *userkey_1,
101 const unsigned char *userkey_2,
102 unsigned int nof_rounds,
103 int strengthened,
104 safer_key_t key)
105 #else
106 static void Safer_Expand_Userkey(const unsigned char *userkey_1,
107 const unsigned char *userkey_2,
108 unsigned int nof_rounds,
109 int strengthened,
110 safer_key_t key)
111 #endif
112 { unsigned int i, j, k;
113 unsigned char ka[LTC_SAFER_BLOCK_LEN + 1];
114 unsigned char kb[LTC_SAFER_BLOCK_LEN + 1];
115
116 if (LTC_SAFER_MAX_NOF_ROUNDS < nof_rounds)
117 nof_rounds = LTC_SAFER_MAX_NOF_ROUNDS;
118 *key++ = (unsigned char)nof_rounds;
119 ka[LTC_SAFER_BLOCK_LEN] = (unsigned char)0;
120 kb[LTC_SAFER_BLOCK_LEN] = (unsigned char)0;
121 k = 0;
122 for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
123 ka[j] = ROL8(userkey_1[j], 5);
124 ka[LTC_SAFER_BLOCK_LEN] ^= ka[j];
125 kb[j] = *key++ = userkey_2[j];
126 kb[LTC_SAFER_BLOCK_LEN] ^= kb[j];
127 }
128 for (i = 1; i <= nof_rounds; i++) {
129 for (j = 0; j < LTC_SAFER_BLOCK_LEN + 1; j++) {
130 ka[j] = ROL8(ka[j], 6);
131 kb[j] = ROL8(kb[j], 6);
132 }
133 if (strengthened) {
134 k = 2 * i - 1;
135 while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; }
136 }
137 for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
138 if (strengthened) {
139 *key++ = (ka[k]
140 + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF;
141 if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; }
142 } else {
143 *key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF;
144 }
145 }
146 if (strengthened) {
147 k = 2 * i;
148 while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; }
149 }
150 for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
151 if (strengthened) {
152 *key++ = (kb[k]
153 + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF;
154 if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; }
155 } else {
156 *key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF;
157 }
158 }
159 }
160
161 #ifdef LTC_CLEAN_STACK
162 zeromem(ka, sizeof(ka));
163 zeromem(kb, sizeof(kb));
164 #endif
165 }
166
167 #ifdef LTC_CLEAN_STACK
168 static void Safer_Expand_Userkey(const unsigned char *userkey_1,
169 const unsigned char *userkey_2,
170 unsigned int nof_rounds,
171 int strengthened,
172 safer_key_t key)
173 {
174 _Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key);
175 burn_stack(sizeof(unsigned char) * (2 * (LTC_SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2);
176 }
177 #endif
178
179 int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
180 {
181 LTC_ARGCHK(key != NULL);
182 LTC_ARGCHK(skey != NULL);
183
184 if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
185 return CRYPT_INVALID_ROUNDS;
186 }
187
188 if (keylen != 8) {
189 return CRYPT_INVALID_KEYSIZE;
190 }
191
192 Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key);
193 return CRYPT_OK;
194 }
195
196 int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
197 {
198 LTC_ARGCHK(key != NULL);
199 LTC_ARGCHK(skey != NULL);
200
201 if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
202 return CRYPT_INVALID_ROUNDS;
203 }
204
205 if (keylen != 8) {
206 return CRYPT_INVALID_KEYSIZE;
207 }
208
209 Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key);
210 return CRYPT_OK;
211 }
212
213 int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
214 {
215 LTC_ARGCHK(key != NULL);
216 LTC_ARGCHK(skey != NULL);
217
218 if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
219 return CRYPT_INVALID_ROUNDS;
220 }
221
222 if (keylen != 16) {
223 return CRYPT_INVALID_KEYSIZE;
224 }
225
226 Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key);
227 return CRYPT_OK;
228 }
229
230 int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
231 {
232 LTC_ARGCHK(key != NULL);
233 LTC_ARGCHK(skey != NULL);
234
235 if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
236 return CRYPT_INVALID_ROUNDS;
237 }
238
239 if (keylen != 16) {
240 return CRYPT_INVALID_KEYSIZE;
241 }
242
243 Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key);
244 return CRYPT_OK;
245 }
246
247 #ifdef LTC_CLEAN_STACK
248 static int _safer_ecb_encrypt(const unsigned char *block_in,
249 unsigned char *block_out,
250 symmetric_key *skey)
251 #else
252 int safer_ecb_encrypt(const unsigned char *block_in,
253 unsigned char *block_out,
254 symmetric_key *skey)
255 #endif
256 { unsigned char a, b, c, d, e, f, g, h, t;
257 unsigned int round;
258 unsigned char *key;
259
260 LTC_ARGCHK(block_in != NULL);
261 LTC_ARGCHK(block_out != NULL);
262 LTC_ARGCHK(skey != NULL);
263
264 key = skey->safer.key;
265 a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
266 e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
267 if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS;
268 while(round-- > 0)
269 {
270 a ^= *++key; b += *++key; c += *++key; d ^= *++key;
271 e ^= *++key; f += *++key; g += *++key; h ^= *++key;
272 a = EXP(a) + *++key; b = LOG(b) ^ *++key;
273 c = LOG(c) ^ *++key; d = EXP(d) + *++key;
274 e = EXP(e) + *++key; f = LOG(f) ^ *++key;
275 g = LOG(g) ^ *++key; h = EXP(h) + *++key;
276 PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h);
277 PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h);
278 PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h);
279 t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t;
280 }
281 a ^= *++key; b += *++key; c += *++key; d ^= *++key;
282 e ^= *++key; f += *++key; g += *++key; h ^= *++key;
283 block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
284 block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
285 block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
286 block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
287 return CRYPT_OK;
288 }
289
290 #ifdef LTC_CLEAN_STACK
291 int safer_ecb_encrypt(const unsigned char *block_in,
292 unsigned char *block_out,
293 symmetric_key *skey)
294 {
295 int err = _safer_ecb_encrypt(block_in, block_out, skey);
296 burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
297 return err;
298 }
299 #endif
300
301 #ifdef LTC_CLEAN_STACK
302 static int _safer_ecb_decrypt(const unsigned char *block_in,
303 unsigned char *block_out,
304 symmetric_key *skey)
305 #else
306 int safer_ecb_decrypt(const unsigned char *block_in,
307 unsigned char *block_out,
308 symmetric_key *skey)
309 #endif
310 { unsigned char a, b, c, d, e, f, g, h, t;
311 unsigned int round;
312 unsigned char *key;
313
314 LTC_ARGCHK(block_in != NULL);
315 LTC_ARGCHK(block_out != NULL);
316 LTC_ARGCHK(skey != NULL);
317
318 key = skey->safer.key;
319 a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
320 e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
321 if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS;
322 key += LTC_SAFER_BLOCK_LEN * (1 + 2 * round);
323 h ^= *key; g -= *--key; f -= *--key; e ^= *--key;
324 d ^= *--key; c -= *--key; b -= *--key; a ^= *--key;
325 while (round--)
326 {
327 t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t;
328 IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h);
329 IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h);
330 IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h);
331 h -= *--key; g ^= *--key; f ^= *--key; e -= *--key;
332 d -= *--key; c ^= *--key; b ^= *--key; a -= *--key;
333 h = LOG(h) ^ *--key; g = EXP(g) - *--key;
334 f = EXP(f) - *--key; e = LOG(e) ^ *--key;
335 d = LOG(d) ^ *--key; c = EXP(c) - *--key;
336 b = EXP(b) - *--key; a = LOG(a) ^ *--key;
337 }
338 block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
339 block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
340 block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
341 block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
342 return CRYPT_OK;
343 }
344
345 #ifdef LTC_CLEAN_STACK
346 int safer_ecb_decrypt(const unsigned char *block_in,
347 unsigned char *block_out,
348 symmetric_key *skey)
349 {
350 int err = _safer_ecb_decrypt(block_in, block_out, skey);
351 burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
352 return err;
353 }
354 #endif
355
356 int safer_64_keysize(int *keysize)
357 {
358 LTC_ARGCHK(keysize != NULL);
359 if (*keysize < 8) {
360 return CRYPT_INVALID_KEYSIZE;
361 } else {
362 *keysize = 8;
363 return CRYPT_OK;
364 }
365 }
366
367 int safer_128_keysize(int *keysize)
368 {
369 LTC_ARGCHK(keysize != NULL);
370 if (*keysize < 16) {
371 return CRYPT_INVALID_KEYSIZE;
372 } else {
373 *keysize = 16;
374 return CRYPT_OK;
375 }
376 }
377
378 int safer_k64_test(void)
379 {
380 #ifndef LTC_TEST
381 return CRYPT_NOP;
382 #else
383 static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
384 k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 },
385 k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 };
386
387 symmetric_key skey;
388 unsigned char buf[2][8];
389 int err;
390
391 /* test K64 */
392 if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) {
393 return err;
394 }
395 safer_ecb_encrypt(k64_pt, buf[0], &skey);
396 safer_ecb_decrypt(buf[0], buf[1], &skey);
397
398 if (XMEMCMP(buf[0], k64_ct, 8) != 0 || XMEMCMP(buf[1], k64_pt, 8) != 0) {
399 return CRYPT_FAIL_TESTVECTOR;
400 }
401
402 return CRYPT_OK;
403 #endif
404 }
405
406
407 int safer_sk64_test(void)
408 {
409 #ifndef LTC_TEST
410 return CRYPT_NOP;
411 #else
412 static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
413 sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
414 sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 };
415
416 symmetric_key skey;
417 unsigned char buf[2][8];
418 int err, y;
419
420 /* test SK64 */
421 if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) {
422 return err;
423 }
424
425 safer_ecb_encrypt(sk64_pt, buf[0], &skey);
426 safer_ecb_decrypt(buf[0], buf[1], &skey);
427
428 if (XMEMCMP(buf[0], sk64_ct, 8) != 0 || XMEMCMP(buf[1], sk64_pt, 8) != 0) {
429 return CRYPT_FAIL_TESTVECTOR;
430 }
431
432 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
433 for (y = 0; y < 8; y++) buf[0][y] = 0;
434 for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey);
435 for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey);
436 for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
437
438 return CRYPT_OK;
439 #endif
440 }
441
442 /** Terminate the context
443 @param skey The scheduled key
444 */
445 void safer_done(symmetric_key *skey)
446 {
447 }
448
449 int safer_sk128_test(void)
450 {
451 #ifndef LTC_TEST
452 return CRYPT_NOP;
453 #else
454 static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
455 sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8,
456 0, 0, 0, 0, 0, 0, 0, 0 },
457 sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 };
458
459 symmetric_key skey;
460 unsigned char buf[2][8];
461 int err, y;
462
463 /* test SK128 */
464 if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) {
465 return err;
466 }
467 safer_ecb_encrypt(sk128_pt, buf[0], &skey);
468 safer_ecb_decrypt(buf[0], buf[1], &skey);
469
470 if (XMEMCMP(buf[0], sk128_ct, 8) != 0 || XMEMCMP(buf[1], sk128_pt, 8) != 0) {
471 return CRYPT_FAIL_TESTVECTOR;
472 }
473
474 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
475 for (y = 0; y < 8; y++) buf[0][y] = 0;
476 for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey);
477 for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey);
478 for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
479 return CRYPT_OK;
480 #endif
481 }
482
483 #endif
484
485
486
487
488 /* $Source$ */
489 /* $Revision$ */
490 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file safer_tab.c
13 Tables for LTC_SAFER block ciphers
14 */
15
16 #include "tomcrypt.h"
17
18 #if defined(LTC_SAFERP) || defined(LTC_SAFER)
19
20 /* This is the box defined by ebox[x] = 45^x mod 257.
21 * Its assumed that the value "256" corresponds to zero. */
22 const unsigned char safer_ebox[256] = {
23 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63,
24 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247,
25 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177,
26 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131,
27 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20,
28 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160,
29 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252,
30 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217,
31 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194,
32 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10,
33 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80,
34 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126,
35 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237,
36 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97,
37 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5,
38 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40
39 };
40
41 /* This is the inverse of ebox or the base 45 logarithm */
42 const unsigned char safer_lbox[256] = {
43 128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248,
44 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130,
45 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37,
46 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15,
47 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198,
48 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84,
49 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188,
50 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217,
51 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158,
52 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42,
53 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219,
54 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29,
55 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14,
56 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104,
57 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66,
58 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48
59 };
60
61 #endif
62
63
64
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file saferp.c
13 LTC_SAFER+ Implementation by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_SAFERP
18
19 const struct ltc_cipher_descriptor saferp_desc =
20 {
21 "safer+",
22 4,
23 16, 32, 16, 8,
24 &saferp_setup,
25 &saferp_ecb_encrypt,
26 &saferp_ecb_decrypt,
27 &saferp_test,
28 &saferp_done,
29 &saferp_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 /* ROUND(b,i)
34 *
35 * This is one forward key application. Note the basic form is
36 * key addition, substitution, key addition. The safer_ebox and safer_lbox
37 * are the exponentiation box and logarithm boxes respectively.
38 * The value of 'i' is the current round number which allows this
39 * function to be unrolled massively. Most of LTC_SAFER+'s speed
40 * comes from not having to compute indirect accesses into the
41 * array of 16 bytes b[0..15] which is the block of data
42 */
43
44 extern const unsigned char safer_ebox[], safer_lbox[];
45
46 #define ROUND(b, i) \
47 b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \
48 b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \
49 b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \
50 b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \
51 b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \
52 b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \
53 b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \
54 b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \
55 b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \
56 b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \
57 b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \
58 b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \
59 b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \
60 b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \
61 b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \
62 b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255;
63
64 /* This is one inverse key application */
65 #define iROUND(b, i) \
66 b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \
67 b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \
68 b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \
69 b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \
70 b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \
71 b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \
72 b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \
73 b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \
74 b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \
75 b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \
76 b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \
77 b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \
78 b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \
79 b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \
80 b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \
81 b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15];
82
83 /* This is a forward single layer PHT transform. */
84 #define PHT(b) \
85 b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \
86 b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \
87 b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \
88 b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \
89 b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \
90 b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \
91 b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \
92 b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255;
93
94 /* This is an inverse single layer PHT transform */
95 #define iPHT(b) \
96 b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \
97 b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \
98 b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \
99 b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \
100 b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \
101 b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \
102 b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \
103 b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \
104
105 /* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */
106 #define SHUF(b, b2) \
107 b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \
108 b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \
109 b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \
110 b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3];
111
112 /* This is the inverse shuffle. It takes from b and gives to b2 */
113 #define iSHUF(b, b2) \
114 b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \
115 b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \
116 b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \
117 b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3];
118
119 /* The complete forward Linear Transform layer.
120 * Note that alternating usage of b and b2.
121 * Each round of LT starts in 'b' and ends in 'b2'.
122 */
123 #define LT(b, b2) \
124 PHT(b); SHUF(b, b2); \
125 PHT(b2); SHUF(b2, b); \
126 PHT(b); SHUF(b, b2); \
127 PHT(b2);
128
129 /* This is the inverse linear transform layer. */
130 #define iLT(b, b2) \
131 iPHT(b); \
132 iSHUF(b, b2); iPHT(b2); \
133 iSHUF(b2, b); iPHT(b); \
134 iSHUF(b, b2); iPHT(b2);
135
136 #ifdef LTC_SMALL_CODE
137
138 static void _round(unsigned char *b, int i, symmetric_key *skey)
139 {
140 ROUND(b, i);
141 }
142
143 static void _iround(unsigned char *b, int i, symmetric_key *skey)
144 {
145 iROUND(b, i);
146 }
147
148 static void _lt(unsigned char *b, unsigned char *b2)
149 {
150 LT(b, b2);
151 }
152
153 static void _ilt(unsigned char *b, unsigned char *b2)
154 {
155 iLT(b, b2);
156 }
157
158 #undef ROUND
159 #define ROUND(b, i) _round(b, i, skey)
160
161 #undef iROUND
162 #define iROUND(b, i) _iround(b, i, skey)
163
164 #undef LT
165 #define LT(b, b2) _lt(b, b2)
166
167 #undef iLT
168 #define iLT(b, b2) _ilt(b, b2)
169
170 #endif
171
172 /* These are the 33, 128-bit bias words for the key schedule */
173 static const unsigned char safer_bias[33][16] = {
174 { 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100},
175 { 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61},
176 { 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160},
177 { 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148},
178 { 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143},
179 { 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202},
180 { 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44},
181 { 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51},
182 { 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56},
183 { 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215},
184 { 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210},
185 { 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53},
186 { 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244},
187 { 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131},
188 { 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241},
189 { 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172},
190 { 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239},
191 { 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202},
192 { 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246},
193 { 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152},
194 { 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236},
195 { 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150},
196 { 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30},
197 { 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6},
198 { 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104},
199 { 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175},
200 { 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35},
201 { 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7},
202 { 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207},
203 { 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247},
204 { 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255},
205 { 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}};
206
207 /**
208 Initialize the LTC_SAFER+ block cipher
209 @param key The symmetric key you wish to pass
210 @param keylen The key length in bytes
211 @param num_rounds The number of rounds desired (0 for default)
212 @param skey The key in as scheduled by this function.
213 @return CRYPT_OK if successful
214 */
215 int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
216 {
217 unsigned x, y, z;
218 unsigned char t[33];
219 static const int rounds[3] = { 8, 12, 16 };
220
221 LTC_ARGCHK(key != NULL);
222 LTC_ARGCHK(skey != NULL);
223
224 /* check arguments */
225 if (keylen != 16 && keylen != 24 && keylen != 32) {
226 return CRYPT_INVALID_KEYSIZE;
227 }
228
229 /* Is the number of rounds valid? Either use zero for default or
230 * 8,12,16 rounds for 16,24,32 byte keys
231 */
232 if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) {
233 return CRYPT_INVALID_ROUNDS;
234 }
235
236 /* 128 bit key version */
237 if (keylen == 16) {
238 /* copy key into t */
239 for (x = y = 0; x < 16; x++) {
240 t[x] = key[x];
241 y ^= key[x];
242 }
243 t[16] = y;
244
245 /* make round keys */
246 for (x = 0; x < 16; x++) {
247 skey->saferp.K[0][x] = t[x];
248 }
249
250 /* make the 16 other keys as a transformation of the first key */
251 for (x = 1; x < 17; x++) {
252 /* rotate 3 bits each */
253 for (y = 0; y < 17; y++) {
254 t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
255 }
256
257 /* select and add */
258 z = x;
259 for (y = 0; y < 16; y++) {
260 skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
261 if (++z == 17) { z = 0; }
262 }
263 }
264 skey->saferp.rounds = 8;
265 } else if (keylen == 24) {
266 /* copy key into t */
267 for (x = y = 0; x < 24; x++) {
268 t[x] = key[x];
269 y ^= key[x];
270 }
271 t[24] = y;
272
273 /* make round keys */
274 for (x = 0; x < 16; x++) {
275 skey->saferp.K[0][x] = t[x];
276 }
277
278 for (x = 1; x < 25; x++) {
279 /* rotate 3 bits each */
280 for (y = 0; y < 25; y++) {
281 t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
282 }
283
284 /* select and add */
285 z = x;
286 for (y = 0; y < 16; y++) {
287 skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
288 if (++z == 25) { z = 0; }
289 }
290 }
291 skey->saferp.rounds = 12;
292 } else {
293 /* copy key into t */
294 for (x = y = 0; x < 32; x++) {
295 t[x] = key[x];
296 y ^= key[x];
297 }
298 t[32] = y;
299
300 /* make round keys */
301 for (x = 0; x < 16; x++) {
302 skey->saferp.K[0][x] = t[x];
303 }
304
305 for (x = 1; x < 33; x++) {
306 /* rotate 3 bits each */
307 for (y = 0; y < 33; y++) {
308 t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
309 }
310
311 /* select and add */
312 z = x;
313 for (y = 0; y < 16; y++) {
314 skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
315 if (++z == 33) { z = 0; }
316 }
317 }
318 skey->saferp.rounds = 16;
319 }
320 #ifdef LTC_CLEAN_STACK
321 zeromem(t, sizeof(t));
322 #endif
323 return CRYPT_OK;
324 }
325
326 /**
327 Encrypts a block of text with LTC_SAFER+
328 @param pt The input plaintext (16 bytes)
329 @param ct The output ciphertext (16 bytes)
330 @param skey The key as scheduled
331 @return CRYPT_OK if successful
332 */
333 int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
334 {
335 unsigned char b[16];
336 int x;
337
338 LTC_ARGCHK(pt != NULL);
339 LTC_ARGCHK(ct != NULL);
340 LTC_ARGCHK(skey != NULL);
341
342 /* do eight rounds */
343 for (x = 0; x < 16; x++) {
344 b[x] = pt[x];
345 }
346 ROUND(b, 0); LT(b, ct);
347 ROUND(ct, 2); LT(ct, b);
348 ROUND(b, 4); LT(b, ct);
349 ROUND(ct, 6); LT(ct, b);
350 ROUND(b, 8); LT(b, ct);
351 ROUND(ct, 10); LT(ct, b);
352 ROUND(b, 12); LT(b, ct);
353 ROUND(ct, 14); LT(ct, b);
354 /* 192-bit key? */
355 if (skey->saferp.rounds > 8) {
356 ROUND(b, 16); LT(b, ct);
357 ROUND(ct, 18); LT(ct, b);
358 ROUND(b, 20); LT(b, ct);
359 ROUND(ct, 22); LT(ct, b);
360 }
361 /* 256-bit key? */
362 if (skey->saferp.rounds > 12) {
363 ROUND(b, 24); LT(b, ct);
364 ROUND(ct, 26); LT(ct, b);
365 ROUND(b, 28); LT(b, ct);
366 ROUND(ct, 30); LT(ct, b);
367 }
368 ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
369 ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
370 ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
371 ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
372 ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
373 ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
374 ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
375 ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
376 ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
377 ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
378 ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
379 ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
380 ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
381 ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
382 ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
383 ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
384 #ifdef LTC_CLEAN_STACK
385 zeromem(b, sizeof(b));
386 #endif
387 return CRYPT_OK;
388 }
389
390 /**
391 Decrypts a block of text with LTC_SAFER+
392 @param ct The input ciphertext (16 bytes)
393 @param pt The output plaintext (16 bytes)
394 @param skey The key as scheduled
395 @return CRYPT_OK if successful
396 */
397 int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
398 {
399 unsigned char b[16];
400 int x;
401
402 LTC_ARGCHK(pt != NULL);
403 LTC_ARGCHK(ct != NULL);
404 LTC_ARGCHK(skey != NULL);
405
406 /* do eight rounds */
407 b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
408 b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
409 b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
410 b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
411 b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
412 b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
413 b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
414 b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
415 b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
416 b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
417 b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
418 b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
419 b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
420 b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
421 b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
422 b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
423 /* 256-bit key? */
424 if (skey->saferp.rounds > 12) {
425 iLT(b, pt); iROUND(pt, 30);
426 iLT(pt, b); iROUND(b, 28);
427 iLT(b, pt); iROUND(pt, 26);
428 iLT(pt, b); iROUND(b, 24);
429 }
430 /* 192-bit key? */
431 if (skey->saferp.rounds > 8) {
432 iLT(b, pt); iROUND(pt, 22);
433 iLT(pt, b); iROUND(b, 20);
434 iLT(b, pt); iROUND(pt, 18);
435 iLT(pt, b); iROUND(b, 16);
436 }
437 iLT(b, pt); iROUND(pt, 14);
438 iLT(pt, b); iROUND(b, 12);
439 iLT(b, pt); iROUND(pt,10);
440 iLT(pt, b); iROUND(b, 8);
441 iLT(b, pt); iROUND(pt,6);
442 iLT(pt, b); iROUND(b, 4);
443 iLT(b, pt); iROUND(pt,2);
444 iLT(pt, b); iROUND(b, 0);
445 for (x = 0; x < 16; x++) {
446 pt[x] = b[x];
447 }
448 #ifdef LTC_CLEAN_STACK
449 zeromem(b, sizeof(b));
450 #endif
451 return CRYPT_OK;
452 }
453
454 /**
455 Performs a self-test of the LTC_SAFER+ block cipher
456 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
457 */
458 int saferp_test(void)
459 {
460 #ifndef LTC_TEST
461 return CRYPT_NOP;
462 #else
463 static const struct {
464 int keylen;
465 unsigned char key[32], pt[16], ct[16];
466 } tests[] = {
467 {
468 16,
469 { 41, 35, 190, 132, 225, 108, 214, 174,
470 82, 144, 73, 241, 241, 187, 233, 235 },
471 { 179, 166, 219, 60, 135, 12, 62, 153,
472 36, 94, 13, 28, 6, 183, 71, 222 },
473 { 224, 31, 182, 10, 12, 255, 84, 70,
474 127, 13, 89, 249, 9, 57, 165, 220 }
475 }, {
476 24,
477 { 72, 211, 143, 117, 230, 217, 29, 42,
478 229, 192, 247, 43, 120, 129, 135, 68,
479 14, 95, 80, 0, 212, 97, 141, 190 },
480 { 123, 5, 21, 7, 59, 51, 130, 31,
481 24, 112, 146, 218, 100, 84, 206, 177 },
482 { 92, 136, 4, 63, 57, 95, 100, 0,
483 150, 130, 130, 16, 193, 111, 219, 133 }
484 }, {
485 32,
486 { 243, 168, 141, 254, 190, 242, 235, 113,
487 255, 160, 208, 59, 117, 6, 140, 126,
488 135, 120, 115, 77, 208, 190, 130, 190,
489 219, 194, 70, 65, 43, 140, 250, 48 },
490 { 127, 112, 240, 167, 84, 134, 50, 149,
491 170, 91, 104, 19, 11, 230, 252, 245 },
492 { 88, 11, 25, 36, 172, 229, 202, 213,
493 170, 65, 105, 153, 220, 104, 153, 138 }
494 }
495 };
496
497 unsigned char tmp[2][16];
498 symmetric_key skey;
499 int err, i, y;
500
501 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
502 if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) {
503 return err;
504 }
505 saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey);
506 saferp_ecb_decrypt(tmp[0], tmp[1], &skey);
507
508 /* compare */
509 if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
510 return CRYPT_FAIL_TESTVECTOR;
511 }
512
513 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
514 for (y = 0; y < 16; y++) tmp[0][y] = 0;
515 for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey);
516 for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey);
517 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
518 }
519
520 return CRYPT_OK;
521 #endif
522 }
523
524 /** Terminate the context
525 @param skey The scheduled key
526 */
527 void saferp_done(symmetric_key *skey)
528 {
529 }
530
531 /**
532 Gets suitable key size
533 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
534 @return CRYPT_OK if the input key size is acceptable.
535 */
536 int saferp_keysize(int *keysize)
537 {
538 LTC_ARGCHK(keysize != NULL);
539
540 if (*keysize < 16)
541 return CRYPT_INVALID_KEYSIZE;
542 if (*keysize < 24) {
543 *keysize = 16;
544 } else if (*keysize < 32) {
545 *keysize = 24;
546 } else {
547 *keysize = 32;
548 }
549 return CRYPT_OK;
550 }
551
552 #endif
553
554
555
556 /* $Source$ */
557 /* $Revision$ */
558 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file skipjack.c
13 Skipjack Implementation by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_SKIPJACK
18
19 const struct ltc_cipher_descriptor skipjack_desc =
20 {
21 "skipjack",
22 17,
23 10, 10, 8, 32,
24 &skipjack_setup,
25 &skipjack_ecb_encrypt,
26 &skipjack_ecb_decrypt,
27 &skipjack_test,
28 &skipjack_done,
29 &skipjack_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 static const unsigned char sbox[256] = {
34 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9,
35 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28,
36 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53,
37 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2,
38 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8,
39 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90,
40 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76,
41 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d,
42 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18,
43 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4,
44 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40,
45 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5,
46 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2,
47 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8,
48 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac,
49 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
50 };
51
52 /* simple x + 1 (mod 10) in one step. */
53 static const int keystep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
54
55 /* simple x - 1 (mod 10) in one step */
56 static const int ikeystep[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 };
57
58 /**
59 Initialize the Skipjack block cipher
60 @param key The symmetric key you wish to pass
61 @param keylen The key length in bytes
62 @param num_rounds The number of rounds desired (0 for default)
63 @param skey The key in as scheduled by this function.
64 @return CRYPT_OK if successful
65 */
66 int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
67 {
68 int x;
69
70 LTC_ARGCHK(key != NULL);
71 LTC_ARGCHK(skey != NULL);
72
73 if (keylen != 10) {
74 return CRYPT_INVALID_KEYSIZE;
75 }
76
77 if (num_rounds != 32 && num_rounds != 0) {
78 return CRYPT_INVALID_ROUNDS;
79 }
80
81 /* make sure the key is in range for platforms where CHAR_BIT != 8 */
82 for (x = 0; x < 10; x++) {
83 skey->skipjack.key[x] = key[x] & 255;
84 }
85
86 return CRYPT_OK;
87 }
88
89 #define RULE_A \
90 tmp = g_func(w1, &kp, skey->skipjack.key); \
91 w1 = tmp ^ w4 ^ x; \
92 w4 = w3; w3 = w2; \
93 w2 = tmp;
94
95 #define RULE_B \
96 tmp = g_func(w1, &kp, skey->skipjack.key); \
97 tmp1 = w4; w4 = w3; \
98 w3 = w1 ^ w2 ^ x; \
99 w1 = tmp1; w2 = tmp;
100
101 #define RULE_A1 \
102 tmp = w1 ^ w2 ^ x; \
103 w1 = ig_func(w2, &kp, skey->skipjack.key); \
104 w2 = w3; w3 = w4; w4 = tmp;
105
106 #define RULE_B1 \
107 tmp = ig_func(w2, &kp, skey->skipjack.key); \
108 w2 = tmp ^ w3 ^ x; \
109 w3 = w4; w4 = w1; w1 = tmp;
110
111 static unsigned g_func(unsigned w, int *kp, unsigned char *key)
112 {
113 unsigned char g1,g2;
114
115 g1 = (w >> 8) & 255; g2 = w & 255;
116 g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp];
117 g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp];
118 g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp];
119 g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp];
120 return ((unsigned)g1<<8)|(unsigned)g2;
121 }
122
123 static unsigned ig_func(unsigned w, int *kp, unsigned char *key)
124 {
125 unsigned char g1,g2;
126
127 g1 = (w >> 8) & 255; g2 = w & 255;
128 *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]];
129 *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]];
130 *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]];
131 *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]];
132 return ((unsigned)g1<<8)|(unsigned)g2;
133 }
134
135 /**
136 Encrypts a block of text with Skipjack
137 @param pt The input plaintext (8 bytes)
138 @param ct The output ciphertext (8 bytes)
139 @param skey The key as scheduled
140 @return CRYPT_OK if successful
141 */
142 #ifdef LTC_CLEAN_STACK
143 static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
144 #else
145 int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
146 #endif
147 {
148 unsigned w1,w2,w3,w4,tmp,tmp1;
149 int x, kp;
150
151 LTC_ARGCHK(pt != NULL);
152 LTC_ARGCHK(ct != NULL);
153 LTC_ARGCHK(skey != NULL);
154
155 /* load block */
156 w1 = ((unsigned)pt[0]<<8)|pt[1];
157 w2 = ((unsigned)pt[2]<<8)|pt[3];
158 w3 = ((unsigned)pt[4]<<8)|pt[5];
159 w4 = ((unsigned)pt[6]<<8)|pt[7];
160
161 /* 8 rounds of RULE A */
162 for (x = 1, kp = 0; x < 9; x++) {
163 RULE_A;
164 }
165
166 /* 8 rounds of RULE B */
167 for (; x < 17; x++) {
168 RULE_B;
169 }
170
171 /* 8 rounds of RULE A */
172 for (; x < 25; x++) {
173 RULE_A;
174 }
175
176 /* 8 rounds of RULE B */
177 for (; x < 33; x++) {
178 RULE_B;
179 }
180
181 /* store block */
182 ct[0] = (w1>>8)&255; ct[1] = w1&255;
183 ct[2] = (w2>>8)&255; ct[3] = w2&255;
184 ct[4] = (w3>>8)&255; ct[5] = w3&255;
185 ct[6] = (w4>>8)&255; ct[7] = w4&255;
186
187 return CRYPT_OK;
188 }
189
190 #ifdef LTC_CLEAN_STACK
191 int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
192 {
193 int err = _skipjack_ecb_encrypt(pt, ct, skey);
194 burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2);
195 return err;
196 }
197 #endif
198
199 /**
200 Decrypts a block of text with Skipjack
201 @param ct The input ciphertext (8 bytes)
202 @param pt The output plaintext (8 bytes)
203 @param skey The key as scheduled
204 @return CRYPT_OK if successful
205 */
206 #ifdef LTC_CLEAN_STACK
207 static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
208 #else
209 int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
210 #endif
211 {
212 unsigned w1,w2,w3,w4,tmp;
213 int x, kp;
214
215 LTC_ARGCHK(pt != NULL);
216 LTC_ARGCHK(ct != NULL);
217 LTC_ARGCHK(skey != NULL);
218
219 /* load block */
220 w1 = ((unsigned)ct[0]<<8)|ct[1];
221 w2 = ((unsigned)ct[2]<<8)|ct[3];
222 w3 = ((unsigned)ct[4]<<8)|ct[5];
223 w4 = ((unsigned)ct[6]<<8)|ct[7];
224
225 /* 8 rounds of RULE B^-1
226
227 Note the value "kp = 8" comes from "kp = (32 * 4) mod 10" where 32*4 is 128 which mod 10 is 8
228 */
229 for (x = 32, kp = 8; x > 24; x--) {
230 RULE_B1;
231 }
232
233 /* 8 rounds of RULE A^-1 */
234 for (; x > 16; x--) {
235 RULE_A1;
236 }
237
238
239 /* 8 rounds of RULE B^-1 */
240 for (; x > 8; x--) {
241 RULE_B1;
242 }
243
244 /* 8 rounds of RULE A^-1 */
245 for (; x > 0; x--) {
246 RULE_A1;
247 }
248
249 /* store block */
250 pt[0] = (w1>>8)&255; pt[1] = w1&255;
251 pt[2] = (w2>>8)&255; pt[3] = w2&255;
252 pt[4] = (w3>>8)&255; pt[5] = w3&255;
253 pt[6] = (w4>>8)&255; pt[7] = w4&255;
254
255 return CRYPT_OK;
256 }
257
258 #ifdef LTC_CLEAN_STACK
259 int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
260 {
261 int err = _skipjack_ecb_decrypt(ct, pt, skey);
262 burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2);
263 return err;
264 }
265 #endif
266
267 /**
268 Performs a self-test of the Skipjack block cipher
269 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
270 */
271 int skipjack_test(void)
272 {
273 #ifndef LTC_TEST
274 return CRYPT_NOP;
275 #else
276 static const struct {
277 unsigned char key[10], pt[8], ct[8];
278 } tests[] = {
279 {
280 { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 },
281 { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa },
282 { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 }
283 }
284 };
285 unsigned char buf[2][8];
286 int x, y, err;
287 symmetric_key key;
288
289 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
290 /* setup key */
291 if ((err = skipjack_setup(tests[x].key, 10, 0, &key)) != CRYPT_OK) {
292 return err;
293 }
294
295 /* encrypt and decrypt */
296 skipjack_ecb_encrypt(tests[x].pt, buf[0], &key);
297 skipjack_ecb_decrypt(buf[0], buf[1], &key);
298
299 /* compare */
300 if (XMEMCMP(buf[0], tests[x].ct, 8) != 0 || XMEMCMP(buf[1], tests[x].pt, 8) != 0) {
301 return CRYPT_FAIL_TESTVECTOR;
302 }
303
304 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
305 for (y = 0; y < 8; y++) buf[0][y] = 0;
306 for (y = 0; y < 1000; y++) skipjack_ecb_encrypt(buf[0], buf[0], &key);
307 for (y = 0; y < 1000; y++) skipjack_ecb_decrypt(buf[0], buf[0], &key);
308 for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
309 }
310
311 return CRYPT_OK;
312 #endif
313 }
314
315 /** Terminate the context
316 @param skey The scheduled key
317 */
318 void skipjack_done(symmetric_key *skey)
319 {
320 }
321
322 /**
323 Gets suitable key size
324 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
325 @return CRYPT_OK if the input key size is acceptable.
326 */
327 int skipjack_keysize(int *keysize)
328 {
329 LTC_ARGCHK(keysize != NULL);
330 if (*keysize < 10) {
331 return CRYPT_INVALID_KEYSIZE;
332 } else if (*keysize > 10) {
333 *keysize = 10;
334 }
335 return CRYPT_OK;
336 }
337
338 #endif
339
340 /* $Source$ */
341 /* $Revision$ */
342 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file twofish.c
13 Implementation of Twofish by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_TWOFISH
18
19 /* first LTC_TWOFISH_ALL_TABLES must ensure LTC_TWOFISH_TABLES is defined */
20 #ifdef LTC_TWOFISH_ALL_TABLES
21 #ifndef LTC_TWOFISH_TABLES
22 #define LTC_TWOFISH_TABLES
23 #endif
24 #endif
25
26 const struct ltc_cipher_descriptor twofish_desc =
27 {
28 "twofish",
29 7,
30 16, 32, 16, 16,
31 &twofish_setup,
32 &twofish_ecb_encrypt,
33 &twofish_ecb_decrypt,
34 &twofish_test,
35 &twofish_done,
36 &twofish_keysize,
37 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
38 };
39
40 /* the two polynomials */
41 #define MDS_POLY 0x169
42 #define RS_POLY 0x14D
43
44 /* The 4x8 RS Linear Transform */
45 static const unsigned char RS[4][8] = {
46 { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E },
47 { 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 },
48 { 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 },
49 { 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 }
50 };
51
52 #ifdef LTC_TWOFISH_SMALL
53 /* sbox usage orderings */
54 static const unsigned char qord[4][5] = {
55 { 1, 1, 0, 0, 1 },
56 { 0, 1, 1, 0, 0 },
57 { 0, 0, 0, 1, 1 },
58 { 1, 0, 1, 1, 0 }
59 };
60 #endif /* LTC_TWOFISH_SMALL */
61
62 #ifdef LTC_TWOFISH_TABLES
63
64 #include "twofish_tab.c.inc"
65
66 #define sbox(i, x) ((ulong32)SBOX[i][(x)&255])
67
68 #else
69
70 /* The Q-box tables */
71 static const unsigned char qbox[2][4][16] = {
72 {
73 { 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 },
74 { 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD },
75 { 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 },
76 { 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA }
77 },
78 {
79 { 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 },
80 { 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 },
81 { 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF },
82 { 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA }
83 }
84 };
85
86 /* computes S_i[x] */
87 #ifdef LTC_CLEAN_STACK
88 static ulong32 _sbox(int i, ulong32 x)
89 #else
90 static ulong32 sbox(int i, ulong32 x)
91 #endif
92 {
93 unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y;
94
95 /* a0,b0 = [x/16], x mod 16 */
96 a0 = (unsigned char)((x>>4)&15);
97 b0 = (unsigned char)((x)&15);
98
99 /* a1 = a0 ^ b0 */
100 a1 = a0 ^ b0;
101
102 /* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */
103 b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15;
104
105 /* a2,b2 = t0[a1], t1[b1] */
106 a2 = qbox[i][0][(int)a1];
107 b2 = qbox[i][1][(int)b1];
108
109 /* a3 = a2 ^ b2 */
110 a3 = a2 ^ b2;
111
112 /* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */
113 b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15;
114
115 /* a4,b4 = t2[a3], t3[b3] */
116 a4 = qbox[i][2][(int)a3];
117 b4 = qbox[i][3][(int)b3];
118
119 /* y = 16b4 + a4 */
120 y = (b4 << 4) + a4;
121
122 /* return result */
123 return (ulong32)y;
124 }
125
126 #ifdef LTC_CLEAN_STACK
127 static ulong32 sbox(int i, ulong32 x)
128 {
129 ulong32 y;
130 y = _sbox(i, x);
131 burn_stack(sizeof(unsigned char) * 11);
132 return y;
133 }
134 #endif /* LTC_CLEAN_STACK */
135
136 #endif /* LTC_TWOFISH_TABLES */
137
138 /* computes ab mod p */
139 static ulong32 gf_mult(ulong32 a, ulong32 b, ulong32 p)
140 {
141 ulong32 result, B[2], P[2];
142
143 P[1] = p;
144 B[1] = b;
145 result = P[0] = B[0] = 0;
146
147 /* unrolled branchless GF multiplier */
148 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
149 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
150 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
151 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
152 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
153 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
154 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
155 result ^= B[a&1];
156
157 return result;
158 }
159
160 /* computes [y0 y1 y2 y3] = MDS . [x0] */
161 #ifndef LTC_TWOFISH_TABLES
162 static ulong32 mds_column_mult(unsigned char in, int col)
163 {
164 ulong32 x01, x5B, xEF;
165
166 x01 = in;
167 x5B = gf_mult(in, 0x5B, MDS_POLY);
168 xEF = gf_mult(in, 0xEF, MDS_POLY);
169
170 switch (col) {
171 case 0:
172 return (x01 << 0 ) |
173 (x5B << 8 ) |
174 (xEF << 16) |
175 (xEF << 24);
176 case 1:
177 return (xEF << 0 ) |
178 (xEF << 8 ) |
179 (x5B << 16) |
180 (x01 << 24);
181 case 2:
182 return (x5B << 0 ) |
183 (xEF << 8 ) |
184 (x01 << 16) |
185 (xEF << 24);
186 case 3:
187 return (x5B << 0 ) |
188 (x01 << 8 ) |
189 (xEF << 16) |
190 (x5B << 24);
191 }
192 /* avoid warnings, we'd never get here normally but just to calm compiler warnings... */
193 return 0;
194 }
195
196 #else /* !LTC_TWOFISH_TABLES */
197
198 #define mds_column_mult(x, i) mds_tab[i][x]
199
200 #endif /* LTC_TWOFISH_TABLES */
201
202 /* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */
203 static void mds_mult(const unsigned char *in, unsigned char *out)
204 {
205 int x;
206 ulong32 tmp;
207 for (tmp = x = 0; x < 4; x++) {
208 tmp ^= mds_column_mult(in[x], x);
209 }
210 STORE32L(tmp, out);
211 }
212
213 #ifdef LTC_TWOFISH_ALL_TABLES
214 /* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
215 static void rs_mult(const unsigned char *in, unsigned char *out)
216 {
217 ulong32 tmp;
218 tmp = rs_tab0[in[0]] ^ rs_tab1[in[1]] ^ rs_tab2[in[2]] ^ rs_tab3[in[3]] ^
219 rs_tab4[in[4]] ^ rs_tab5[in[5]] ^ rs_tab6[in[6]] ^ rs_tab7[in[7]];
220 STORE32L(tmp, out);
221 }
222
223 #else /* !LTC_TWOFISH_ALL_TABLES */
224
225 /* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
226 static void rs_mult(const unsigned char *in, unsigned char *out)
227 {
228 int x, y;
229 for (x = 0; x < 4; x++) {
230 out[x] = 0;
231 for (y = 0; y < 8; y++) {
232 out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY);
233 }
234 }
235 }
236
237 #endif
238
239 /* computes h(x) */
240 static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset)
241 {
242 int x;
243 unsigned char y[4];
244 for (x = 0; x < 4; x++) {
245 y[x] = in[x];
246 }
247 switch (k) {
248 case 4:
249 y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]);
250 y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]);
251 y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]);
252 y[3] = (unsigned char)(sbox(1, (ulong32)y[3]) ^ M[4 * (6 + offset) + 3]);
253 case 3:
254 y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (4 + offset) + 0]);
255 y[1] = (unsigned char)(sbox(1, (ulong32)y[1]) ^ M[4 * (4 + offset) + 1]);
256 y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (4 + offset) + 2]);
257 y[3] = (unsigned char)(sbox(0, (ulong32)y[3]) ^ M[4 * (4 + offset) + 3]);
258 case 2:
259 y[0] = (unsigned char)(sbox(1, sbox(0, sbox(0, (ulong32)y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0]));
260 y[1] = (unsigned char)(sbox(0, sbox(0, sbox(1, (ulong32)y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1]));
261 y[2] = (unsigned char)(sbox(1, sbox(1, sbox(0, (ulong32)y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2]));
262 y[3] = (unsigned char)(sbox(0, sbox(1, sbox(1, (ulong32)y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3]));
263 }
264 mds_mult(y, out);
265 }
266
267 #ifndef LTC_TWOFISH_SMALL
268
269 /* for GCC we don't use pointer aliases */
270 #if defined(__GNUC__)
271 #define S1 skey->twofish.S[0]
272 #define S2 skey->twofish.S[1]
273 #define S3 skey->twofish.S[2]
274 #define S4 skey->twofish.S[3]
275 #endif
276
277 /* the G function */
278 #define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)])
279 #define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)])
280
281 #else
282
283 #ifdef LTC_CLEAN_STACK
284 static ulong32 _g_func(ulong32 x, symmetric_key *key)
285 #else
286 static ulong32 g_func(ulong32 x, symmetric_key *key)
287 #endif
288 {
289 unsigned char g, i, y, z;
290 ulong32 res;
291
292 res = 0;
293 for (y = 0; y < 4; y++) {
294 z = key->twofish.start;
295
296 /* do unkeyed substitution */
297 g = sbox(qord[y][z++], (x >> (8*y)) & 255);
298
299 /* first subkey */
300 i = 0;
301
302 /* do key mixing+sbox until z==5 */
303 while (z != 5) {
304 g = g ^ key->twofish.S[4*i++ + y];
305 g = sbox(qord[y][z++], g);
306 }
307
308 /* multiply g by a column of the MDS */
309 res ^= mds_column_mult(g, y);
310 }
311 return res;
312 }
313
314 #define g1_func(x, key) g_func(ROLc(x, 8), key)
315
316 #ifdef LTC_CLEAN_STACK
317 static ulong32 g_func(ulong32 x, symmetric_key *key)
318 {
319 ulong32 y;
320 y = _g_func(x, key);
321 burn_stack(sizeof(unsigned char) * 4 + sizeof(ulong32));
322 return y;
323 }
324 #endif /* LTC_CLEAN_STACK */
325
326 #endif /* LTC_TWOFISH_SMALL */
327
328 /**
329 Initialize the Twofish block cipher
330 @param key The symmetric key you wish to pass
331 @param keylen The key length in bytes
332 @param num_rounds The number of rounds desired (0 for default)
333 @param skey The key in as scheduled by this function.
334 @return CRYPT_OK if successful
335 */
336 #ifdef LTC_CLEAN_STACK
337 static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
338 #else
339 int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
340 #endif
341 {
342 #ifndef LTC_TWOFISH_SMALL
343 unsigned char S[4*4], tmpx0, tmpx1;
344 #endif
345 int k, x, y;
346 unsigned char tmp[4], tmp2[4], M[8*4];
347 ulong32 A, B;
348
349 LTC_ARGCHK(key != NULL);
350 LTC_ARGCHK(skey != NULL);
351
352 /* invalid arguments? */
353 if (num_rounds != 16 && num_rounds != 0) {
354 return CRYPT_INVALID_ROUNDS;
355 }
356
357 if (keylen != 16 && keylen != 24 && keylen != 32) {
358 return CRYPT_INVALID_KEYSIZE;
359 }
360
361 /* k = keysize/64 [but since our keysize is in bytes...] */
362 k = keylen / 8;
363
364 /* copy the key into M */
365 for (x = 0; x < keylen; x++) {
366 M[x] = key[x] & 255;
367 }
368
369 /* create the S[..] words */
370 #ifndef LTC_TWOFISH_SMALL
371 for (x = 0; x < k; x++) {
372 rs_mult(M+(x*8), S+(x*4));
373 }
374 #else
375 for (x = 0; x < k; x++) {
376 rs_mult(M+(x*8), skey->twofish.S+(x*4));
377 }
378 #endif
379
380 /* make subkeys */
381 for (x = 0; x < 20; x++) {
382 /* A = h(p * 2x, Me) */
383 for (y = 0; y < 4; y++) {
384 tmp[y] = x+x;
385 }
386 h_func(tmp, tmp2, M, k, 0);
387 LOAD32L(A, tmp2);
388
389 /* B = ROL(h(p * (2x + 1), Mo), 8) */
390 for (y = 0; y < 4; y++) {
391 tmp[y] = (unsigned char)(x+x+1);
392 }
393 h_func(tmp, tmp2, M, k, 1);
394 LOAD32L(B, tmp2);
395 B = ROLc(B, 8);
396
397 /* K[2i] = A + B */
398 skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL;
399
400 /* K[2i+1] = (A + 2B) <<< 9 */
401 skey->twofish.K[x+x+1] = ROLc(B + B + A, 9);
402 }
403
404 #ifndef LTC_TWOFISH_SMALL
405 /* make the sboxes (large ram variant) */
406 if (k == 2) {
407 for (x = 0; x < 256; x++) {
408 tmpx0 = (unsigned char)sbox(0, x);
409 tmpx1 = (unsigned char)sbox(1, x);
410 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0);
411 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1);
412 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2);
413 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3);
414 }
415 } else if (k == 3) {
416 for (x = 0; x < 256; x++) {
417 tmpx0 = (unsigned char)sbox(0, x);
418 tmpx1 = (unsigned char)sbox(1, x);
419 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0);
420 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1);
421 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2);
422 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3);
423 }
424 } else {
425 for (x = 0; x < 256; x++) {
426 tmpx0 = (unsigned char)sbox(0, x);
427 tmpx1 = (unsigned char)sbox(1, x);
428 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0);
429 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1);
430 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2);
431 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3);
432 }
433 }
434 #else
435 /* where to start in the sbox layers */
436 /* small ram variant */
437 switch (k) {
438 case 4 : skey->twofish.start = 0; break;
439 case 3 : skey->twofish.start = 1; break;
440 default: skey->twofish.start = 2; break;
441 }
442 #endif
443 return CRYPT_OK;
444 }
445
446 #ifdef LTC_CLEAN_STACK
447 int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
448 {
449 int x;
450 x = _twofish_setup(key, keylen, num_rounds, skey);
451 burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(ulong32) * 2);
452 return x;
453 }
454 #endif
455
456 /**
457 Encrypts a block of text with Twofish
458 @param pt The input plaintext (16 bytes)
459 @param ct The output ciphertext (16 bytes)
460 @param skey The key as scheduled
461 @return CRYPT_OK if successful
462 */
463 #ifdef LTC_CLEAN_STACK
464 static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
465 #else
466 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
467 #endif
468 {
469 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
470 int r;
471 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
472 ulong32 *S1, *S2, *S3, *S4;
473 #endif
474
475 LTC_ARGCHK(pt != NULL);
476 LTC_ARGCHK(ct != NULL);
477 LTC_ARGCHK(skey != NULL);
478
479 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
480 S1 = skey->twofish.S[0];
481 S2 = skey->twofish.S[1];
482 S3 = skey->twofish.S[2];
483 S4 = skey->twofish.S[3];
484 #endif
485
486 LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);
487 LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);
488 a ^= skey->twofish.K[0];
489 b ^= skey->twofish.K[1];
490 c ^= skey->twofish.K[2];
491 d ^= skey->twofish.K[3];
492
493 k = skey->twofish.K + 8;
494 for (r = 8; r != 0; --r) {
495 t2 = g1_func(b, skey);
496 t1 = g_func(a, skey) + t2;
497 c = RORc(c ^ (t1 + k[0]), 1);
498 d = ROLc(d, 1) ^ (t2 + t1 + k[1]);
499
500 t2 = g1_func(d, skey);
501 t1 = g_func(c, skey) + t2;
502 a = RORc(a ^ (t1 + k[2]), 1);
503 b = ROLc(b, 1) ^ (t2 + t1 + k[3]);
504 k += 4;
505 }
506
507 /* output with "undo last swap" */
508 ta = c ^ skey->twofish.K[4];
509 tb = d ^ skey->twofish.K[5];
510 tc = a ^ skey->twofish.K[6];
511 td = b ^ skey->twofish.K[7];
512
513 /* store output */
514 STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
515 STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
516
517 return CRYPT_OK;
518 }
519
520 #ifdef LTC_CLEAN_STACK
521 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
522 {
523 int err = _twofish_ecb_encrypt(pt, ct, skey);
524 burn_stack(sizeof(ulong32) * 10 + sizeof(int));
525 return err;
526 }
527 #endif
528
529 /**
530 Decrypts a block of text with Twofish
531 @param ct The input ciphertext (16 bytes)
532 @param pt The output plaintext (16 bytes)
533 @param skey The key as scheduled
534 @return CRYPT_OK if successful
535 */
536 #ifdef LTC_CLEAN_STACK
537 static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
538 #else
539 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
540 #endif
541 {
542 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
543 int r;
544 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
545 ulong32 *S1, *S2, *S3, *S4;
546 #endif
547
548 LTC_ARGCHK(pt != NULL);
549 LTC_ARGCHK(ct != NULL);
550 LTC_ARGCHK(skey != NULL);
551
552 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
553 S1 = skey->twofish.S[0];
554 S2 = skey->twofish.S[1];
555 S3 = skey->twofish.S[2];
556 S4 = skey->twofish.S[3];
557 #endif
558
559 /* load input */
560 LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]);
561 LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]);
562
563 /* undo undo final swap */
564 a = tc ^ skey->twofish.K[6];
565 b = td ^ skey->twofish.K[7];
566 c = ta ^ skey->twofish.K[4];
567 d = tb ^ skey->twofish.K[5];
568
569 k = skey->twofish.K + 36;
570 for (r = 8; r != 0; --r) {
571 t2 = g1_func(d, skey);
572 t1 = g_func(c, skey) + t2;
573 a = ROLc(a, 1) ^ (t1 + k[2]);
574 b = RORc(b ^ (t2 + t1 + k[3]), 1);
575
576 t2 = g1_func(b, skey);
577 t1 = g_func(a, skey) + t2;
578 c = ROLc(c, 1) ^ (t1 + k[0]);
579 d = RORc(d ^ (t2 + t1 + k[1]), 1);
580 k -= 4;
581 }
582
583 /* pre-white */
584 a ^= skey->twofish.K[0];
585 b ^= skey->twofish.K[1];
586 c ^= skey->twofish.K[2];
587 d ^= skey->twofish.K[3];
588
589 /* store */
590 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
591 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
592 return CRYPT_OK;
593 }
594
595 #ifdef LTC_CLEAN_STACK
596 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
597 {
598 int err =_twofish_ecb_decrypt(ct, pt, skey);
599 burn_stack(sizeof(ulong32) * 10 + sizeof(int));
600 return err;
601 }
602 #endif
603
604 /**
605 Performs a self-test of the Twofish block cipher
606 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
607 */
608 int twofish_test(void)
609 {
610 #ifndef LTC_TEST
611 return CRYPT_NOP;
612 #else
613 static const struct {
614 int keylen;
615 unsigned char key[32], pt[16], ct[16];
616 } tests[] = {
617 { 16,
618 { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
619 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A },
620 { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
621 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 },
622 { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
623 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 }
624 }, {
625 24,
626 { 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,
627 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
628 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 },
629 { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
630 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 },
631 { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
632 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 }
633 }, {
634 32,
635 { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
636 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
637 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
638 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F },
639 { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
640 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 },
641 { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
642 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA }
643 }
644 };
645
646
647 symmetric_key key;
648 unsigned char tmp[2][16];
649 int err, i, y;
650
651 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
652 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
653 return err;
654 }
655 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key);
656 twofish_ecb_decrypt(tmp[0], tmp[1], &key);
657 if (XMEMCMP(tmp[0], tests[i].ct, 16) != 0 || XMEMCMP(tmp[1], tests[i].pt, 16) != 0) {
658 #if 0
659 printf("Twofish failed test %d, %d, %d\n", i, XMEMCMP(tmp[0], tests[i].ct, 16), XMEMCMP(tmp[1], tests[i].pt, 16));
660 #endif
661 return CRYPT_FAIL_TESTVECTOR;
662 }
663 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
664 for (y = 0; y < 16; y++) tmp[0][y] = 0;
665 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key);
666 for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key);
667 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
668 }
669 return CRYPT_OK;
670 #endif
671 }
672
673 /** Terminate the context
674 @param skey The scheduled key
675 */
676 void twofish_done(symmetric_key *skey)
677 {
678 }
679
680 /**
681 Gets suitable key size
682 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
683 @return CRYPT_OK if the input key size is acceptable.
684 */
685 int twofish_keysize(int *keysize)
686 {
687 LTC_ARGCHK(keysize);
688 if (*keysize < 16)
689 return CRYPT_INVALID_KEYSIZE;
690 if (*keysize < 24) {
691 *keysize = 16;
692 return CRYPT_OK;
693 } else if (*keysize < 32) {
694 *keysize = 24;
695 return CRYPT_OK;
696 } else {
697 *keysize = 32;
698 return CRYPT_OK;
699 }
700 }
701
702 #endif
703
704
705
706
707 /* $Source$ */
708 /* $Revision$ */
709 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file twofish_tab.c
13 Twofish tables, Tom St Denis
14 */
15 #ifdef LTC_TWOFISH_TABLES
16
17 /* pre generated 8x8 tables from the four 4x4s */
18 static const unsigned char SBOX[2][256] = {
19 {
20 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92,
21 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98,
22 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13,
23 0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23,
24 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01,
25 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe,
26 0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c,
27 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
28 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95,
29 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5,
30 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9,
31 0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8,
32 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d,
33 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11,
34 0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c,
35 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
36 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87,
37 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f,
38 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e,
39 0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02,
40 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7,
41 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12,
42 0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc,
43 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
44 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d,
45 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0},
46 {
47 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3,
48 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd,
49 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa,
50 0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d,
51 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84,
52 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54,
53 0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60,
54 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
55 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3,
56 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff,
57 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7,
58 0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9,
59 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94,
60 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c,
61 0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76,
62 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
63 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23,
64 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e,
65 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f,
66 0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5,
67 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e,
68 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34,
69 0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4,
70 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
71 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25,
72 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91}
73 };
74
75 /* the 4x4 MDS in a nicer format */
76 static const ulong32 mds_tab[4][256] = {
77 {
78 0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL,
79 0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL,
80 0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL,
81 0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL,
82 0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL,
83 0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL,
84 0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL,
85 0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL,
86 0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL,
87 0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL,
88 0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL,
89 0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL,
90 0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL,
91 0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL,
92 0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL,
93 0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL,
94 0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL,
95 0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL,
96 0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL,
97 0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL,
98 0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL,
99 0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL,
100 0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL,
101 0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL,
102 0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL,
103 0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL,
104 0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL,
105 0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL,
106 0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL,
107 0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL,
108 0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL,
109 0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL
110 },
111 {
112 0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL,
113 0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL,
114 0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL,
115 0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL,
116 0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL,
117 0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL,
118 0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL,
119 0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL,
120 0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL,
121 0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL,
122 0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL,
123 0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL,
124 0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL,
125 0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL,
126 0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL,
127 0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL,
128 0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL,
129 0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL,
130 0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL,
131 0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL,
132 0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL,
133 0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL,
134 0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL,
135 0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL,
136 0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL,
137 0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL,
138 0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL,
139 0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL,
140 0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL,
141 0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL,
142 0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL,
143 0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL
144 },
145 {
146 0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL,
147 0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL,
148 0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL,
149 0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL,
150 0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL,
151 0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL,
152 0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL,
153 0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL,
154 0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL,
155 0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL,
156 0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL,
157 0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL,
158 0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL,
159 0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL,
160 0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL,
161 0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL,
162 0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL,
163 0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL,
164 0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL,
165 0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL,
166 0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL,
167 0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL,
168 0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL,
169 0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL,
170 0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL,
171 0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL,
172 0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL,
173 0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL,
174 0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL,
175 0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL,
176 0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL,
177 0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL
178 },
179 {
180 0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL,
181 0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL,
182 0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL,
183 0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL,
184 0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL,
185 0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL,
186 0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL,
187 0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL,
188 0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL,
189 0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL,
190 0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL,
191 0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL,
192 0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL,
193 0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL,
194 0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL,
195 0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL,
196 0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL,
197 0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL,
198 0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL,
199 0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL,
200 0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL,
201 0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL,
202 0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL,
203 0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL,
204 0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL,
205 0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL,
206 0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL,
207 0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL,
208 0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL,
209 0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL,
210 0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL,
211 0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL
212 }};
213
214 #ifdef LTC_TWOFISH_ALL_TABLES
215
216 /* the 4x8 RS transform */
217 static const ulong32 rs_tab0[256] = {
218 0x00000000LU, 0xa402a401LU, 0x05040502LU, 0xa106a103LU, 0x0a080a04LU, 0xae0aae05LU, 0x0f0c0f06LU, 0xab0eab07LU,
219 0x14101408LU, 0xb012b009LU, 0x1114110aLU, 0xb516b50bLU, 0x1e181e0cLU, 0xba1aba0dLU, 0x1b1c1b0eLU, 0xbf1ebf0fLU,
220 0x28202810LU, 0x8c228c11LU, 0x2d242d12LU, 0x89268913LU, 0x22282214LU, 0x862a8615LU, 0x272c2716LU, 0x832e8317LU,
221 0x3c303c18LU, 0x98329819LU, 0x3934391aLU, 0x9d369d1bLU, 0x3638361cLU, 0x923a921dLU, 0x333c331eLU, 0x973e971fLU,
222 0x50405020LU, 0xf442f421LU, 0x55445522LU, 0xf146f123LU, 0x5a485a24LU, 0xfe4afe25LU, 0x5f4c5f26LU, 0xfb4efb27LU,
223 0x44504428LU, 0xe052e029LU, 0x4154412aLU, 0xe556e52bLU, 0x4e584e2cLU, 0xea5aea2dLU, 0x4b5c4b2eLU, 0xef5eef2fLU,
224 0x78607830LU, 0xdc62dc31LU, 0x7d647d32LU, 0xd966d933LU, 0x72687234LU, 0xd66ad635LU, 0x776c7736LU, 0xd36ed337LU,
225 0x6c706c38LU, 0xc872c839LU, 0x6974693aLU, 0xcd76cd3bLU, 0x6678663cLU, 0xc27ac23dLU, 0x637c633eLU, 0xc77ec73fLU,
226 0xa080a040LU, 0x04820441LU, 0xa584a542LU, 0x01860143LU, 0xaa88aa44LU, 0x0e8a0e45LU, 0xaf8caf46LU, 0x0b8e0b47LU,
227 0xb490b448LU, 0x10921049LU, 0xb194b14aLU, 0x1596154bLU, 0xbe98be4cLU, 0x1a9a1a4dLU, 0xbb9cbb4eLU, 0x1f9e1f4fLU,
228 0x88a08850LU, 0x2ca22c51LU, 0x8da48d52LU, 0x29a62953LU, 0x82a88254LU, 0x26aa2655LU, 0x87ac8756LU, 0x23ae2357LU,
229 0x9cb09c58LU, 0x38b23859LU, 0x99b4995aLU, 0x3db63d5bLU, 0x96b8965cLU, 0x32ba325dLU, 0x93bc935eLU, 0x37be375fLU,
230 0xf0c0f060LU, 0x54c25461LU, 0xf5c4f562LU, 0x51c65163LU, 0xfac8fa64LU, 0x5eca5e65LU, 0xffccff66LU, 0x5bce5b67LU,
231 0xe4d0e468LU, 0x40d24069LU, 0xe1d4e16aLU, 0x45d6456bLU, 0xeed8ee6cLU, 0x4ada4a6dLU, 0xebdceb6eLU, 0x4fde4f6fLU,
232 0xd8e0d870LU, 0x7ce27c71LU, 0xdde4dd72LU, 0x79e67973LU, 0xd2e8d274LU, 0x76ea7675LU, 0xd7ecd776LU, 0x73ee7377LU,
233 0xccf0cc78LU, 0x68f26879LU, 0xc9f4c97aLU, 0x6df66d7bLU, 0xc6f8c67cLU, 0x62fa627dLU, 0xc3fcc37eLU, 0x67fe677fLU,
234 0x0d4d0d80LU, 0xa94fa981LU, 0x08490882LU, 0xac4bac83LU, 0x07450784LU, 0xa347a385LU, 0x02410286LU, 0xa643a687LU,
235 0x195d1988LU, 0xbd5fbd89LU, 0x1c591c8aLU, 0xb85bb88bLU, 0x1355138cLU, 0xb757b78dLU, 0x1651168eLU, 0xb253b28fLU,
236 0x256d2590LU, 0x816f8191LU, 0x20692092LU, 0x846b8493LU, 0x2f652f94LU, 0x8b678b95LU, 0x2a612a96LU, 0x8e638e97LU,
237 0x317d3198LU, 0x957f9599LU, 0x3479349aLU, 0x907b909bLU, 0x3b753b9cLU, 0x9f779f9dLU, 0x3e713e9eLU, 0x9a739a9fLU,
238 0x5d0d5da0LU, 0xf90ff9a1LU, 0x580958a2LU, 0xfc0bfca3LU, 0x570557a4LU, 0xf307f3a5LU, 0x520152a6LU, 0xf603f6a7LU,
239 0x491d49a8LU, 0xed1feda9LU, 0x4c194caaLU, 0xe81be8abLU, 0x431543acLU, 0xe717e7adLU, 0x461146aeLU, 0xe213e2afLU,
240 0x752d75b0LU, 0xd12fd1b1LU, 0x702970b2LU, 0xd42bd4b3LU, 0x7f257fb4LU, 0xdb27dbb5LU, 0x7a217ab6LU, 0xde23deb7LU,
241 0x613d61b8LU, 0xc53fc5b9LU, 0x643964baLU, 0xc03bc0bbLU, 0x6b356bbcLU, 0xcf37cfbdLU, 0x6e316ebeLU, 0xca33cabfLU,
242 0xadcdadc0LU, 0x09cf09c1LU, 0xa8c9a8c2LU, 0x0ccb0cc3LU, 0xa7c5a7c4LU, 0x03c703c5LU, 0xa2c1a2c6LU, 0x06c306c7LU,
243 0xb9ddb9c8LU, 0x1ddf1dc9LU, 0xbcd9bccaLU, 0x18db18cbLU, 0xb3d5b3ccLU, 0x17d717cdLU, 0xb6d1b6ceLU, 0x12d312cfLU,
244 0x85ed85d0LU, 0x21ef21d1LU, 0x80e980d2LU, 0x24eb24d3LU, 0x8fe58fd4LU, 0x2be72bd5LU, 0x8ae18ad6LU, 0x2ee32ed7LU,
245 0x91fd91d8LU, 0x35ff35d9LU, 0x94f994daLU, 0x30fb30dbLU, 0x9bf59bdcLU, 0x3ff73fddLU, 0x9ef19edeLU, 0x3af33adfLU,
246 0xfd8dfde0LU, 0x598f59e1LU, 0xf889f8e2LU, 0x5c8b5ce3LU, 0xf785f7e4LU, 0x538753e5LU, 0xf281f2e6LU, 0x568356e7LU,
247 0xe99de9e8LU, 0x4d9f4de9LU, 0xec99eceaLU, 0x489b48ebLU, 0xe395e3ecLU, 0x479747edLU, 0xe691e6eeLU, 0x429342efLU,
248 0xd5add5f0LU, 0x71af71f1LU, 0xd0a9d0f2LU, 0x74ab74f3LU, 0xdfa5dff4LU, 0x7ba77bf5LU, 0xdaa1daf6LU, 0x7ea37ef7LU,
249 0xc1bdc1f8LU, 0x65bf65f9LU, 0xc4b9c4faLU, 0x60bb60fbLU, 0xcbb5cbfcLU, 0x6fb76ffdLU, 0xceb1cefeLU, 0x6ab36affLU };
250
251 static const ulong32 rs_tab1[256] = {
252 0x00000000LU, 0x55a156a4LU, 0xaa0fac05LU, 0xffaefaa1LU, 0x191e150aLU, 0x4cbf43aeLU, 0xb311b90fLU, 0xe6b0efabLU,
253 0x323c2a14LU, 0x679d7cb0LU, 0x98338611LU, 0xcd92d0b5LU, 0x2b223f1eLU, 0x7e8369baLU, 0x812d931bLU, 0xd48cc5bfLU,
254 0x64785428LU, 0x31d9028cLU, 0xce77f82dLU, 0x9bd6ae89LU, 0x7d664122LU, 0x28c71786LU, 0xd769ed27LU, 0x82c8bb83LU,
255 0x56447e3cLU, 0x03e52898LU, 0xfc4bd239LU, 0xa9ea849dLU, 0x4f5a6b36LU, 0x1afb3d92LU, 0xe555c733LU, 0xb0f49197LU,
256 0xc8f0a850LU, 0x9d51fef4LU, 0x62ff0455LU, 0x375e52f1LU, 0xd1eebd5aLU, 0x844febfeLU, 0x7be1115fLU, 0x2e4047fbLU,
257 0xfacc8244LU, 0xaf6dd4e0LU, 0x50c32e41LU, 0x056278e5LU, 0xe3d2974eLU, 0xb673c1eaLU, 0x49dd3b4bLU, 0x1c7c6defLU,
258 0xac88fc78LU, 0xf929aadcLU, 0x0687507dLU, 0x532606d9LU, 0xb596e972LU, 0xe037bfd6LU, 0x1f994577LU, 0x4a3813d3LU,
259 0x9eb4d66cLU, 0xcb1580c8LU, 0x34bb7a69LU, 0x611a2ccdLU, 0x87aac366LU, 0xd20b95c2LU, 0x2da56f63LU, 0x780439c7LU,
260 0xddad1da0LU, 0x880c4b04LU, 0x77a2b1a5LU, 0x2203e701LU, 0xc4b308aaLU, 0x91125e0eLU, 0x6ebca4afLU, 0x3b1df20bLU,
261 0xef9137b4LU, 0xba306110LU, 0x459e9bb1LU, 0x103fcd15LU, 0xf68f22beLU, 0xa32e741aLU, 0x5c808ebbLU, 0x0921d81fLU,
262 0xb9d54988LU, 0xec741f2cLU, 0x13dae58dLU, 0x467bb329LU, 0xa0cb5c82LU, 0xf56a0a26LU, 0x0ac4f087LU, 0x5f65a623LU,
263 0x8be9639cLU, 0xde483538LU, 0x21e6cf99LU, 0x7447993dLU, 0x92f77696LU, 0xc7562032LU, 0x38f8da93LU, 0x6d598c37LU,
264 0x155db5f0LU, 0x40fce354LU, 0xbf5219f5LU, 0xeaf34f51LU, 0x0c43a0faLU, 0x59e2f65eLU, 0xa64c0cffLU, 0xf3ed5a5bLU,
265 0x27619fe4LU, 0x72c0c940LU, 0x8d6e33e1LU, 0xd8cf6545LU, 0x3e7f8aeeLU, 0x6bdedc4aLU, 0x947026ebLU, 0xc1d1704fLU,
266 0x7125e1d8LU, 0x2484b77cLU, 0xdb2a4dddLU, 0x8e8b1b79LU, 0x683bf4d2LU, 0x3d9aa276LU, 0xc23458d7LU, 0x97950e73LU,
267 0x4319cbccLU, 0x16b89d68LU, 0xe91667c9LU, 0xbcb7316dLU, 0x5a07dec6LU, 0x0fa68862LU, 0xf00872c3LU, 0xa5a92467LU,
268 0xf7173a0dLU, 0xa2b66ca9LU, 0x5d189608LU, 0x08b9c0acLU, 0xee092f07LU, 0xbba879a3LU, 0x44068302LU, 0x11a7d5a6LU,
269 0xc52b1019LU, 0x908a46bdLU, 0x6f24bc1cLU, 0x3a85eab8LU, 0xdc350513LU, 0x899453b7LU, 0x763aa916LU, 0x239bffb2LU,
270 0x936f6e25LU, 0xc6ce3881LU, 0x3960c220LU, 0x6cc19484LU, 0x8a717b2fLU, 0xdfd02d8bLU, 0x207ed72aLU, 0x75df818eLU,
271 0xa1534431LU, 0xf4f21295LU, 0x0b5ce834LU, 0x5efdbe90LU, 0xb84d513bLU, 0xedec079fLU, 0x1242fd3eLU, 0x47e3ab9aLU,
272 0x3fe7925dLU, 0x6a46c4f9LU, 0x95e83e58LU, 0xc04968fcLU, 0x26f98757LU, 0x7358d1f3LU, 0x8cf62b52LU, 0xd9577df6LU,
273 0x0ddbb849LU, 0x587aeeedLU, 0xa7d4144cLU, 0xf27542e8LU, 0x14c5ad43LU, 0x4164fbe7LU, 0xbeca0146LU, 0xeb6b57e2LU,
274 0x5b9fc675LU, 0x0e3e90d1LU, 0xf1906a70LU, 0xa4313cd4LU, 0x4281d37fLU, 0x172085dbLU, 0xe88e7f7aLU, 0xbd2f29deLU,
275 0x69a3ec61LU, 0x3c02bac5LU, 0xc3ac4064LU, 0x960d16c0LU, 0x70bdf96bLU, 0x251cafcfLU, 0xdab2556eLU, 0x8f1303caLU,
276 0x2aba27adLU, 0x7f1b7109LU, 0x80b58ba8LU, 0xd514dd0cLU, 0x33a432a7LU, 0x66056403LU, 0x99ab9ea2LU, 0xcc0ac806LU,
277 0x18860db9LU, 0x4d275b1dLU, 0xb289a1bcLU, 0xe728f718LU, 0x019818b3LU, 0x54394e17LU, 0xab97b4b6LU, 0xfe36e212LU,
278 0x4ec27385LU, 0x1b632521LU, 0xe4cddf80LU, 0xb16c8924LU, 0x57dc668fLU, 0x027d302bLU, 0xfdd3ca8aLU, 0xa8729c2eLU,
279 0x7cfe5991LU, 0x295f0f35LU, 0xd6f1f594LU, 0x8350a330LU, 0x65e04c9bLU, 0x30411a3fLU, 0xcfefe09eLU, 0x9a4eb63aLU,
280 0xe24a8ffdLU, 0xb7ebd959LU, 0x484523f8LU, 0x1de4755cLU, 0xfb549af7LU, 0xaef5cc53LU, 0x515b36f2LU, 0x04fa6056LU,
281 0xd076a5e9LU, 0x85d7f34dLU, 0x7a7909ecLU, 0x2fd85f48LU, 0xc968b0e3LU, 0x9cc9e647LU, 0x63671ce6LU, 0x36c64a42LU,
282 0x8632dbd5LU, 0xd3938d71LU, 0x2c3d77d0LU, 0x799c2174LU, 0x9f2ccedfLU, 0xca8d987bLU, 0x352362daLU, 0x6082347eLU,
283 0xb40ef1c1LU, 0xe1afa765LU, 0x1e015dc4LU, 0x4ba00b60LU, 0xad10e4cbLU, 0xf8b1b26fLU, 0x071f48ceLU, 0x52be1e6aLU };
284
285 static const ulong32 rs_tab2[256] = {
286 0x00000000LU, 0x87fc8255LU, 0x43b549aaLU, 0xc449cbffLU, 0x86279219LU, 0x01db104cLU, 0xc592dbb3LU, 0x426e59e6LU,
287 0x414e6932LU, 0xc6b2eb67LU, 0x02fb2098LU, 0x8507a2cdLU, 0xc769fb2bLU, 0x4095797eLU, 0x84dcb281LU, 0x032030d4LU,
288 0x829cd264LU, 0x05605031LU, 0xc1299bceLU, 0x46d5199bLU, 0x04bb407dLU, 0x8347c228LU, 0x470e09d7LU, 0xc0f28b82LU,
289 0xc3d2bb56LU, 0x442e3903LU, 0x8067f2fcLU, 0x079b70a9LU, 0x45f5294fLU, 0xc209ab1aLU, 0x064060e5LU, 0x81bce2b0LU,
290 0x4975e9c8LU, 0xce896b9dLU, 0x0ac0a062LU, 0x8d3c2237LU, 0xcf527bd1LU, 0x48aef984LU, 0x8ce7327bLU, 0x0b1bb02eLU,
291 0x083b80faLU, 0x8fc702afLU, 0x4b8ec950LU, 0xcc724b05LU, 0x8e1c12e3LU, 0x09e090b6LU, 0xcda95b49LU, 0x4a55d91cLU,
292 0xcbe93bacLU, 0x4c15b9f9LU, 0x885c7206LU, 0x0fa0f053LU, 0x4dcea9b5LU, 0xca322be0LU, 0x0e7be01fLU, 0x8987624aLU,
293 0x8aa7529eLU, 0x0d5bd0cbLU, 0xc9121b34LU, 0x4eee9961LU, 0x0c80c087LU, 0x8b7c42d2LU, 0x4f35892dLU, 0xc8c90b78LU,
294 0x92ea9fddLU, 0x15161d88LU, 0xd15fd677LU, 0x56a35422LU, 0x14cd0dc4LU, 0x93318f91LU, 0x5778446eLU, 0xd084c63bLU,
295 0xd3a4f6efLU, 0x545874baLU, 0x9011bf45LU, 0x17ed3d10LU, 0x558364f6LU, 0xd27fe6a3LU, 0x16362d5cLU, 0x91caaf09LU,
296 0x10764db9LU, 0x978acfecLU, 0x53c30413LU, 0xd43f8646LU, 0x9651dfa0LU, 0x11ad5df5LU, 0xd5e4960aLU, 0x5218145fLU,
297 0x5138248bLU, 0xd6c4a6deLU, 0x128d6d21LU, 0x9571ef74LU, 0xd71fb692LU, 0x50e334c7LU, 0x94aaff38LU, 0x13567d6dLU,
298 0xdb9f7615LU, 0x5c63f440LU, 0x982a3fbfLU, 0x1fd6bdeaLU, 0x5db8e40cLU, 0xda446659LU, 0x1e0dada6LU, 0x99f12ff3LU,
299 0x9ad11f27LU, 0x1d2d9d72LU, 0xd964568dLU, 0x5e98d4d8LU, 0x1cf68d3eLU, 0x9b0a0f6bLU, 0x5f43c494LU, 0xd8bf46c1LU,
300 0x5903a471LU, 0xdeff2624LU, 0x1ab6eddbLU, 0x9d4a6f8eLU, 0xdf243668LU, 0x58d8b43dLU, 0x9c917fc2LU, 0x1b6dfd97LU,
301 0x184dcd43LU, 0x9fb14f16LU, 0x5bf884e9LU, 0xdc0406bcLU, 0x9e6a5f5aLU, 0x1996dd0fLU, 0xdddf16f0LU, 0x5a2394a5LU,
302 0x699973f7LU, 0xee65f1a2LU, 0x2a2c3a5dLU, 0xadd0b808LU, 0xefbee1eeLU, 0x684263bbLU, 0xac0ba844LU, 0x2bf72a11LU,
303 0x28d71ac5LU, 0xaf2b9890LU, 0x6b62536fLU, 0xec9ed13aLU, 0xaef088dcLU, 0x290c0a89LU, 0xed45c176LU, 0x6ab94323LU,
304 0xeb05a193LU, 0x6cf923c6LU, 0xa8b0e839LU, 0x2f4c6a6cLU, 0x6d22338aLU, 0xeadeb1dfLU, 0x2e977a20LU, 0xa96bf875LU,
305 0xaa4bc8a1LU, 0x2db74af4LU, 0xe9fe810bLU, 0x6e02035eLU, 0x2c6c5ab8LU, 0xab90d8edLU, 0x6fd91312LU, 0xe8259147LU,
306 0x20ec9a3fLU, 0xa710186aLU, 0x6359d395LU, 0xe4a551c0LU, 0xa6cb0826LU, 0x21378a73LU, 0xe57e418cLU, 0x6282c3d9LU,
307 0x61a2f30dLU, 0xe65e7158LU, 0x2217baa7LU, 0xa5eb38f2LU, 0xe7856114LU, 0x6079e341LU, 0xa43028beLU, 0x23ccaaebLU,
308 0xa270485bLU, 0x258cca0eLU, 0xe1c501f1LU, 0x663983a4LU, 0x2457da42LU, 0xa3ab5817LU, 0x67e293e8LU, 0xe01e11bdLU,
309 0xe33e2169LU, 0x64c2a33cLU, 0xa08b68c3LU, 0x2777ea96LU, 0x6519b370LU, 0xe2e53125LU, 0x26acfadaLU, 0xa150788fLU,
310 0xfb73ec2aLU, 0x7c8f6e7fLU, 0xb8c6a580LU, 0x3f3a27d5LU, 0x7d547e33LU, 0xfaa8fc66LU, 0x3ee13799LU, 0xb91db5ccLU,
311 0xba3d8518LU, 0x3dc1074dLU, 0xf988ccb2LU, 0x7e744ee7LU, 0x3c1a1701LU, 0xbbe69554LU, 0x7faf5eabLU, 0xf853dcfeLU,
312 0x79ef3e4eLU, 0xfe13bc1bLU, 0x3a5a77e4LU, 0xbda6f5b1LU, 0xffc8ac57LU, 0x78342e02LU, 0xbc7de5fdLU, 0x3b8167a8LU,
313 0x38a1577cLU, 0xbf5dd529LU, 0x7b141ed6LU, 0xfce89c83LU, 0xbe86c565LU, 0x397a4730LU, 0xfd338ccfLU, 0x7acf0e9aLU,
314 0xb20605e2LU, 0x35fa87b7LU, 0xf1b34c48LU, 0x764fce1dLU, 0x342197fbLU, 0xb3dd15aeLU, 0x7794de51LU, 0xf0685c04LU,
315 0xf3486cd0LU, 0x74b4ee85LU, 0xb0fd257aLU, 0x3701a72fLU, 0x756ffec9LU, 0xf2937c9cLU, 0x36dab763LU, 0xb1263536LU,
316 0x309ad786LU, 0xb76655d3LU, 0x732f9e2cLU, 0xf4d31c79LU, 0xb6bd459fLU, 0x3141c7caLU, 0xf5080c35LU, 0x72f48e60LU,
317 0x71d4beb4LU, 0xf6283ce1LU, 0x3261f71eLU, 0xb59d754bLU, 0xf7f32cadLU, 0x700faef8LU, 0xb4466507LU, 0x33bae752LU };
318
319 static const ulong32 rs_tab3[256] = {
320 0x00000000LU, 0x5ac1f387LU, 0xb4cfab43LU, 0xee0e58c4LU, 0x25d31b86LU, 0x7f12e801LU, 0x911cb0c5LU, 0xcbdd4342LU,
321 0x4aeb3641LU, 0x102ac5c6LU, 0xfe249d02LU, 0xa4e56e85LU, 0x6f382dc7LU, 0x35f9de40LU, 0xdbf78684LU, 0x81367503LU,
322 0x949b6c82LU, 0xce5a9f05LU, 0x2054c7c1LU, 0x7a953446LU, 0xb1487704LU, 0xeb898483LU, 0x0587dc47LU, 0x5f462fc0LU,
323 0xde705ac3LU, 0x84b1a944LU, 0x6abff180LU, 0x307e0207LU, 0xfba34145LU, 0xa162b2c2LU, 0x4f6cea06LU, 0x15ad1981LU,
324 0x657bd849LU, 0x3fba2bceLU, 0xd1b4730aLU, 0x8b75808dLU, 0x40a8c3cfLU, 0x1a693048LU, 0xf467688cLU, 0xaea69b0bLU,
325 0x2f90ee08LU, 0x75511d8fLU, 0x9b5f454bLU, 0xc19eb6ccLU, 0x0a43f58eLU, 0x50820609LU, 0xbe8c5ecdLU, 0xe44dad4aLU,
326 0xf1e0b4cbLU, 0xab21474cLU, 0x452f1f88LU, 0x1feeec0fLU, 0xd433af4dLU, 0x8ef25ccaLU, 0x60fc040eLU, 0x3a3df789LU,
327 0xbb0b828aLU, 0xe1ca710dLU, 0x0fc429c9LU, 0x5505da4eLU, 0x9ed8990cLU, 0xc4196a8bLU, 0x2a17324fLU, 0x70d6c1c8LU,
328 0xcaf6fd92LU, 0x90370e15LU, 0x7e3956d1LU, 0x24f8a556LU, 0xef25e614LU, 0xb5e41593LU, 0x5bea4d57LU, 0x012bbed0LU,
329 0x801dcbd3LU, 0xdadc3854LU, 0x34d26090LU, 0x6e139317LU, 0xa5ced055LU, 0xff0f23d2LU, 0x11017b16LU, 0x4bc08891LU,
330 0x5e6d9110LU, 0x04ac6297LU, 0xeaa23a53LU, 0xb063c9d4LU, 0x7bbe8a96LU, 0x217f7911LU, 0xcf7121d5LU, 0x95b0d252LU,
331 0x1486a751LU, 0x4e4754d6LU, 0xa0490c12LU, 0xfa88ff95LU, 0x3155bcd7LU, 0x6b944f50LU, 0x859a1794LU, 0xdf5be413LU,
332 0xaf8d25dbLU, 0xf54cd65cLU, 0x1b428e98LU, 0x41837d1fLU, 0x8a5e3e5dLU, 0xd09fcddaLU, 0x3e91951eLU, 0x64506699LU,
333 0xe566139aLU, 0xbfa7e01dLU, 0x51a9b8d9LU, 0x0b684b5eLU, 0xc0b5081cLU, 0x9a74fb9bLU, 0x747aa35fLU, 0x2ebb50d8LU,
334 0x3b164959LU, 0x61d7badeLU, 0x8fd9e21aLU, 0xd518119dLU, 0x1ec552dfLU, 0x4404a158LU, 0xaa0af99cLU, 0xf0cb0a1bLU,
335 0x71fd7f18LU, 0x2b3c8c9fLU, 0xc532d45bLU, 0x9ff327dcLU, 0x542e649eLU, 0x0eef9719LU, 0xe0e1cfddLU, 0xba203c5aLU,
336 0xd9a1b769LU, 0x836044eeLU, 0x6d6e1c2aLU, 0x37afefadLU, 0xfc72acefLU, 0xa6b35f68LU, 0x48bd07acLU, 0x127cf42bLU,
337 0x934a8128LU, 0xc98b72afLU, 0x27852a6bLU, 0x7d44d9ecLU, 0xb6999aaeLU, 0xec586929LU, 0x025631edLU, 0x5897c26aLU,
338 0x4d3adbebLU, 0x17fb286cLU, 0xf9f570a8LU, 0xa334832fLU, 0x68e9c06dLU, 0x322833eaLU, 0xdc266b2eLU, 0x86e798a9LU,
339 0x07d1edaaLU, 0x5d101e2dLU, 0xb31e46e9LU, 0xe9dfb56eLU, 0x2202f62cLU, 0x78c305abLU, 0x96cd5d6fLU, 0xcc0caee8LU,
340 0xbcda6f20LU, 0xe61b9ca7LU, 0x0815c463LU, 0x52d437e4LU, 0x990974a6LU, 0xc3c88721LU, 0x2dc6dfe5LU, 0x77072c62LU,
341 0xf6315961LU, 0xacf0aae6LU, 0x42fef222LU, 0x183f01a5LU, 0xd3e242e7LU, 0x8923b160LU, 0x672de9a4LU, 0x3dec1a23LU,
342 0x284103a2LU, 0x7280f025LU, 0x9c8ea8e1LU, 0xc64f5b66LU, 0x0d921824LU, 0x5753eba3LU, 0xb95db367LU, 0xe39c40e0LU,
343 0x62aa35e3LU, 0x386bc664LU, 0xd6659ea0LU, 0x8ca46d27LU, 0x47792e65LU, 0x1db8dde2LU, 0xf3b68526LU, 0xa97776a1LU,
344 0x13574afbLU, 0x4996b97cLU, 0xa798e1b8LU, 0xfd59123fLU, 0x3684517dLU, 0x6c45a2faLU, 0x824bfa3eLU, 0xd88a09b9LU,
345 0x59bc7cbaLU, 0x037d8f3dLU, 0xed73d7f9LU, 0xb7b2247eLU, 0x7c6f673cLU, 0x26ae94bbLU, 0xc8a0cc7fLU, 0x92613ff8LU,
346 0x87cc2679LU, 0xdd0dd5feLU, 0x33038d3aLU, 0x69c27ebdLU, 0xa21f3dffLU, 0xf8dece78LU, 0x16d096bcLU, 0x4c11653bLU,
347 0xcd271038LU, 0x97e6e3bfLU, 0x79e8bb7bLU, 0x232948fcLU, 0xe8f40bbeLU, 0xb235f839LU, 0x5c3ba0fdLU, 0x06fa537aLU,
348 0x762c92b2LU, 0x2ced6135LU, 0xc2e339f1LU, 0x9822ca76LU, 0x53ff8934LU, 0x093e7ab3LU, 0xe7302277LU, 0xbdf1d1f0LU,
349 0x3cc7a4f3LU, 0x66065774LU, 0x88080fb0LU, 0xd2c9fc37LU, 0x1914bf75LU, 0x43d54cf2LU, 0xaddb1436LU, 0xf71ae7b1LU,
350 0xe2b7fe30LU, 0xb8760db7LU, 0x56785573LU, 0x0cb9a6f4LU, 0xc764e5b6LU, 0x9da51631LU, 0x73ab4ef5LU, 0x296abd72LU,
351 0xa85cc871LU, 0xf29d3bf6LU, 0x1c936332LU, 0x465290b5LU, 0x8d8fd3f7LU, 0xd74e2070LU, 0x394078b4LU, 0x63818b33LU };
352
353 static const ulong32 rs_tab4[256] = {
354 0x00000000LU, 0x58471e5aLU, 0xb08e3cb4LU, 0xe8c922eeLU, 0x2d517825LU, 0x7516667fLU, 0x9ddf4491LU, 0xc5985acbLU,
355 0x5aa2f04aLU, 0x02e5ee10LU, 0xea2cccfeLU, 0xb26bd2a4LU, 0x77f3886fLU, 0x2fb49635LU, 0xc77db4dbLU, 0x9f3aaa81LU,
356 0xb409ad94LU, 0xec4eb3ceLU, 0x04879120LU, 0x5cc08f7aLU, 0x9958d5b1LU, 0xc11fcbebLU, 0x29d6e905LU, 0x7191f75fLU,
357 0xeeab5ddeLU, 0xb6ec4384LU, 0x5e25616aLU, 0x06627f30LU, 0xc3fa25fbLU, 0x9bbd3ba1LU, 0x7374194fLU, 0x2b330715LU,
358 0x25121765LU, 0x7d55093fLU, 0x959c2bd1LU, 0xcddb358bLU, 0x08436f40LU, 0x5004711aLU, 0xb8cd53f4LU, 0xe08a4daeLU,
359 0x7fb0e72fLU, 0x27f7f975LU, 0xcf3edb9bLU, 0x9779c5c1LU, 0x52e19f0aLU, 0x0aa68150LU, 0xe26fa3beLU, 0xba28bde4LU,
360 0x911bbaf1LU, 0xc95ca4abLU, 0x21958645LU, 0x79d2981fLU, 0xbc4ac2d4LU, 0xe40ddc8eLU, 0x0cc4fe60LU, 0x5483e03aLU,
361 0xcbb94abbLU, 0x93fe54e1LU, 0x7b37760fLU, 0x23706855LU, 0xe6e8329eLU, 0xbeaf2cc4LU, 0x56660e2aLU, 0x0e211070LU,
362 0x4a242ecaLU, 0x12633090LU, 0xfaaa127eLU, 0xa2ed0c24LU, 0x677556efLU, 0x3f3248b5LU, 0xd7fb6a5bLU, 0x8fbc7401LU,
363 0x1086de80LU, 0x48c1c0daLU, 0xa008e234LU, 0xf84ffc6eLU, 0x3dd7a6a5LU, 0x6590b8ffLU, 0x8d599a11LU, 0xd51e844bLU,
364 0xfe2d835eLU, 0xa66a9d04LU, 0x4ea3bfeaLU, 0x16e4a1b0LU, 0xd37cfb7bLU, 0x8b3be521LU, 0x63f2c7cfLU, 0x3bb5d995LU,
365 0xa48f7314LU, 0xfcc86d4eLU, 0x14014fa0LU, 0x4c4651faLU, 0x89de0b31LU, 0xd199156bLU, 0x39503785LU, 0x611729dfLU,
366 0x6f3639afLU, 0x377127f5LU, 0xdfb8051bLU, 0x87ff1b41LU, 0x4267418aLU, 0x1a205fd0LU, 0xf2e97d3eLU, 0xaaae6364LU,
367 0x3594c9e5LU, 0x6dd3d7bfLU, 0x851af551LU, 0xdd5deb0bLU, 0x18c5b1c0LU, 0x4082af9aLU, 0xa84b8d74LU, 0xf00c932eLU,
368 0xdb3f943bLU, 0x83788a61LU, 0x6bb1a88fLU, 0x33f6b6d5LU, 0xf66eec1eLU, 0xae29f244LU, 0x46e0d0aaLU, 0x1ea7cef0LU,
369 0x819d6471LU, 0xd9da7a2bLU, 0x311358c5LU, 0x6954469fLU, 0xaccc1c54LU, 0xf48b020eLU, 0x1c4220e0LU, 0x44053ebaLU,
370 0x94485cd9LU, 0xcc0f4283LU, 0x24c6606dLU, 0x7c817e37LU, 0xb91924fcLU, 0xe15e3aa6LU, 0x09971848LU, 0x51d00612LU,
371 0xceeaac93LU, 0x96adb2c9LU, 0x7e649027LU, 0x26238e7dLU, 0xe3bbd4b6LU, 0xbbfccaecLU, 0x5335e802LU, 0x0b72f658LU,
372 0x2041f14dLU, 0x7806ef17LU, 0x90cfcdf9LU, 0xc888d3a3LU, 0x0d108968LU, 0x55579732LU, 0xbd9eb5dcLU, 0xe5d9ab86LU,
373 0x7ae30107LU, 0x22a41f5dLU, 0xca6d3db3LU, 0x922a23e9LU, 0x57b27922LU, 0x0ff56778LU, 0xe73c4596LU, 0xbf7b5bccLU,
374 0xb15a4bbcLU, 0xe91d55e6LU, 0x01d47708LU, 0x59936952LU, 0x9c0b3399LU, 0xc44c2dc3LU, 0x2c850f2dLU, 0x74c21177LU,
375 0xebf8bbf6LU, 0xb3bfa5acLU, 0x5b768742LU, 0x03319918LU, 0xc6a9c3d3LU, 0x9eeedd89LU, 0x7627ff67LU, 0x2e60e13dLU,
376 0x0553e628LU, 0x5d14f872LU, 0xb5ddda9cLU, 0xed9ac4c6LU, 0x28029e0dLU, 0x70458057LU, 0x988ca2b9LU, 0xc0cbbce3LU,
377 0x5ff11662LU, 0x07b60838LU, 0xef7f2ad6LU, 0xb738348cLU, 0x72a06e47LU, 0x2ae7701dLU, 0xc22e52f3LU, 0x9a694ca9LU,
378 0xde6c7213LU, 0x862b6c49LU, 0x6ee24ea7LU, 0x36a550fdLU, 0xf33d0a36LU, 0xab7a146cLU, 0x43b33682LU, 0x1bf428d8LU,
379 0x84ce8259LU, 0xdc899c03LU, 0x3440beedLU, 0x6c07a0b7LU, 0xa99ffa7cLU, 0xf1d8e426LU, 0x1911c6c8LU, 0x4156d892LU,
380 0x6a65df87LU, 0x3222c1ddLU, 0xdaebe333LU, 0x82acfd69LU, 0x4734a7a2LU, 0x1f73b9f8LU, 0xf7ba9b16LU, 0xaffd854cLU,
381 0x30c72fcdLU, 0x68803197LU, 0x80491379LU, 0xd80e0d23LU, 0x1d9657e8LU, 0x45d149b2LU, 0xad186b5cLU, 0xf55f7506LU,
382 0xfb7e6576LU, 0xa3397b2cLU, 0x4bf059c2LU, 0x13b74798LU, 0xd62f1d53LU, 0x8e680309LU, 0x66a121e7LU, 0x3ee63fbdLU,
383 0xa1dc953cLU, 0xf99b8b66LU, 0x1152a988LU, 0x4915b7d2LU, 0x8c8ded19LU, 0xd4caf343LU, 0x3c03d1adLU, 0x6444cff7LU,
384 0x4f77c8e2LU, 0x1730d6b8LU, 0xfff9f456LU, 0xa7beea0cLU, 0x6226b0c7LU, 0x3a61ae9dLU, 0xd2a88c73LU, 0x8aef9229LU,
385 0x15d538a8LU, 0x4d9226f2LU, 0xa55b041cLU, 0xfd1c1a46LU, 0x3884408dLU, 0x60c35ed7LU, 0x880a7c39LU, 0xd04d6263LU };
386
387 static const ulong32 rs_tab5[256] = {
388 0x00000000LU, 0xdbaec658LU, 0xfb11c1b0LU, 0x20bf07e8LU, 0xbb22cf2dLU, 0x608c0975LU, 0x40330e9dLU, 0x9b9dc8c5LU,
389 0x3b44d35aLU, 0xe0ea1502LU, 0xc05512eaLU, 0x1bfbd4b2LU, 0x80661c77LU, 0x5bc8da2fLU, 0x7b77ddc7LU, 0xa0d91b9fLU,
390 0x7688ebb4LU, 0xad262decLU, 0x8d992a04LU, 0x5637ec5cLU, 0xcdaa2499LU, 0x1604e2c1LU, 0x36bbe529LU, 0xed152371LU,
391 0x4dcc38eeLU, 0x9662feb6LU, 0xb6ddf95eLU, 0x6d733f06LU, 0xf6eef7c3LU, 0x2d40319bLU, 0x0dff3673LU, 0xd651f02bLU,
392 0xec5d9b25LU, 0x37f35d7dLU, 0x174c5a95LU, 0xcce29ccdLU, 0x577f5408LU, 0x8cd19250LU, 0xac6e95b8LU, 0x77c053e0LU,
393 0xd719487fLU, 0x0cb78e27LU, 0x2c0889cfLU, 0xf7a64f97LU, 0x6c3b8752LU, 0xb795410aLU, 0x972a46e2LU, 0x4c8480baLU,
394 0x9ad57091LU, 0x417bb6c9LU, 0x61c4b121LU, 0xba6a7779LU, 0x21f7bfbcLU, 0xfa5979e4LU, 0xdae67e0cLU, 0x0148b854LU,
395 0xa191a3cbLU, 0x7a3f6593LU, 0x5a80627bLU, 0x812ea423LU, 0x1ab36ce6LU, 0xc11daabeLU, 0xe1a2ad56LU, 0x3a0c6b0eLU,
396 0x95ba7b4aLU, 0x4e14bd12LU, 0x6eabbafaLU, 0xb5057ca2LU, 0x2e98b467LU, 0xf536723fLU, 0xd58975d7LU, 0x0e27b38fLU,
397 0xaefea810LU, 0x75506e48LU, 0x55ef69a0LU, 0x8e41aff8LU, 0x15dc673dLU, 0xce72a165LU, 0xeecda68dLU, 0x356360d5LU,
398 0xe33290feLU, 0x389c56a6LU, 0x1823514eLU, 0xc38d9716LU, 0x58105fd3LU, 0x83be998bLU, 0xa3019e63LU, 0x78af583bLU,
399 0xd87643a4LU, 0x03d885fcLU, 0x23678214LU, 0xf8c9444cLU, 0x63548c89LU, 0xb8fa4ad1LU, 0x98454d39LU, 0x43eb8b61LU,
400 0x79e7e06fLU, 0xa2492637LU, 0x82f621dfLU, 0x5958e787LU, 0xc2c52f42LU, 0x196be91aLU, 0x39d4eef2LU, 0xe27a28aaLU,
401 0x42a33335LU, 0x990df56dLU, 0xb9b2f285LU, 0x621c34ddLU, 0xf981fc18LU, 0x222f3a40LU, 0x02903da8LU, 0xd93efbf0LU,
402 0x0f6f0bdbLU, 0xd4c1cd83LU, 0xf47eca6bLU, 0x2fd00c33LU, 0xb44dc4f6LU, 0x6fe302aeLU, 0x4f5c0546LU, 0x94f2c31eLU,
403 0x342bd881LU, 0xef851ed9LU, 0xcf3a1931LU, 0x1494df69LU, 0x8f0917acLU, 0x54a7d1f4LU, 0x7418d61cLU, 0xafb61044LU,
404 0x6739f694LU, 0xbc9730ccLU, 0x9c283724LU, 0x4786f17cLU, 0xdc1b39b9LU, 0x07b5ffe1LU, 0x270af809LU, 0xfca43e51LU,
405 0x5c7d25ceLU, 0x87d3e396LU, 0xa76ce47eLU, 0x7cc22226LU, 0xe75feae3LU, 0x3cf12cbbLU, 0x1c4e2b53LU, 0xc7e0ed0bLU,
406 0x11b11d20LU, 0xca1fdb78LU, 0xeaa0dc90LU, 0x310e1ac8LU, 0xaa93d20dLU, 0x713d1455LU, 0x518213bdLU, 0x8a2cd5e5LU,
407 0x2af5ce7aLU, 0xf15b0822LU, 0xd1e40fcaLU, 0x0a4ac992LU, 0x91d70157LU, 0x4a79c70fLU, 0x6ac6c0e7LU, 0xb16806bfLU,
408 0x8b646db1LU, 0x50caabe9LU, 0x7075ac01LU, 0xabdb6a59LU, 0x3046a29cLU, 0xebe864c4LU, 0xcb57632cLU, 0x10f9a574LU,
409 0xb020beebLU, 0x6b8e78b3LU, 0x4b317f5bLU, 0x909fb903LU, 0x0b0271c6LU, 0xd0acb79eLU, 0xf013b076LU, 0x2bbd762eLU,
410 0xfdec8605LU, 0x2642405dLU, 0x06fd47b5LU, 0xdd5381edLU, 0x46ce4928LU, 0x9d608f70LU, 0xbddf8898LU, 0x66714ec0LU,
411 0xc6a8555fLU, 0x1d069307LU, 0x3db994efLU, 0xe61752b7LU, 0x7d8a9a72LU, 0xa6245c2aLU, 0x869b5bc2LU, 0x5d359d9aLU,
412 0xf2838ddeLU, 0x292d4b86LU, 0x09924c6eLU, 0xd23c8a36LU, 0x49a142f3LU, 0x920f84abLU, 0xb2b08343LU, 0x691e451bLU,
413 0xc9c75e84LU, 0x126998dcLU, 0x32d69f34LU, 0xe978596cLU, 0x72e591a9LU, 0xa94b57f1LU, 0x89f45019LU, 0x525a9641LU,
414 0x840b666aLU, 0x5fa5a032LU, 0x7f1aa7daLU, 0xa4b46182LU, 0x3f29a947LU, 0xe4876f1fLU, 0xc43868f7LU, 0x1f96aeafLU,
415 0xbf4fb530LU, 0x64e17368LU, 0x445e7480LU, 0x9ff0b2d8LU, 0x046d7a1dLU, 0xdfc3bc45LU, 0xff7cbbadLU, 0x24d27df5LU,
416 0x1ede16fbLU, 0xc570d0a3LU, 0xe5cfd74bLU, 0x3e611113LU, 0xa5fcd9d6LU, 0x7e521f8eLU, 0x5eed1866LU, 0x8543de3eLU,
417 0x259ac5a1LU, 0xfe3403f9LU, 0xde8b0411LU, 0x0525c249LU, 0x9eb80a8cLU, 0x4516ccd4LU, 0x65a9cb3cLU, 0xbe070d64LU,
418 0x6856fd4fLU, 0xb3f83b17LU, 0x93473cffLU, 0x48e9faa7LU, 0xd3743262LU, 0x08daf43aLU, 0x2865f3d2LU, 0xf3cb358aLU,
419 0x53122e15LU, 0x88bce84dLU, 0xa803efa5LU, 0x73ad29fdLU, 0xe830e138LU, 0x339e2760LU, 0x13212088LU, 0xc88fe6d0LU };
420
421 static const ulong32 rs_tab6[256] = {
422 0x00000000LU, 0x9e3d68dbLU, 0x717ad0fbLU, 0xef47b820LU, 0xe2f4edbbLU, 0x7cc98560LU, 0x938e3d40LU, 0x0db3559bLU,
423 0x89a5973bLU, 0x1798ffe0LU, 0xf8df47c0LU, 0x66e22f1bLU, 0x6b517a80LU, 0xf56c125bLU, 0x1a2baa7bLU, 0x8416c2a0LU,
424 0x5f076376LU, 0xc13a0badLU, 0x2e7db38dLU, 0xb040db56LU, 0xbdf38ecdLU, 0x23cee616LU, 0xcc895e36LU, 0x52b436edLU,
425 0xd6a2f44dLU, 0x489f9c96LU, 0xa7d824b6LU, 0x39e54c6dLU, 0x345619f6LU, 0xaa6b712dLU, 0x452cc90dLU, 0xdb11a1d6LU,
426 0xbe0ec6ecLU, 0x2033ae37LU, 0xcf741617LU, 0x51497eccLU, 0x5cfa2b57LU, 0xc2c7438cLU, 0x2d80fbacLU, 0xb3bd9377LU,
427 0x37ab51d7LU, 0xa996390cLU, 0x46d1812cLU, 0xd8ece9f7LU, 0xd55fbc6cLU, 0x4b62d4b7LU, 0xa4256c97LU, 0x3a18044cLU,
428 0xe109a59aLU, 0x7f34cd41LU, 0x90737561LU, 0x0e4e1dbaLU, 0x03fd4821LU, 0x9dc020faLU, 0x728798daLU, 0xecbaf001LU,
429 0x68ac32a1LU, 0xf6915a7aLU, 0x19d6e25aLU, 0x87eb8a81LU, 0x8a58df1aLU, 0x1465b7c1LU, 0xfb220fe1LU, 0x651f673aLU,
430 0x311cc195LU, 0xaf21a94eLU, 0x4066116eLU, 0xde5b79b5LU, 0xd3e82c2eLU, 0x4dd544f5LU, 0xa292fcd5LU, 0x3caf940eLU,
431 0xb8b956aeLU, 0x26843e75LU, 0xc9c38655LU, 0x57feee8eLU, 0x5a4dbb15LU, 0xc470d3ceLU, 0x2b376beeLU, 0xb50a0335LU,
432 0x6e1ba2e3LU, 0xf026ca38LU, 0x1f617218LU, 0x815c1ac3LU, 0x8cef4f58LU, 0x12d22783LU, 0xfd959fa3LU, 0x63a8f778LU,
433 0xe7be35d8LU, 0x79835d03LU, 0x96c4e523LU, 0x08f98df8LU, 0x054ad863LU, 0x9b77b0b8LU, 0x74300898LU, 0xea0d6043LU,
434 0x8f120779LU, 0x112f6fa2LU, 0xfe68d782LU, 0x6055bf59LU, 0x6de6eac2LU, 0xf3db8219LU, 0x1c9c3a39LU, 0x82a152e2LU,
435 0x06b79042LU, 0x988af899LU, 0x77cd40b9LU, 0xe9f02862LU, 0xe4437df9LU, 0x7a7e1522LU, 0x9539ad02LU, 0x0b04c5d9LU,
436 0xd015640fLU, 0x4e280cd4LU, 0xa16fb4f4LU, 0x3f52dc2fLU, 0x32e189b4LU, 0xacdce16fLU, 0x439b594fLU, 0xdda63194LU,
437 0x59b0f334LU, 0xc78d9befLU, 0x28ca23cfLU, 0xb6f74b14LU, 0xbb441e8fLU, 0x25797654LU, 0xca3ece74LU, 0x5403a6afLU,
438 0x6238cf67LU, 0xfc05a7bcLU, 0x13421f9cLU, 0x8d7f7747LU, 0x80cc22dcLU, 0x1ef14a07LU, 0xf1b6f227LU, 0x6f8b9afcLU,
439 0xeb9d585cLU, 0x75a03087LU, 0x9ae788a7LU, 0x04dae07cLU, 0x0969b5e7LU, 0x9754dd3cLU, 0x7813651cLU, 0xe62e0dc7LU,
440 0x3d3fac11LU, 0xa302c4caLU, 0x4c457ceaLU, 0xd2781431LU, 0xdfcb41aaLU, 0x41f62971LU, 0xaeb19151LU, 0x308cf98aLU,
441 0xb49a3b2aLU, 0x2aa753f1LU, 0xc5e0ebd1LU, 0x5bdd830aLU, 0x566ed691LU, 0xc853be4aLU, 0x2714066aLU, 0xb9296eb1LU,
442 0xdc36098bLU, 0x420b6150LU, 0xad4cd970LU, 0x3371b1abLU, 0x3ec2e430LU, 0xa0ff8cebLU, 0x4fb834cbLU, 0xd1855c10LU,
443 0x55939eb0LU, 0xcbaef66bLU, 0x24e94e4bLU, 0xbad42690LU, 0xb767730bLU, 0x295a1bd0LU, 0xc61da3f0LU, 0x5820cb2bLU,
444 0x83316afdLU, 0x1d0c0226LU, 0xf24bba06LU, 0x6c76d2ddLU, 0x61c58746LU, 0xfff8ef9dLU, 0x10bf57bdLU, 0x8e823f66LU,
445 0x0a94fdc6LU, 0x94a9951dLU, 0x7bee2d3dLU, 0xe5d345e6LU, 0xe860107dLU, 0x765d78a6LU, 0x991ac086LU, 0x0727a85dLU,
446 0x53240ef2LU, 0xcd196629LU, 0x225ede09LU, 0xbc63b6d2LU, 0xb1d0e349LU, 0x2fed8b92LU, 0xc0aa33b2LU, 0x5e975b69LU,
447 0xda8199c9LU, 0x44bcf112LU, 0xabfb4932LU, 0x35c621e9LU, 0x38757472LU, 0xa6481ca9LU, 0x490fa489LU, 0xd732cc52LU,
448 0x0c236d84LU, 0x921e055fLU, 0x7d59bd7fLU, 0xe364d5a4LU, 0xeed7803fLU, 0x70eae8e4LU, 0x9fad50c4LU, 0x0190381fLU,
449 0x8586fabfLU, 0x1bbb9264LU, 0xf4fc2a44LU, 0x6ac1429fLU, 0x67721704LU, 0xf94f7fdfLU, 0x1608c7ffLU, 0x8835af24LU,
450 0xed2ac81eLU, 0x7317a0c5LU, 0x9c5018e5LU, 0x026d703eLU, 0x0fde25a5LU, 0x91e34d7eLU, 0x7ea4f55eLU, 0xe0999d85LU,
451 0x648f5f25LU, 0xfab237feLU, 0x15f58fdeLU, 0x8bc8e705LU, 0x867bb29eLU, 0x1846da45LU, 0xf7016265LU, 0x693c0abeLU,
452 0xb22dab68LU, 0x2c10c3b3LU, 0xc3577b93LU, 0x5d6a1348LU, 0x50d946d3LU, 0xcee42e08LU, 0x21a39628LU, 0xbf9efef3LU,
453 0x3b883c53LU, 0xa5b55488LU, 0x4af2eca8LU, 0xd4cf8473LU, 0xd97cd1e8LU, 0x4741b933LU, 0xa8060113LU, 0x363b69c8LU };
454
455 static const ulong32 rs_tab7[256] = {
456 0x00000000LU, 0x0319e59eLU, 0x06328771LU, 0x052b62efLU, 0x0c6443e2LU, 0x0f7da67cLU, 0x0a56c493LU, 0x094f210dLU,
457 0x18c88689LU, 0x1bd16317LU, 0x1efa01f8LU, 0x1de3e466LU, 0x14acc56bLU, 0x17b520f5LU, 0x129e421aLU, 0x1187a784LU,
458 0x30dd415fLU, 0x33c4a4c1LU, 0x36efc62eLU, 0x35f623b0LU, 0x3cb902bdLU, 0x3fa0e723LU, 0x3a8b85ccLU, 0x39926052LU,
459 0x2815c7d6LU, 0x2b0c2248LU, 0x2e2740a7LU, 0x2d3ea539LU, 0x24718434LU, 0x276861aaLU, 0x22430345LU, 0x215ae6dbLU,
460 0x60f782beLU, 0x63ee6720LU, 0x66c505cfLU, 0x65dce051LU, 0x6c93c15cLU, 0x6f8a24c2LU, 0x6aa1462dLU, 0x69b8a3b3LU,
461 0x783f0437LU, 0x7b26e1a9LU, 0x7e0d8346LU, 0x7d1466d8LU, 0x745b47d5LU, 0x7742a24bLU, 0x7269c0a4LU, 0x7170253aLU,
462 0x502ac3e1LU, 0x5333267fLU, 0x56184490LU, 0x5501a10eLU, 0x5c4e8003LU, 0x5f57659dLU, 0x5a7c0772LU, 0x5965e2ecLU,
463 0x48e24568LU, 0x4bfba0f6LU, 0x4ed0c219LU, 0x4dc92787LU, 0x4486068aLU, 0x479fe314LU, 0x42b481fbLU, 0x41ad6465LU,
464 0xc0a34931LU, 0xc3baacafLU, 0xc691ce40LU, 0xc5882bdeLU, 0xccc70ad3LU, 0xcfdeef4dLU, 0xcaf58da2LU, 0xc9ec683cLU,
465 0xd86bcfb8LU, 0xdb722a26LU, 0xde5948c9LU, 0xdd40ad57LU, 0xd40f8c5aLU, 0xd71669c4LU, 0xd23d0b2bLU, 0xd124eeb5LU,
466 0xf07e086eLU, 0xf367edf0LU, 0xf64c8f1fLU, 0xf5556a81LU, 0xfc1a4b8cLU, 0xff03ae12LU, 0xfa28ccfdLU, 0xf9312963LU,
467 0xe8b68ee7LU, 0xebaf6b79LU, 0xee840996LU, 0xed9dec08LU, 0xe4d2cd05LU, 0xe7cb289bLU, 0xe2e04a74LU, 0xe1f9afeaLU,
468 0xa054cb8fLU, 0xa34d2e11LU, 0xa6664cfeLU, 0xa57fa960LU, 0xac30886dLU, 0xaf296df3LU, 0xaa020f1cLU, 0xa91bea82LU,
469 0xb89c4d06LU, 0xbb85a898LU, 0xbeaeca77LU, 0xbdb72fe9LU, 0xb4f80ee4LU, 0xb7e1eb7aLU, 0xb2ca8995LU, 0xb1d36c0bLU,
470 0x90898ad0LU, 0x93906f4eLU, 0x96bb0da1LU, 0x95a2e83fLU, 0x9cedc932LU, 0x9ff42cacLU, 0x9adf4e43LU, 0x99c6abddLU,
471 0x88410c59LU, 0x8b58e9c7LU, 0x8e738b28LU, 0x8d6a6eb6LU, 0x84254fbbLU, 0x873caa25LU, 0x8217c8caLU, 0x810e2d54LU,
472 0xcd0b9262LU, 0xce1277fcLU, 0xcb391513LU, 0xc820f08dLU, 0xc16fd180LU, 0xc276341eLU, 0xc75d56f1LU, 0xc444b36fLU,
473 0xd5c314ebLU, 0xd6daf175LU, 0xd3f1939aLU, 0xd0e87604LU, 0xd9a75709LU, 0xdabeb297LU, 0xdf95d078LU, 0xdc8c35e6LU,
474 0xfdd6d33dLU, 0xfecf36a3LU, 0xfbe4544cLU, 0xf8fdb1d2LU, 0xf1b290dfLU, 0xf2ab7541LU, 0xf78017aeLU, 0xf499f230LU,
475 0xe51e55b4LU, 0xe607b02aLU, 0xe32cd2c5LU, 0xe035375bLU, 0xe97a1656LU, 0xea63f3c8LU, 0xef489127LU, 0xec5174b9LU,
476 0xadfc10dcLU, 0xaee5f542LU, 0xabce97adLU, 0xa8d77233LU, 0xa198533eLU, 0xa281b6a0LU, 0xa7aad44fLU, 0xa4b331d1LU,
477 0xb5349655LU, 0xb62d73cbLU, 0xb3061124LU, 0xb01ff4baLU, 0xb950d5b7LU, 0xba493029LU, 0xbf6252c6LU, 0xbc7bb758LU,
478 0x9d215183LU, 0x9e38b41dLU, 0x9b13d6f2LU, 0x980a336cLU, 0x91451261LU, 0x925cf7ffLU, 0x97779510LU, 0x946e708eLU,
479 0x85e9d70aLU, 0x86f03294LU, 0x83db507bLU, 0x80c2b5e5LU, 0x898d94e8LU, 0x8a947176LU, 0x8fbf1399LU, 0x8ca6f607LU,
480 0x0da8db53LU, 0x0eb13ecdLU, 0x0b9a5c22LU, 0x0883b9bcLU, 0x01cc98b1LU, 0x02d57d2fLU, 0x07fe1fc0LU, 0x04e7fa5eLU,
481 0x15605ddaLU, 0x1679b844LU, 0x1352daabLU, 0x104b3f35LU, 0x19041e38LU, 0x1a1dfba6LU, 0x1f369949LU, 0x1c2f7cd7LU,
482 0x3d759a0cLU, 0x3e6c7f92LU, 0x3b471d7dLU, 0x385ef8e3LU, 0x3111d9eeLU, 0x32083c70LU, 0x37235e9fLU, 0x343abb01LU,
483 0x25bd1c85LU, 0x26a4f91bLU, 0x238f9bf4LU, 0x20967e6aLU, 0x29d95f67LU, 0x2ac0baf9LU, 0x2febd816LU, 0x2cf23d88LU,
484 0x6d5f59edLU, 0x6e46bc73LU, 0x6b6dde9cLU, 0x68743b02LU, 0x613b1a0fLU, 0x6222ff91LU, 0x67099d7eLU, 0x641078e0LU,
485 0x7597df64LU, 0x768e3afaLU, 0x73a55815LU, 0x70bcbd8bLU, 0x79f39c86LU, 0x7aea7918LU, 0x7fc11bf7LU, 0x7cd8fe69LU,
486 0x5d8218b2LU, 0x5e9bfd2cLU, 0x5bb09fc3LU, 0x58a97a5dLU, 0x51e65b50LU, 0x52ffbeceLU, 0x57d4dc21LU, 0x54cd39bfLU,
487 0x454a9e3bLU, 0x46537ba5LU, 0x4378194aLU, 0x4061fcd4LU, 0x492eddd9LU, 0x4a373847LU, 0x4f1c5aa8LU, 0x4c05bf36LU };
488
489 #endif /* LTC_TWOFISH_ALL_TABLES */
490
491 #endif
492
493 /* $Source$ */
494 /* $Revision$ */
495 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file xtea.c
13 Implementation of LTC_XTEA, Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_XTEA
18
19 const struct ltc_cipher_descriptor xtea_desc =
20 {
21 "xtea",
22 1,
23 16, 16, 8, 32,
24 &xtea_setup,
25 &xtea_ecb_encrypt,
26 &xtea_ecb_decrypt,
27 &xtea_test,
28 &xtea_done,
29 &xtea_keysize,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31 };
32
33 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
34 {
35 unsigned long x, sum, K[4];
36
37 LTC_ARGCHK(key != NULL);
38 LTC_ARGCHK(skey != NULL);
39
40 /* check arguments */
41 if (keylen != 16) {
42 return CRYPT_INVALID_KEYSIZE;
43 }
44
45 if (num_rounds != 0 && num_rounds != 32) {
46 return CRYPT_INVALID_ROUNDS;
47 }
48
49 /* load key */
50 LOAD32H(K[0], key+0);
51 LOAD32H(K[1], key+4);
52 LOAD32H(K[2], key+8);
53 LOAD32H(K[3], key+12);
54
55 for (x = sum = 0; x < 32; x++) {
56 skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL;
57 sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL;
58 skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL;
59 }
60
61 #ifdef LTC_CLEAN_STACK
62 zeromem(&K, sizeof(K));
63 #endif
64
65 return CRYPT_OK;
66 }
67
68 /**
69 Encrypts a block of text with LTC_XTEA
70 @param pt The input plaintext (8 bytes)
71 @param ct The output ciphertext (8 bytes)
72 @param skey The key as scheduled
73 @return CRYPT_OK if successful
74 */
75 int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
76 {
77 unsigned long y, z;
78 int r;
79
80 LTC_ARGCHK(pt != NULL);
81 LTC_ARGCHK(ct != NULL);
82 LTC_ARGCHK(skey != NULL);
83
84 LOAD32H(y, &pt[0]);
85 LOAD32H(z, &pt[4]);
86 for (r = 0; r < 32; r += 4) {
87 y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL;
88 z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL;
89
90 y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+1])) & 0xFFFFFFFFUL;
91 z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+1])) & 0xFFFFFFFFUL;
92
93 y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+2])) & 0xFFFFFFFFUL;
94 z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+2])) & 0xFFFFFFFFUL;
95
96 y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+3])) & 0xFFFFFFFFUL;
97 z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+3])) & 0xFFFFFFFFUL;
98 }
99 STORE32H(y, &ct[0]);
100 STORE32H(z, &ct[4]);
101 return CRYPT_OK;
102 }
103
104 /**
105 Decrypts a block of text with LTC_XTEA
106 @param ct The input ciphertext (8 bytes)
107 @param pt The output plaintext (8 bytes)
108 @param skey The key as scheduled
109 @return CRYPT_OK if successful
110 */
111 int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
112 {
113 unsigned long y, z;
114 int r;
115
116 LTC_ARGCHK(pt != NULL);
117 LTC_ARGCHK(ct != NULL);
118 LTC_ARGCHK(skey != NULL);
119
120 LOAD32H(y, &ct[0]);
121 LOAD32H(z, &ct[4]);
122 for (r = 31; r >= 0; r -= 4) {
123 z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL;
124 y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL;
125
126 z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-1])) & 0xFFFFFFFFUL;
127 y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-1])) & 0xFFFFFFFFUL;
128
129 z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-2])) & 0xFFFFFFFFUL;
130 y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-2])) & 0xFFFFFFFFUL;
131
132 z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-3])) & 0xFFFFFFFFUL;
133 y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-3])) & 0xFFFFFFFFUL;
134 }
135 STORE32H(y, &pt[0]);
136 STORE32H(z, &pt[4]);
137 return CRYPT_OK;
138 }
139
140 /**
141 Performs a self-test of the LTC_XTEA block cipher
142 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
143 */
144 int xtea_test(void)
145 {
146 #ifndef LTC_TEST
147 return CRYPT_NOP;
148 #else
149 static const struct {
150 unsigned char key[16], pt[8], ct[8];
151 } tests[] = {
152 {
153 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
155 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
156 { 0xde, 0xe9, 0xd4, 0xd8, 0xf7, 0x13, 0x1e, 0xd9 }
157 }, {
158 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
159 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04 },
160 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
161 { 0xa5, 0x97, 0xab, 0x41, 0x76, 0x01, 0x4d, 0x72 }
162 }, {
163 { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
164 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06 },
165 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02 },
166 { 0xb1, 0xfd, 0x5d, 0xa9, 0xcc, 0x6d, 0xc9, 0xdc }
167 }, {
168 { 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
169 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
170 { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
171 { 0x70, 0x4b, 0x31, 0x34, 0x47, 0x44, 0xdf, 0xab }
172 }, {
173 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
174 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
175 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
176 { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }
177 }, {
178 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
179 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
180 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
181 { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }
182 }, {
183 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
184 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
185 { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
186 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
187 }, {
188 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
190 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
191 { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }
192 }, {
193 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
195 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
196 { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }
197 }, {
198 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
200 { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 },
201 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
202 }
203 };
204 unsigned char tmp[2][8];
205 symmetric_key skey;
206 int i, err, y;
207 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
208 zeromem(&skey, sizeof(skey));
209 if ((err = xtea_setup(tests[i].key, 16, 0, &skey)) != CRYPT_OK) {
210 return err;
211 }
212 xtea_ecb_encrypt(tests[i].pt, tmp[0], &skey);
213 xtea_ecb_decrypt(tmp[0], tmp[1], &skey);
214
215 if (XMEMCMP(tmp[0], tests[i].ct, 8) != 0 || XMEMCMP(tmp[1], tests[i].pt, 8) != 0) {
216 #if 0
217 printf("\n\nTest %d failed\n", i);
218 if (XMEMCMP(tmp[0], tests[i].ct, 8)) {
219 printf("CT: ");
220 for (i = 0; i < 8; i++) {
221 printf("%02x ", tmp[0][i]);
222 }
223 printf("\n");
224 } else {
225 printf("PT: ");
226 for (i = 0; i < 8; i++) {
227 printf("%02x ", tmp[1][i]);
228 }
229 printf("\n");
230 }
231 #endif
232 return CRYPT_FAIL_TESTVECTOR;
233 }
234
235 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
236 for (y = 0; y < 8; y++) tmp[0][y] = 0;
237 for (y = 0; y < 1000; y++) xtea_ecb_encrypt(tmp[0], tmp[0], &skey);
238 for (y = 0; y < 1000; y++) xtea_ecb_decrypt(tmp[0], tmp[0], &skey);
239 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
240 } /* for */
241
242 return CRYPT_OK;
243 #endif
244 }
245
246 /** Terminate the context
247 @param skey The scheduled key
248 */
249 void xtea_done(symmetric_key *skey)
250 {
251 }
252
253 /**
254 Gets suitable key size
255 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
256 @return CRYPT_OK if the input key size is acceptable.
257 */
258 int xtea_keysize(int *keysize)
259 {
260 LTC_ARGCHK(keysize != NULL);
261 if (*keysize < 16) {
262 return CRYPT_INVALID_KEYSIZE;
263 }
264 *keysize = 16;
265 return CRYPT_OK;
266 }
267
268
269 #endif
270
271
272
273
274 /* $Source$ */
275 /* $Revision$ */
276 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ccm_memory.c
14 CCM support, process a block of memory, Tom St Denis
15 */
16
17 #ifdef LTC_CCM_MODE
18
19 /**
20 CCM encrypt/decrypt and produce an authentication tag
21 @param cipher The index of the cipher desired
22 @param key The secret key to use
23 @param keylen The length of the secret key (octets)
24 @param uskey A previously scheduled key [optional can be NULL]
25 @param nonce The session nonce [use once]
26 @param noncelen The length of the nonce
27 @param header The header for the session
28 @param headerlen The length of the header (octets)
29 @param pt [out] The plaintext
30 @param ptlen The length of the plaintext (octets)
31 @param ct [out] The ciphertext
32 @param tag [out] The destination tag
33 @param taglen [in/out] The max size and resulting size of the authentication tag
34 @param direction Encrypt or Decrypt direction (0 or 1)
35 @return CRYPT_OK if successful
36 */
37 int ccm_memory(int cipher,
38 const unsigned char *key, unsigned long keylen,
39 symmetric_key *uskey,
40 const unsigned char *nonce, unsigned long noncelen,
41 const unsigned char *header, unsigned long headerlen,
42 unsigned char *pt, unsigned long ptlen,
43 unsigned char *ct,
44 unsigned char *tag, unsigned long *taglen,
45 int direction)
46 {
47 unsigned char PAD[16], ctr[16], CTRPAD[16], b;
48 symmetric_key *skey;
49 int err;
50 unsigned long len, L, x, y, z, CTRlen;
51
52 if (uskey == NULL) {
53 LTC_ARGCHK(key != NULL);
54 }
55 LTC_ARGCHK(nonce != NULL);
56 if (headerlen > 0) {
57 LTC_ARGCHK(header != NULL);
58 }
59 LTC_ARGCHK(pt != NULL);
60 LTC_ARGCHK(ct != NULL);
61 LTC_ARGCHK(tag != NULL);
62 LTC_ARGCHK(taglen != NULL);
63
64 #ifdef LTC_FAST
65 if (16 % sizeof(LTC_FAST_TYPE)) {
66 return CRYPT_INVALID_ARG;
67 }
68 #endif
69
70 /* check cipher input */
71 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
72 return err;
73 }
74 if (cipher_descriptor[cipher].block_length != 16) {
75 return CRYPT_INVALID_CIPHER;
76 }
77
78 /* make sure the taglen is even and <= 16 */
79 *taglen &= ~1;
80 if (*taglen > 16) {
81 *taglen = 16;
82 }
83
84 /* can't use < 4 */
85 if (*taglen < 4) {
86 return CRYPT_INVALID_ARG;
87 }
88
89 /* is there an accelerator? */
90 if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
91 return cipher_descriptor[cipher].accel_ccm_memory(
92 key, keylen,
93 uskey,
94 nonce, noncelen,
95 header, headerlen,
96 pt, ptlen,
97 ct,
98 tag, taglen,
99 direction);
100 }
101
102 /* let's get the L value */
103 len = ptlen;
104 L = 0;
105 while (len) {
106 ++L;
107 len >>= 8;
108 }
109 if (L <= 1) {
110 L = 2;
111 }
112
113 /* increase L to match the nonce len */
114 noncelen = (noncelen > 13) ? 13 : noncelen;
115 if ((15 - noncelen) > L) {
116 L = 15 - noncelen;
117 }
118
119 /* decrease noncelen to match L */
120 if ((noncelen + L) > 15) {
121 noncelen = 15 - L;
122 }
123
124 /* allocate mem for the symmetric key */
125 if (uskey == NULL) {
126 skey = XMALLOC(sizeof(*skey));
127 if (skey == NULL) {
128 return CRYPT_MEM;
129 }
130
131 /* initialize the cipher */
132 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
133 XFREE(skey);
134 return err;
135 }
136 } else {
137 skey = uskey;
138 }
139
140 /* form B_0 == flags | Nonce N | l(m) */
141 x = 0;
142 PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
143 (((*taglen - 2)>>1)<<3) |
144 (L-1));
145
146 /* nonce */
147 for (y = 0; y < (16 - (L + 1)); y++) {
148 PAD[x++] = nonce[y];
149 }
150
151 /* store len */
152 len = ptlen;
153
154 /* shift len so the upper bytes of len are the contents of the length */
155 for (y = L; y < 4; y++) {
156 len <<= 8;
157 }
158
159 /* store l(m) (only store 32-bits) */
160 for (y = 0; L > 4 && (L-y)>4; y++) {
161 PAD[x++] = 0;
162 }
163 for (; y < L; y++) {
164 PAD[x++] = (unsigned char)((len >> 24) & 255);
165 len <<= 8;
166 }
167
168 /* encrypt PAD */
169 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
170 goto error;
171 }
172
173 /* handle header */
174 if (headerlen > 0) {
175 x = 0;
176
177 /* store length */
178 if (headerlen < ((1UL<<16) - (1UL<<8))) {
179 PAD[x++] ^= (headerlen>>8) & 255;
180 PAD[x++] ^= headerlen & 255;
181 } else {
182 PAD[x++] ^= 0xFF;
183 PAD[x++] ^= 0xFE;
184 PAD[x++] ^= (headerlen>>24) & 255;
185 PAD[x++] ^= (headerlen>>16) & 255;
186 PAD[x++] ^= (headerlen>>8) & 255;
187 PAD[x++] ^= headerlen & 255;
188 }
189
190 /* now add the data */
191 for (y = 0; y < headerlen; y++) {
192 if (x == 16) {
193 /* full block so let's encrypt it */
194 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
195 goto error;
196 }
197 x = 0;
198 }
199 PAD[x++] ^= header[y];
200 }
201
202 /* remainder? */
203 if (x != 0) {
204 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
205 goto error;
206 }
207 }
208 }
209
210 /* setup the ctr counter */
211 x = 0;
212
213 /* flags */
214 ctr[x++] = (unsigned char)L-1;
215
216 /* nonce */
217 for (y = 0; y < (16 - (L+1)); ++y) {
218 ctr[x++] = nonce[y];
219 }
220 /* offset */
221 while (x < 16) {
222 ctr[x++] = 0;
223 }
224
225 x = 0;
226 CTRlen = 16;
227
228 /* now handle the PT */
229 if (ptlen > 0) {
230 y = 0;
231 #ifdef LTC_FAST
232 if (ptlen & ~15) {
233 if (direction == CCM_ENCRYPT) {
234 for (; y < (ptlen & ~15); y += 16) {
235 /* increment the ctr? */
236 for (z = 15; z > 15-L; z--) {
237 ctr[z] = (ctr[z] + 1) & 255;
238 if (ctr[z]) break;
239 }
240 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
241 goto error;
242 }
243
244 /* xor the PT against the pad first */
245 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
246 *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
247 *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
248 }
249 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
250 goto error;
251 }
252 }
253 } else {
254 for (; y < (ptlen & ~15); y += 16) {
255 /* increment the ctr? */
256 for (z = 15; z > 15-L; z--) {
257 ctr[z] = (ctr[z] + 1) & 255;
258 if (ctr[z]) break;
259 }
260 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
261 goto error;
262 }
263
264 /* xor the PT against the pad last */
265 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
266 *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
267 *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
268 }
269 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
270 goto error;
271 }
272 }
273 }
274 }
275 #endif
276
277 for (; y < ptlen; y++) {
278 /* increment the ctr? */
279 if (CTRlen == 16) {
280 for (z = 15; z > 15-L; z--) {
281 ctr[z] = (ctr[z] + 1) & 255;
282 if (ctr[z]) break;
283 }
284 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
285 goto error;
286 }
287 CTRlen = 0;
288 }
289
290 /* if we encrypt we add the bytes to the MAC first */
291 if (direction == CCM_ENCRYPT) {
292 b = pt[y];
293 ct[y] = b ^ CTRPAD[CTRlen++];
294 } else {
295 b = ct[y] ^ CTRPAD[CTRlen++];
296 pt[y] = b;
297 }
298
299 if (x == 16) {
300 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
301 goto error;
302 }
303 x = 0;
304 }
305 PAD[x++] ^= b;
306 }
307
308 if (x != 0) {
309 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
310 goto error;
311 }
312 }
313 }
314
315 /* setup CTR for the TAG (zero the count) */
316 for (y = 15; y > 15 - L; y--) {
317 ctr[y] = 0x00;
318 }
319 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
320 goto error;
321 }
322
323 if (skey != uskey) {
324 cipher_descriptor[cipher].done(skey);
325 }
326
327 /* store the TAG */
328 for (x = 0; x < 16 && x < *taglen; x++) {
329 tag[x] = PAD[x] ^ CTRPAD[x];
330 }
331 *taglen = x;
332
333 #ifdef LTC_CLEAN_STACK
334 zeromem(skey, sizeof(*skey));
335 zeromem(PAD, sizeof(PAD));
336 zeromem(CTRPAD, sizeof(CTRPAD));
337 #endif
338 error:
339 if (skey != uskey) {
340 XFREE(skey);
341 }
342
343 return err;
344 }
345
346 #endif
347
348 /* $Source$ */
349 /* $Revision$ */
350 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ccm_memory.c
14 CCM support, process a block of memory, Tom St Denis
15 */
16
17 #ifdef CCM_MODE
18
19 /**
20 CCM encrypt/decrypt and produce an authentication tag
21 @param cipher The index of the cipher desired
22 @param key The secret key to use
23 @param keylen The length of the secret key (octets)
24 @param uskey A previously scheduled key [optional can be NULL]
25 @param nonce The session nonce [use once]
26 @param noncelen The length of the nonce
27 @param header The header for the session
28 @param headerlen The length of the header (octets)
29 @param pt [out] The plaintext
30 @param ptlen The length of the plaintext (octets)
31 @param ct [out] The ciphertext
32 @param tag [out] The destination tag
33 @param taglen [in/out] The max size and resulting size of the authentication tag
34 @param direction Encrypt or Decrypt direction (0 or 1)
35 @return CRYPT_OK if successful
36 */
37 int ccm_memory_ex(int cipher,
38 const unsigned char *key, unsigned long keylen,
39 symmetric_key *uskey,
40 const unsigned char *nonce, unsigned long noncelen,
41 const unsigned char *header, unsigned long headerlen,
42 unsigned char *pt, unsigned long ptlen,
43 unsigned char *ct,
44 unsigned char *tag, unsigned long *taglen,
45 int direction,
46 const unsigned char *B_0,
47 const unsigned char *CTR,
48 int ctrwidth)
49 {
50 unsigned char PAD[16], ctr[16], CTRPAD[16], ctrcopy[16], b;
51 symmetric_key *skey;
52 int err;
53 unsigned long len, L, x, y, z, CTRlen;
54
55 if (uskey == NULL) {
56 LTC_ARGCHK(key != NULL);
57 }
58 LTC_ARGCHK(nonce != NULL);
59 if (headerlen > 0) {
60 LTC_ARGCHK(header != NULL);
61 }
62 LTC_ARGCHK(pt != NULL);
63 LTC_ARGCHK(ct != NULL);
64 LTC_ARGCHK(tag != NULL);
65 LTC_ARGCHK(taglen != NULL);
66
67 #ifdef LTC_FAST
68 if (16 % sizeof(LTC_FAST_TYPE)) {
69 return CRYPT_INVALID_ARG;
70 }
71 #endif
72
73 /* check cipher input */
74 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
75 return err;
76 }
77 if (cipher_descriptor[cipher].block_length != 16) {
78 return CRYPT_INVALID_CIPHER;
79 }
80
81 /* make sure the taglen is even and <= 16 */
82 *taglen &= ~1;
83 if (*taglen > 16) {
84 *taglen = 16;
85 }
86
87 /* can't use < 4 */
88 if (*taglen < 4) {
89 return CRYPT_INVALID_ARG;
90 }
91
92 /* is there an accelerator? */
93 if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
94 return cipher_descriptor[cipher].accel_ccm_memory(
95 key, keylen,
96 uskey,
97 nonce, noncelen,
98 header, headerlen,
99 pt, ptlen,
100 ct,
101 tag, taglen,
102 direction);
103 }
104
105 /* let's get the L value */
106 len = ptlen;
107 L = 0;
108 while (len) {
109 ++L;
110 len >>= 8;
111 }
112 if (L <= 1) {
113 L = 2;
114 }
115
116 /* increase L to match the nonce len */
117 noncelen = (noncelen > 13) ? 13 : noncelen;
118 if ((15 - noncelen) > L) {
119 L = 15 - noncelen;
120 }
121
122 /* decrease noncelen to match L */
123 if ((noncelen + L) > 15) {
124 noncelen = 15 - L;
125 }
126
127 /* allocate mem for the symmetric key */
128 if (uskey == NULL) {
129 skey = XMALLOC(sizeof(*skey));
130 if (skey == NULL) {
131 return CRYPT_MEM;
132 }
133
134 /* initialize the cipher */
135 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
136 XFREE(skey);
137 return err;
138 }
139 } else {
140 skey = uskey;
141 }
142
143 /* form B_0 == flags | Nonce N | l(m) */
144 x = 0;
145
146 if (B_0 == NULL) {
147 PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
148 (((*taglen - 2)>>1)<<3) |
149 (L-1));
150
151 /* nonce */
152 for (y = 0; y < (16 - (L + 1)); y++) {
153 PAD[x++] = nonce[y];
154 }
155
156 /* store len */
157 len = ptlen;
158
159 /* shift len so the upper bytes of len are the contents of the length */
160 for (y = L; y < 4; y++) {
161 len <<= 8;
162 }
163
164 /* store l(m) (only store 32-bits) */
165 for (y = 0; L > 4 && (L-y)>4; y++) {
166 PAD[x++] = 0;
167 }
168 for (; y < L; y++) {
169 PAD[x++] = (unsigned char)((len >> 24) & 255);
170 len <<= 8;
171 }
172
173 } else {
174 // B_0 != NULL
175 XMEMCPY(PAD, B_0, 16);
176 }
177
178 /* encrypt PAD */
179 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
180 goto error;
181 }
182
183 /* handle header */
184 if (headerlen > 0) {
185 x = 0;
186
187 #if 0
188 /* store length */
189 if (headerlen < ((1UL<<16) - (1UL<<8))) {
190 PAD[x++] ^= (headerlen>>8) & 255;
191 PAD[x++] ^= headerlen & 255;
192 } else {
193 PAD[x++] ^= 0xFF;
194 PAD[x++] ^= 0xFE;
195 PAD[x++] ^= (headerlen>>24) & 255;
196 PAD[x++] ^= (headerlen>>16) & 255;
197 PAD[x++] ^= (headerlen>>8) & 255;
198 PAD[x++] ^= headerlen & 255;
199 }
200 #endif
201
202 /* now add the data */
203 for (y = 0; y < headerlen; y++) {
204 if (x == 16) {
205 /* full block so let's encrypt it */
206 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
207 goto error;
208 }
209 x = 0;
210 }
211 PAD[x++] ^= header[y];
212 }
213
214 /* remainder? */
215 if (x != 0) {
216 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
217 goto error;
218 }
219 }
220 }
221
222 /* setup the ctr counter */
223 if (CTR == NULL) {
224 x = 0;
225
226 /* flags */
227 ctr[x++] = (unsigned char)L-1;
228
229 /* nonce */
230 for (y = 0; y < (16 - (L+1)); ++y) {
231 ctr[x++] = nonce[y];
232 }
233 /* offset */
234 while (x < 16) {
235 ctr[x++] = 0;
236 }
237 } else {
238 XMEMCPY(ctr, CTR, 16);
239 }
240
241 x = 0;
242 CTRlen = 16;
243
244 /* now handle the PT */
245 if (ptlen > 0) {
246 y = 0;
247 #ifdef LTC_FAST2
248 if (ptlen & ~15) {
249 if (direction == CCM_ENCRYPT) {
250 for (; y < (ptlen & ~15); y += 16) {
251 /* increment the ctr? */
252 for (z = 15; z > 15-ctrwidth; z--) {
253 ctr[z] = (ctr[z] + 1) & 255;
254 if (ctr[z]) break;
255 }
256 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
257 goto error;
258 }
259
260 /* xor the PT against the pad first */
261 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
262 *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
263 *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
264 }
265 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
266 goto error;
267 }
268 }
269 } else {
270 for (; y < (ptlen & ~15); y += 16) {
271 /* increment the ctr? */
272 for (z = 15; z > 15-ctrwidth; z--) {
273 ctr[z] = (ctr[z] + 1) & 255;
274 if (ctr[z]) break;
275 }
276 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
277 goto error;
278 }
279
280 /* xor the PT against the pad last */
281 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
282 *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
283 *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
284 }
285 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
286 goto error;
287 }
288 }
289 }
290 }
291 #endif
292
293 for (; y < ptlen; y++) {
294 /* increment the ctr? */
295 if (CTRlen == 16) {
296 for (z = 15; z > 15-ctrwidth; z--) {
297 ctr[z] = (ctr[z] + 1) & 255;
298 if (ctr[z]) break;
299 }
300 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
301 goto error;
302 }
303 CTRlen = 0;
304 }
305
306 /* if we encrypt we add the bytes to the MAC first */
307 if (direction == CCM_ENCRYPT) {
308 b = pt[y];
309 ct[y] = b ^ CTRPAD[CTRlen++];
310 } else {
311 b = ct[y] ^ CTRPAD[CTRlen++];
312 pt[y] = b;
313 }
314
315 if (x == 16) {
316 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
317 goto error;
318 }
319 x = 0;
320 }
321 PAD[x++] ^= b;
322 }
323
324 if (x != 0) {
325 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
326 goto error;
327 }
328 }
329 }
330
331 // grab the CTR
332 memcpy(ctrcopy, ctr, 16);
333
334 /* setup CTR for the TAG (zero the count) */
335 if (CTR == NULL) {
336 for (y = 15; y > 15 - L; y--) {
337 ctr[y] = 0x00;
338 }
339 } else {
340 XMEMCPY(ctr, CTR, 16);
341 }
342
343 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
344 goto error;
345 }
346
347 if (skey != uskey) {
348 cipher_descriptor[cipher].done(skey);
349 }
350
351 /* store the TAG */
352 for (x = 0; x < 16 && x < *taglen; x++) {
353 tag[x] = PAD[x] ^ CTRPAD[x];
354 }
355 *taglen = x;
356
357 if (CTR != NULL) {
358 for (z = 15; z > 15-ctrwidth; z--) {
359 ctrcopy[z] = (ctrcopy[z] + 1) & 255;
360 if (ctrcopy[z]) break;
361 }
362 memcpy(CTR, ctrcopy, 16);
363 }
364
365 #ifdef LTC_CLEAN_STACK
366 zeromem(skey, sizeof(*skey));
367 zeromem(PAD, sizeof(PAD));
368 zeromem(CTRPAD, sizeof(CTRPAD));
369 #endif
370 error:
371 if (skey != uskey) {
372 XFREE(skey);
373 }
374
375 return err;
376 }
377
378 #endif
379
380 /* $Source$ */
381 /* $Revision$ */
382 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @file eax_addheader.c
12 EAX implementation, add meta-data, by Tom St Denis
13 */
14 #include "tomcrypt.h"
15
16 #ifdef LTC_EAX_MODE
17
18 /**
19 add header (metadata) to the stream
20 @param eax The current EAX state
21 @param header The header (meta-data) data you wish to add to the state
22 @param length The length of the header data
23 @return CRYPT_OK if successful
24 */
25 int eax_addheader(eax_state *eax, const unsigned char *header,
26 unsigned long length)
27 {
28 LTC_ARGCHK(eax != NULL);
29 LTC_ARGCHK(header != NULL);
30 return omac_process(&eax->headeromac, header, length);
31 }
32
33 #endif
34
35 /* $Source$ */
36 /* $Revision$ */
37 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_decrypt.c
13 EAX implementation, decrypt block, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Decrypt data with the EAX protocol
21 @param eax The EAX state
22 @param ct The ciphertext
23 @param pt [out] The plaintext
24 @param length The length (octets) of the ciphertext
25 @return CRYPT_OK if successful
26 */
27 int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt,
28 unsigned long length)
29 {
30 int err;
31
32 LTC_ARGCHK(eax != NULL);
33 LTC_ARGCHK(pt != NULL);
34 LTC_ARGCHK(ct != NULL);
35
36 /* omac ciphertext */
37 if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) {
38 return err;
39 }
40
41 /* decrypt */
42 return ctr_decrypt(ct, pt, length, &eax->ctr);
43 }
44
45 #endif
46
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_decrypt_verify_memory.c
13 EAX implementation, decrypt block of memory, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Decrypt a block of memory and verify the provided MAC tag with EAX
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the key (octets)
24 @param nonce The nonce data (use once) for the session
25 @param noncelen The length of the nonce data.
26 @param header The session header data
27 @param headerlen The length of the header (octets)
28 @param ct The ciphertext
29 @param ctlen The length of the ciphertext (octets)
30 @param pt [out] The plaintext
31 @param tag The authentication tag provided by the encoder
32 @param taglen [in/out] The length of the tag (octets)
33 @param stat [out] The result of the decryption (1==valid tag, 0==invalid)
34 @return CRYPT_OK if successful regardless of the resulting tag comparison
35 */
36 int eax_decrypt_verify_memory(int cipher,
37 const unsigned char *key, unsigned long keylen,
38 const unsigned char *nonce, unsigned long noncelen,
39 const unsigned char *header, unsigned long headerlen,
40 const unsigned char *ct, unsigned long ctlen,
41 unsigned char *pt,
42 unsigned char *tag, unsigned long taglen,
43 int *stat)
44 {
45 int err;
46 eax_state *eax;
47 unsigned char *buf;
48 unsigned long buflen;
49
50 LTC_ARGCHK(stat != NULL);
51 LTC_ARGCHK(key != NULL);
52 LTC_ARGCHK(pt != NULL);
53 LTC_ARGCHK(ct != NULL);
54 LTC_ARGCHK(tag != NULL);
55
56 /* default to zero */
57 *stat = 0;
58
59 /* allocate ram */
60 buf = XMALLOC(taglen);
61 eax = XMALLOC(sizeof(*eax));
62 if (eax == NULL || buf == NULL) {
63 if (eax != NULL) {
64 XFREE(eax);
65 }
66 if (buf != NULL) {
67 XFREE(buf);
68 }
69 return CRYPT_MEM;
70 }
71
72 if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
73 goto LBL_ERR;
74 }
75
76 if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79
80 buflen = taglen;
81 if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) {
82 goto LBL_ERR;
83 }
84
85 /* compare tags */
86 if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) {
87 *stat = 1;
88 }
89
90 err = CRYPT_OK;
91 LBL_ERR:
92 #ifdef LTC_CLEAN_STACK
93 zeromem(buf, taglen);
94 zeromem(eax, sizeof(*eax));
95 #endif
96
97 XFREE(eax);
98 XFREE(buf);
99
100 return err;
101 }
102
103 #endif
104
105 /* $Source$ */
106 /* $Revision$ */
107 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_done.c
13 EAX implementation, terminate session, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Terminate an EAX session and get the tag.
21 @param eax The EAX state
22 @param tag [out] The destination of the authentication tag
23 @param taglen [in/out] The max length and resulting length of the authentication tag
24 @return CRYPT_OK if successful
25 */
26 int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen)
27 {
28 int err;
29 unsigned char *headermac, *ctmac;
30 unsigned long x, len;
31
32 LTC_ARGCHK(eax != NULL);
33 LTC_ARGCHK(tag != NULL);
34 LTC_ARGCHK(taglen != NULL);
35
36 /* allocate ram */
37 headermac = XMALLOC(MAXBLOCKSIZE);
38 ctmac = XMALLOC(MAXBLOCKSIZE);
39
40 if (headermac == NULL || ctmac == NULL) {
41 if (headermac != NULL) {
42 XFREE(headermac);
43 }
44 if (ctmac != NULL) {
45 XFREE(ctmac);
46 }
47 return CRYPT_MEM;
48 }
49
50 /* finish ctomac */
51 len = MAXBLOCKSIZE;
52 if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) {
53 goto LBL_ERR;
54 }
55
56 /* finish headeromac */
57
58 /* note we specifically don't reset len so the two lens are minimal */
59
60 if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) {
61 goto LBL_ERR;
62 }
63
64 /* terminate the CTR chain */
65 if ((err = ctr_done(&eax->ctr)) != CRYPT_OK) {
66 goto LBL_ERR;
67 }
68
69 /* compute N xor H xor C */
70 for (x = 0; x < len && x < *taglen; x++) {
71 tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x];
72 }
73 *taglen = x;
74
75 err = CRYPT_OK;
76 LBL_ERR:
77 #ifdef LTC_CLEAN_STACK
78 zeromem(ctmac, MAXBLOCKSIZE);
79 zeromem(headermac, MAXBLOCKSIZE);
80 zeromem(eax, sizeof(*eax));
81 #endif
82
83 XFREE(ctmac);
84 XFREE(headermac);
85
86 return err;
87 }
88
89 #endif
90
91 /* $Source$ */
92 /* $Revision$ */
93 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_encrypt.c
13 EAX implementation, encrypt block by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Encrypt with EAX a block of data.
21 @param eax The EAX state
22 @param pt The plaintext to encrypt
23 @param ct [out] The ciphertext as encrypted
24 @param length The length of the plaintext (octets)
25 @return CRYPT_OK if successful
26 */
27 int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct,
28 unsigned long length)
29 {
30 int err;
31
32 LTC_ARGCHK(eax != NULL);
33 LTC_ARGCHK(pt != NULL);
34 LTC_ARGCHK(ct != NULL);
35
36 /* encrypt */
37 if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) {
38 return err;
39 }
40
41 /* omac ciphertext */
42 return omac_process(&eax->ctomac, ct, length);
43 }
44
45 #endif
46
47
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_encrypt_authenticate_memory.c
13 EAX implementation, encrypt a block of memory, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 EAX encrypt and produce an authentication tag
21 @param cipher The index of the cipher desired
22 @param key The secret key to use
23 @param keylen The length of the secret key (octets)
24 @param nonce The session nonce [use once]
25 @param noncelen The length of the nonce
26 @param header The header for the session
27 @param headerlen The length of the header (octets)
28 @param pt The plaintext
29 @param ptlen The length of the plaintext (octets)
30 @param ct [out] The ciphertext
31 @param tag [out] The destination tag
32 @param taglen [in/out] The max size and resulting size of the authentication tag
33 @return CRYPT_OK if successful
34 */
35 int eax_encrypt_authenticate_memory(int cipher,
36 const unsigned char *key, unsigned long keylen,
37 const unsigned char *nonce, unsigned long noncelen,
38 const unsigned char *header, unsigned long headerlen,
39 const unsigned char *pt, unsigned long ptlen,
40 unsigned char *ct,
41 unsigned char *tag, unsigned long *taglen)
42 {
43 int err;
44 eax_state *eax;
45
46 LTC_ARGCHK(key != NULL);
47 LTC_ARGCHK(pt != NULL);
48 LTC_ARGCHK(ct != NULL);
49 LTC_ARGCHK(tag != NULL);
50 LTC_ARGCHK(taglen != NULL);
51
52 eax = XMALLOC(sizeof(*eax));
53
54 if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57
58 if ((err = eax_encrypt(eax, pt, ct, ptlen)) != CRYPT_OK) {
59 goto LBL_ERR;
60 }
61
62 if ((err = eax_done(eax, tag, taglen)) != CRYPT_OK) {
63 goto LBL_ERR;
64 }
65
66 err = CRYPT_OK;
67 LBL_ERR:
68 #ifdef LTC_CLEAN_STACK
69 zeromem(eax, sizeof(*eax));
70 #endif
71
72 XFREE(eax);
73
74 return err;
75 }
76
77 #endif
78
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file eax_init.c
13 EAX implementation, initialized EAX state, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_EAX_MODE
18
19 /**
20 Initialized an EAX state
21 @param eax [out] The EAX state to initialize
22 @param cipher The index of the desired cipher
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param nonce The use-once nonce for the session
26 @param noncelen The length of the nonce (octets)
27 @param header The header for the EAX state
28 @param headerlen The header length (octets)
29 @return CRYPT_OK if successful
30 */
31 int eax_init(eax_state *eax, int cipher,
32 const unsigned char *key, unsigned long keylen,
33 const unsigned char *nonce, unsigned long noncelen,
34 const unsigned char *header, unsigned long headerlen)
35 {
36 unsigned char *buf;
37 int err, blklen;
38 omac_state *omac;
39 unsigned long len;
40
41
42 LTC_ARGCHK(eax != NULL);
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(nonce != NULL);
45 if (headerlen > 0) {
46 LTC_ARGCHK(header != NULL);
47 }
48
49 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
50 return err;
51 }
52 blklen = cipher_descriptor[cipher].block_length;
53
54 /* allocate ram */
55 buf = XMALLOC(MAXBLOCKSIZE);
56 omac = XMALLOC(sizeof(*omac));
57
58 if (buf == NULL || omac == NULL) {
59 if (buf != NULL) {
60 XFREE(buf);
61 }
62 if (omac != NULL) {
63 XFREE(omac);
64 }
65 return CRYPT_MEM;
66 }
67
68 /* N = LTC_OMAC_0K(nonce) */
69 zeromem(buf, MAXBLOCKSIZE);
70 if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
71 goto LBL_ERR;
72 }
73
74 /* omac the [0]_n */
75 if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) {
76 goto LBL_ERR;
77 }
78 /* omac the nonce */
79 if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) {
80 goto LBL_ERR;
81 }
82 /* store result */
83 len = sizeof(eax->N);
84 if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) {
85 goto LBL_ERR;
86 }
87
88 /* H = LTC_OMAC_1K(header) */
89 zeromem(buf, MAXBLOCKSIZE);
90 buf[blklen - 1] = 1;
91
92 if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) {
93 goto LBL_ERR;
94 }
95
96 /* omac the [1]_n */
97 if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) {
98 goto LBL_ERR;
99 }
100 /* omac the header */
101 if (headerlen != 0) {
102 if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) {
103 goto LBL_ERR;
104 }
105 }
106
107 /* note we don't finish the headeromac, this allows us to add more header later */
108
109 /* setup the CTR mode */
110 if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) {
111 goto LBL_ERR;
112 }
113
114 /* setup the LTC_OMAC for the ciphertext */
115 if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) {
116 goto LBL_ERR;
117 }
118
119 /* omac [2]_n */
120 zeromem(buf, MAXBLOCKSIZE);
121 buf[blklen-1] = 2;
122 if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) {
123 goto LBL_ERR;
124 }
125
126 err = CRYPT_OK;
127 LBL_ERR:
128 #ifdef LTC_CLEAN_STACK
129 zeromem(buf, MAXBLOCKSIZE);
130 zeromem(omac, sizeof(*omac));
131 #endif
132
133 XFREE(omac);
134 XFREE(buf);
135
136 return err;
137 }
138
139 #endif
140
141 /* $Source$ */
142 /* $Revision$ */
143 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_add_aad.c
13 GCM implementation, Add AAD data to the stream, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Add AAD to the GCM state
21 @param gcm The GCM state
22 @param adata The additional authentication data to add to the GCM state
23 @param adatalen The length of the AAD data.
24 @return CRYPT_OK on success
25 */
26 int gcm_add_aad(gcm_state *gcm,
27 const unsigned char *adata, unsigned long adatalen)
28 {
29 unsigned long x;
30 int err;
31 #ifdef LTC_FAST
32 unsigned long y;
33 #endif
34
35 LTC_ARGCHK(gcm != NULL);
36 if (adatalen > 0) {
37 LTC_ARGCHK(adata != NULL);
38 }
39
40 if (gcm->buflen > 16 || gcm->buflen < 0) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* in IV mode? */
49 if (gcm->mode == LTC_GCM_MODE_IV) {
50 /* let's process the IV */
51 if (gcm->ivmode || gcm->buflen != 12) {
52 for (x = 0; x < (unsigned long)gcm->buflen; x++) {
53 gcm->X[x] ^= gcm->buf[x];
54 }
55 if (gcm->buflen) {
56 gcm->totlen += gcm->buflen * CONST64(8);
57 gcm_mult_h(gcm, gcm->X);
58 }
59
60 /* mix in the length */
61 zeromem(gcm->buf, 8);
62 STORE64H(gcm->totlen, gcm->buf+8);
63 for (x = 0; x < 16; x++) {
64 gcm->X[x] ^= gcm->buf[x];
65 }
66 gcm_mult_h(gcm, gcm->X);
67
68 /* copy counter out */
69 XMEMCPY(gcm->Y, gcm->X, 16);
70 zeromem(gcm->X, 16);
71 } else {
72 XMEMCPY(gcm->Y, gcm->buf, 12);
73 gcm->Y[12] = 0;
74 gcm->Y[13] = 0;
75 gcm->Y[14] = 0;
76 gcm->Y[15] = 1;
77 }
78 XMEMCPY(gcm->Y_0, gcm->Y, 16);
79 zeromem(gcm->buf, 16);
80 gcm->buflen = 0;
81 gcm->totlen = 0;
82 gcm->mode = LTC_GCM_MODE_AAD;
83 }
84
85 if (gcm->mode != LTC_GCM_MODE_AAD || gcm->buflen >= 16) {
86 return CRYPT_INVALID_ARG;
87 }
88
89 x = 0;
90 #ifdef LTC_FAST
91 if (gcm->buflen == 0) {
92 for (x = 0; x < (adatalen & ~15); x += 16) {
93 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
94 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&adata[x + y]));
95 }
96 gcm_mult_h(gcm, gcm->X);
97 gcm->totlen += 128;
98 }
99 adata += x;
100 }
101 #endif
102
103
104 /* start adding AAD data to the state */
105 for (; x < adatalen; x++) {
106 gcm->X[gcm->buflen++] ^= *adata++;
107
108 if (gcm->buflen == 16) {
109 /* GF mult it */
110 gcm_mult_h(gcm, gcm->X);
111 gcm->buflen = 0;
112 gcm->totlen += 128;
113 }
114 }
115
116 return CRYPT_OK;
117 }
118 #endif
119
120
121 /* $Source$ */
122 /* $Revision$ */
123 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_add_iv.c
13 GCM implementation, add IV data to the state, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Add IV data to the GCM state
21 @param gcm The GCM state
22 @param IV The initial value data to add
23 @param IVlen The length of the IV
24 @return CRYPT_OK on success
25 */
26 int gcm_add_iv(gcm_state *gcm,
27 const unsigned char *IV, unsigned long IVlen)
28 {
29 unsigned long x, y;
30 int err;
31
32 LTC_ARGCHK(gcm != NULL);
33 if (IVlen > 0) {
34 LTC_ARGCHK(IV != NULL);
35 }
36
37 /* must be in IV mode */
38 if (gcm->mode != LTC_GCM_MODE_IV) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 if (gcm->buflen >= 16 || gcm->buflen < 0) {
43 return CRYPT_INVALID_ARG;
44 }
45
46 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
47 return err;
48 }
49
50
51 /* trip the ivmode flag */
52 if (IVlen + gcm->buflen > 12) {
53 gcm->ivmode |= 1;
54 }
55
56 x = 0;
57 #ifdef LTC_FAST
58 if (gcm->buflen == 0) {
59 for (x = 0; x < (IVlen & ~15); x += 16) {
60 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
61 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&IV[x + y]));
62 }
63 gcm_mult_h(gcm, gcm->X);
64 gcm->totlen += 128;
65 }
66 IV += x;
67 }
68 #endif
69
70 /* start adding IV data to the state */
71 for (; x < IVlen; x++) {
72 gcm->buf[gcm->buflen++] = *IV++;
73
74 if (gcm->buflen == 16) {
75 /* GF mult it */
76 for (y = 0; y < 16; y++) {
77 gcm->X[y] ^= gcm->buf[y];
78 }
79 gcm_mult_h(gcm, gcm->X);
80 gcm->buflen = 0;
81 gcm->totlen += 128;
82 }
83 }
84
85 return CRYPT_OK;
86 }
87
88 #endif
89
90
91 /* $Source$ */
92 /* $Revision$ */
93 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_done.c
13 GCM implementation, Terminate the stream, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Terminate a GCM stream
21 @param gcm The GCM state
22 @param tag [out] The destination for the MAC tag
23 @param taglen [in/out] The length of the MAC tag
24 @return CRYPT_OK on success
25 */
26 int gcm_done(gcm_state *gcm,
27 unsigned char *tag, unsigned long *taglen)
28 {
29 unsigned long x;
30 int err;
31
32 LTC_ARGCHK(gcm != NULL);
33 LTC_ARGCHK(tag != NULL);
34 LTC_ARGCHK(taglen != NULL);
35
36 if (gcm->buflen > 16 || gcm->buflen < 0) {
37 return CRYPT_INVALID_ARG;
38 }
39
40 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
41 return err;
42 }
43
44
45 if (gcm->mode != LTC_GCM_MODE_TEXT) {
46 return CRYPT_INVALID_ARG;
47 }
48
49 /* handle remaining ciphertext */
50 if (gcm->buflen) {
51 gcm->pttotlen += gcm->buflen * CONST64(8);
52 gcm_mult_h(gcm, gcm->X);
53 }
54
55 /* length */
56 STORE64H(gcm->totlen, gcm->buf);
57 STORE64H(gcm->pttotlen, gcm->buf+8);
58 for (x = 0; x < 16; x++) {
59 gcm->X[x] ^= gcm->buf[x];
60 }
61 gcm_mult_h(gcm, gcm->X);
62
63 /* encrypt original counter */
64 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
65 return err;
66 }
67 for (x = 0; x < 16 && x < *taglen; x++) {
68 tag[x] = gcm->buf[x] ^ gcm->X[x];
69 }
70 *taglen = x;
71
72 cipher_descriptor[gcm->cipher].done(&gcm->K);
73
74 return CRYPT_OK;
75 }
76
77 #endif
78
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_gf_mult.c
13 GCM implementation, do the GF mult, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
18
19 /* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the
20 * lower 16 bits are not zero'ed I removed the upper 14 bytes */
21 const unsigned char gcm_shift_table[256*2] = {
22 0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e,
23 0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e,
24 0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e,
25 0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e,
26 0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e,
27 0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e,
28 0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e,
29 0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e,
30 0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce,
31 0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde,
32 0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee,
33 0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe,
34 0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e,
35 0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e,
36 0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae,
37 0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe,
38 0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e,
39 0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e,
40 0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e,
41 0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e,
42 0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e,
43 0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e,
44 0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e,
45 0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e,
46 0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce,
47 0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde,
48 0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee,
49 0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe,
50 0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e,
51 0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e,
52 0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae,
53 0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe };
54
55 #endif
56
57
58 #if defined(LTC_GCM_MODE) || defined(LRW_MODE)
59
60 #ifndef LTC_FAST
61 /* right shift */
62 static void gcm_rightshift(unsigned char *a)
63 {
64 int x;
65 for (x = 15; x > 0; x--) {
66 a[x] = (a[x]>>1) | ((a[x-1]<<7)&0x80);
67 }
68 a[0] >>= 1;
69 }
70
71 /* c = b*a */
72 static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
73 static const unsigned char poly[] = { 0x00, 0xE1 };
74
75
76 /**
77 GCM GF multiplier (internal use only) bitserial
78 @param a First value
79 @param b Second value
80 @param c Destination for a * b
81 */
82 void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c)
83 {
84 unsigned char Z[16], V[16];
85 unsigned x, y, z;
86
87 zeromem(Z, 16);
88 XMEMCPY(V, a, 16);
89 for (x = 0; x < 128; x++) {
90 if (b[x>>3] & mask[x&7]) {
91 for (y = 0; y < 16; y++) {
92 Z[y] ^= V[y];
93 }
94 }
95 z = V[15] & 0x01;
96 gcm_rightshift(V);
97 V[0] ^= poly[z];
98 }
99 XMEMCPY(c, Z, 16);
100 }
101
102 #else
103
104 /* map normal numbers to "ieee" way ... e.g. bit reversed */
105 #define M(x) ( ((x&8)>>3) | ((x&4)>>1) | ((x&2)<<1) | ((x&1)<<3) )
106
107 #define BPD (sizeof(LTC_FAST_TYPE) * 8)
108 #define WPV (1 + (16 / sizeof(LTC_FAST_TYPE)))
109
110 /**
111 GCM GF multiplier (internal use only) word oriented
112 @param a First value
113 @param b Second value
114 @param c Destination for a * b
115 */
116 void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c)
117 {
118 int i, j, k, u;
119 LTC_FAST_TYPE B[16][WPV], tmp[32 / sizeof(LTC_FAST_TYPE)], pB[16 / sizeof(LTC_FAST_TYPE)], zz, z;
120 unsigned char pTmp[32];
121
122 /* create simple tables */
123 zeromem(B[0], sizeof(B[0]));
124 zeromem(B[M(1)], sizeof(B[M(1)]));
125
126 #ifdef ENDIAN_32BITWORD
127 for (i = 0; i < 4; i++) {
128 LOAD32H(B[M(1)][i], a + (i<<2));
129 LOAD32L(pB[i], b + (i<<2));
130 }
131 #else
132 for (i = 0; i < 2; i++) {
133 LOAD64H(B[M(1)][i], a + (i<<3));
134 LOAD64L(pB[i], b + (i<<3));
135 }
136 #endif
137
138 /* now create 2, 4 and 8 */
139 B[M(2)][0] = B[M(1)][0] >> 1;
140 B[M(4)][0] = B[M(1)][0] >> 2;
141 B[M(8)][0] = B[M(1)][0] >> 3;
142 for (i = 1; i < (int)WPV; i++) {
143 B[M(2)][i] = (B[M(1)][i-1] << (BPD-1)) | (B[M(1)][i] >> 1);
144 B[M(4)][i] = (B[M(1)][i-1] << (BPD-2)) | (B[M(1)][i] >> 2);
145 B[M(8)][i] = (B[M(1)][i-1] << (BPD-3)) | (B[M(1)][i] >> 3);
146 }
147
148 /* now all values with two bits which are 3, 5, 6, 9, 10, 12 */
149 for (i = 0; i < (int)WPV; i++) {
150 B[M(3)][i] = B[M(1)][i] ^ B[M(2)][i];
151 B[M(5)][i] = B[M(1)][i] ^ B[M(4)][i];
152 B[M(6)][i] = B[M(2)][i] ^ B[M(4)][i];
153 B[M(9)][i] = B[M(1)][i] ^ B[M(8)][i];
154 B[M(10)][i] = B[M(2)][i] ^ B[M(8)][i];
155 B[M(12)][i] = B[M(8)][i] ^ B[M(4)][i];
156
157 /* now all 3 bit values and the only 4 bit value: 7, 11, 13, 14, 15 */
158 B[M(7)][i] = B[M(3)][i] ^ B[M(4)][i];
159 B[M(11)][i] = B[M(3)][i] ^ B[M(8)][i];
160 B[M(13)][i] = B[M(1)][i] ^ B[M(12)][i];
161 B[M(14)][i] = B[M(6)][i] ^ B[M(8)][i];
162 B[M(15)][i] = B[M(7)][i] ^ B[M(8)][i];
163 }
164
165 zeromem(tmp, sizeof(tmp));
166
167 /* compute product four bits of each word at a time */
168 /* for each nibble */
169 for (i = (BPD/4)-1; i >= 0; i--) {
170 /* for each word */
171 for (j = 0; j < (int)(WPV-1); j++) {
172 /* grab the 4 bits recall the nibbles are backwards so it's a shift by (i^1)*4 */
173 u = (pB[j] >> ((i^1)<<2)) & 15;
174
175 /* add offset by the word count the table looked up value to the result */
176 for (k = 0; k < (int)WPV; k++) {
177 tmp[k+j] ^= B[u][k];
178 }
179 }
180 /* shift result up by 4 bits */
181 if (i != 0) {
182 for (z = j = 0; j < (int)(32 / sizeof(LTC_FAST_TYPE)); j++) {
183 zz = tmp[j] << (BPD-4);
184 tmp[j] = (tmp[j] >> 4) | z;
185 z = zz;
186 }
187 }
188 }
189
190 /* store product */
191 #ifdef ENDIAN_32BITWORD
192 for (i = 0; i < 8; i++) {
193 STORE32H(tmp[i], pTmp + (i<<2));
194 }
195 #else
196 for (i = 0; i < 4; i++) {
197 STORE64H(tmp[i], pTmp + (i<<3));
198 }
199 #endif
200
201 /* reduce by taking most significant byte and adding the appropriate two byte sequence 16 bytes down */
202 for (i = 31; i >= 16; i--) {
203 pTmp[i-16] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)];
204 pTmp[i-15] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)+1];
205 }
206
207 for (i = 0; i < 16; i++) {
208 c[i] = pTmp[i];
209 }
210
211 }
212
213 #endif
214
215 #endif
216
217 /* $Source$ */
218 /* $Revision$ */
219 /* $Date$ */
220
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_init.c
13 GCM implementation, initialize state, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Initialize a GCM state
21 @param gcm The GCM state to initialize
22 @param cipher The index of the cipher to use
23 @param key The secret key
24 @param keylen The length of the secret key
25 @return CRYPT_OK on success
26 */
27 int gcm_init(gcm_state *gcm, int cipher,
28 const unsigned char *key, int keylen)
29 {
30 int err;
31 unsigned char B[16];
32 #ifdef LTC_GCM_TABLES
33 int x, y, z, t;
34 #endif
35
36 LTC_ARGCHK(gcm != NULL);
37 LTC_ARGCHK(key != NULL);
38
39 #ifdef LTC_FAST
40 if (16 % sizeof(LTC_FAST_TYPE)) {
41 return CRYPT_INVALID_ARG;
42 }
43 #endif
44
45 /* is cipher valid? */
46 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
47 return err;
48 }
49 if (cipher_descriptor[cipher].block_length != 16) {
50 return CRYPT_INVALID_CIPHER;
51 }
52
53 /* schedule key */
54 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) {
55 return err;
56 }
57
58 /* H = E(0) */
59 zeromem(B, 16);
60 if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
61 return err;
62 }
63
64 /* setup state */
65 zeromem(gcm->buf, sizeof(gcm->buf));
66 zeromem(gcm->X, sizeof(gcm->X));
67 gcm->cipher = cipher;
68 gcm->mode = LTC_GCM_MODE_IV;
69 gcm->ivmode = 0;
70 gcm->buflen = 0;
71 gcm->totlen = 0;
72 gcm->pttotlen = 0;
73
74 #ifdef LTC_GCM_TABLES
75 /* setup tables */
76
77 /* generate the first table as it has no shifting (from which we make the other tables) */
78 zeromem(B, 16);
79 for (y = 0; y < 256; y++) {
80 B[0] = y;
81 gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]);
82 }
83
84 /* now generate the rest of the tables based the previous table */
85 for (x = 1; x < 16; x++) {
86 for (y = 0; y < 256; y++) {
87 /* now shift it right by 8 bits */
88 t = gcm->PC[x-1][y][15];
89 for (z = 15; z > 0; z--) {
90 gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1];
91 }
92 gcm->PC[x][y][0] = gcm_shift_table[t<<1];
93 gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
94 }
95 }
96
97 #endif
98
99 return CRYPT_OK;
100 }
101
102 #endif
103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_memory.c
13 GCM implementation, process a packet, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Process an entire GCM packet in one call.
21 @param cipher Index of cipher to use
22 @param key The secret key
23 @param keylen The length of the secret key
24 @param IV The initial vector
25 @param IVlen The length of the initial vector
26 @param adata The additional authentication data (header)
27 @param adatalen The length of the adata
28 @param pt The plaintext
29 @param ptlen The length of the plaintext (ciphertext length is the same)
30 @param ct The ciphertext
31 @param tag [out] The MAC tag
32 @param taglen [in/out] The MAC tag length
33 @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
34 @return CRYPT_OK on success
35 */
36 int gcm_memory( int cipher,
37 const unsigned char *key, unsigned long keylen,
38 const unsigned char *IV, unsigned long IVlen,
39 const unsigned char *adata, unsigned long adatalen,
40 unsigned char *pt, unsigned long ptlen,
41 unsigned char *ct,
42 unsigned char *tag, unsigned long *taglen,
43 int direction)
44 {
45 void *orig;
46 gcm_state *gcm;
47 int err;
48
49 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
50 return err;
51 }
52
53 if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
54 return
55 cipher_descriptor[cipher].accel_gcm_memory
56 (key, keylen,
57 IV, IVlen,
58 adata, adatalen,
59 pt, ptlen,
60 ct,
61 tag, taglen,
62 direction);
63 }
64
65
66
67 #ifndef LTC_GCM_TABLES_SSE2
68 orig = gcm = XMALLOC(sizeof(*gcm));
69 #else
70 orig = gcm = XMALLOC(sizeof(*gcm) + 16);
71 #endif
72 if (gcm == NULL) {
73 return CRYPT_MEM;
74 }
75
76 /* Force GCM to be on a multiple of 16 so we can use 128-bit aligned operations
77 * note that we only modify gcm and keep orig intact. This code is not portable
78 * but again it's only for SSE2 anyways, so who cares?
79 */
80 #ifdef LTC_GCM_TABLES_SSE2
81 if ((unsigned long)gcm & 15) {
82 gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
83 }
84 #endif
85
86 if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {
87 goto LTC_ERR;
88 }
89 if ((err = gcm_add_iv(gcm, IV, IVlen)) != CRYPT_OK) {
90 goto LTC_ERR;
91 }
92 if ((err = gcm_add_aad(gcm, adata, adatalen)) != CRYPT_OK) {
93 goto LTC_ERR;
94 }
95 if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) {
96 goto LTC_ERR;
97 }
98 err = gcm_done(gcm, tag, taglen);
99 LTC_ERR:
100 XFREE(orig);
101 return err;
102 }
103 #endif
104
105
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_mult_h.c
13 GCM implementation, do the GF mult, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #if defined(LTC_GCM_MODE)
18 /**
19 GCM multiply by H
20 @param gcm The GCM state which holds the H value
21 @param I The value to multiply H by
22 */
23 void gcm_mult_h(gcm_state *gcm, unsigned char *I)
24 {
25 unsigned char T[16];
26 #ifdef LTC_GCM_TABLES
27 int x, y;
28 #ifdef LTC_GCM_TABLES_SSE2
29 asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
30 for (x = 1; x < 16; x++) {
31 asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
32 }
33 asm("movdqa %%xmm0,(%0)"::"r"(&T));
34 #else
35 XMEMCPY(T, &gcm->PC[0][I[0]][0], 16);
36 for (x = 1; x < 16; x++) {
37 #ifdef LTC_FAST
38 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
39 *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][I[x]][y]));
40 }
41 #else
42 for (y = 0; y < 16; y++) {
43 T[y] ^= gcm->PC[x][I[x]][y];
44 }
45 #endif /* LTC_FAST */
46 }
47 #endif /* LTC_GCM_TABLES_SSE2 */
48 #else
49 gcm_gf_mult(gcm->H, I, T);
50 #endif
51 XMEMCPY(I, T, 16);
52 }
53 #endif
54
55 /* $Source$ */
56 /* $Revision$ */
57 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_process.c
13 GCM implementation, process message data, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Process plaintext/ciphertext through GCM
21 @param gcm The GCM state
22 @param pt The plaintext
23 @param ptlen The plaintext length (ciphertext length is the same)
24 @param ct The ciphertext
25 @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
26 @return CRYPT_OK on success
27 */
28 int gcm_process(gcm_state *gcm,
29 unsigned char *pt, unsigned long ptlen,
30 unsigned char *ct,
31 int direction)
32 {
33 unsigned long x;
34 int y, err;
35 unsigned char b;
36
37 LTC_ARGCHK(gcm != NULL);
38 if (ptlen > 0) {
39 LTC_ARGCHK(pt != NULL);
40 LTC_ARGCHK(ct != NULL);
41 }
42
43 if (gcm->buflen > 16 || gcm->buflen < 0) {
44 return CRYPT_INVALID_ARG;
45 }
46
47 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
48 return err;
49 }
50
51 /* in AAD mode? */
52 if (gcm->mode == LTC_GCM_MODE_AAD) {
53 /* let's process the AAD */
54 if (gcm->buflen) {
55 gcm->totlen += gcm->buflen * CONST64(8);
56 gcm_mult_h(gcm, gcm->X);
57 }
58
59 /* increment counter */
60 for (y = 15; y >= 12; y--) {
61 if (++gcm->Y[y] & 255) { break; }
62 }
63 /* encrypt the counter */
64 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
65 return err;
66 }
67
68 gcm->buflen = 0;
69 gcm->mode = LTC_GCM_MODE_TEXT;
70 }
71
72 if (gcm->mode != LTC_GCM_MODE_TEXT) {
73 return CRYPT_INVALID_ARG;
74 }
75
76 x = 0;
77 #ifdef LTC_FAST
78 if (gcm->buflen == 0) {
79 if (direction == GCM_ENCRYPT) {
80 for (x = 0; x < (ptlen & ~15); x += 16) {
81 /* ctr encrypt */
82 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
83 *((LTC_FAST_TYPE*)(&ct[x + y])) = *((LTC_FAST_TYPE*)(&pt[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y]));
84 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y]));
85 }
86 /* GMAC it */
87 gcm->pttotlen += 128;
88 gcm_mult_h(gcm, gcm->X);
89 /* increment counter */
90 for (y = 15; y >= 12; y--) {
91 if (++gcm->Y[y] & 255) { break; }
92 }
93 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
94 return err;
95 }
96 }
97 } else {
98 for (x = 0; x < (ptlen & ~15); x += 16) {
99 /* ctr encrypt */
100 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
101 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y]));
102 *((LTC_FAST_TYPE*)(&pt[x + y])) = *((LTC_FAST_TYPE*)(&ct[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y]));
103 }
104 /* GMAC it */
105 gcm->pttotlen += 128;
106 gcm_mult_h(gcm, gcm->X);
107 /* increment counter */
108 for (y = 15; y >= 12; y--) {
109 if (++gcm->Y[y] & 255) { break; }
110 }
111 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
112 return err;
113 }
114 }
115 }
116 }
117 #endif
118
119 /* process text */
120 for (; x < ptlen; x++) {
121 if (gcm->buflen == 16) {
122 gcm->pttotlen += 128;
123 gcm_mult_h(gcm, gcm->X);
124
125 /* increment counter */
126 for (y = 15; y >= 12; y--) {
127 if (++gcm->Y[y] & 255) { break; }
128 }
129 if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
130 return err;
131 }
132 gcm->buflen = 0;
133 }
134
135 if (direction == GCM_ENCRYPT) {
136 b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen];
137 } else {
138 b = ct[x];
139 pt[x] = ct[x] ^ gcm->buf[gcm->buflen];
140 }
141 gcm->X[gcm->buflen++] ^= b;
142 }
143
144 return CRYPT_OK;
145 }
146
147 #endif
148
149 /* $Source$ */
150 /* $Revision$ */
151 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file gcm_reset.c
13 GCM implementation, reset a used state so it can accept IV data, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_GCM_MODE
18
19 /**
20 Reset a GCM state to as if you just called gcm_init(). This saves the initialization time.
21 @param gcm The GCM state to reset
22 @return CRYPT_OK on success
23 */
24 int gcm_reset(gcm_state *gcm)
25 {
26 LTC_ARGCHK(gcm != NULL);
27
28 zeromem(gcm->buf, sizeof(gcm->buf));
29 zeromem(gcm->X, sizeof(gcm->X));
30 gcm->mode = LTC_GCM_MODE_IV;
31 gcm->ivmode = 0;
32 gcm->buflen = 0;
33 gcm->totlen = 0;
34 gcm->pttotlen = 0;
35
36 return CRYPT_OK;
37 }
38
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_add_aad.c
11 OCB implementation, add AAD data, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Add AAD - additional associated data
19 @param ocb The OCB state
20 @param aad The AAD data
21 @param aadlen The size of AAD data (octets)
22 @return CRYPT_OK if successful
23 */
24 int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen)
25 {
26 int err, x, full_blocks, full_blocks_len, last_block_len;
27 unsigned char *data;
28 unsigned long datalen, l;
29
30 LTC_ARGCHK(ocb != NULL);
31 LTC_ARGCHK(aad != NULL);
32
33 if (aadlen == 0) return CRYPT_OK;
34
35 if (ocb->adata_buffer_bytes > 0) {
36 l = ocb->block_len - ocb->adata_buffer_bytes;
37 if (l > aadlen) l = aadlen;
38 XMEMCPY(ocb->adata_buffer+ocb->adata_buffer_bytes, aad, l);
39 ocb->adata_buffer_bytes += l;
40
41 if (ocb->adata_buffer_bytes == ocb->block_len) {
42 if ((err = ocb3_int_aad_add_block(ocb, ocb->adata_buffer)) != CRYPT_OK) {
43 return err;
44 }
45 ocb->adata_buffer_bytes = 0;
46 }
47
48 data = (unsigned char *)aad + l;
49 datalen = aadlen - l;
50 }
51 else {
52 data = (unsigned char *)aad;
53 datalen = aadlen;
54 }
55
56 if (datalen <= 0) return CRYPT_OK;
57
58 full_blocks = datalen/ocb->block_len;
59 full_blocks_len = full_blocks * ocb->block_len;
60 last_block_len = datalen - full_blocks_len;
61
62 for (x=0; x<full_blocks; x++) {
63 if ((err = ocb3_int_aad_add_block(ocb, data+x*ocb->block_len)) != CRYPT_OK) {
64 return err;
65 }
66 }
67
68 if (last_block_len>0) {
69 XMEMCPY(ocb->adata_buffer, data+full_blocks_len, last_block_len);
70 ocb->adata_buffer_bytes = last_block_len;
71 }
72
73 return CRYPT_OK;
74 }
75
76 #endif
77
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_decrypt.c
13 OCB implementation, decrypt data, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Decrypt blocks of ciphertext with OCB
21 @param ocb The OCB state
22 @param ct The ciphertext (length multiple of the block size of the block cipher)
23 @param ctlen The length of the input (octets)
24 @param pt [out] The plaintext (length of ct)
25 @return CRYPT_OK if successful
26 */
27 int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
28 {
29 unsigned char tmp[MAXBLOCKSIZE];
30 int err, i, full_blocks;
31 unsigned char *pt_b, *ct_b;
32
33 LTC_ARGCHK(ocb != NULL);
34 LTC_ARGCHK(pt != NULL);
35 LTC_ARGCHK(ct != NULL);
36 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
37 return err;
38 }
39 if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 if (ctlen % ocb->block_len) { /* ctlen has to bu multiple of block_len */
44 return CRYPT_INVALID_ARG;
45 }
46
47 full_blocks = ctlen/ocb->block_len;
48 for(i=0; i<full_blocks; i++) {
49 pt_b = (unsigned char *)pt+i*ocb->block_len;
50 ct_b = (unsigned char *)ct+i*ocb->block_len;
51
52 /* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
53 ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);
54
55 /* tmp[] = ct[] XOR ocb->Offset_current[] */
56 ocb3_int_xor_blocks(tmp, ct_b, ocb->Offset_current, ocb->block_len);
57
58 /* decrypt */
59 if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
60 goto LBL_ERR;
61 }
62
63 /* pt[] = tmp[] XOR ocb->Offset_current[] */
64 ocb3_int_xor_blocks(pt_b, tmp, ocb->Offset_current, ocb->block_len);
65
66 /* ocb->checksum[] = ocb->checksum[] XOR pt[] */
67 ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);
68
69 ocb->block_index++;
70 }
71
72 err = CRYPT_OK;
73
74 LBL_ERR:
75 #ifdef LTC_CLEAN_STACK
76 zeromem(tmp, sizeof(tmp));
77 #endif
78 return err;
79 }
80
81 #endif
82
83 /* $Source$ */
84 /* $Revision$ */
85 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_decrypt_last.c
11 OCB implementation, internal helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Finish an OCB (decryption) stream
19 @param ocb The OCB state
20 @param ct The remaining ciphertext
21 @param ctlen The length of the ciphertext (octets)
22 @param pt [out] The output buffer
23 @return CRYPT_OK if successful
24 */
25 int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
26 {
27 unsigned char iOffset_star[MAXBLOCKSIZE];
28 unsigned char iPad[MAXBLOCKSIZE];
29 int err, x, full_blocks, full_blocks_len, last_block_len;
30
31 LTC_ARGCHK(ocb != NULL);
32 LTC_ARGCHK(ct != NULL);
33 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
34 goto LBL_ERR;
35 }
36
37 full_blocks = ctlen/ocb->block_len;
38 full_blocks_len = full_blocks * ocb->block_len;
39 last_block_len = ctlen - full_blocks_len;
40
41 /* process full blocks first */
42 if (full_blocks>0) {
43 if ((err = ocb3_decrypt(ocb, ct, full_blocks_len, pt)) != CRYPT_OK) {
44 goto LBL_ERR;
45 }
46 }
47
48 if (last_block_len>0) {
49 /* Offset_* = Offset_m xor L_* */
50 ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
51
52 /* Pad = ENCIPHER(K, Offset_*) */
53 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
54 goto LBL_ERR;
55 }
56
57 /* P_* = C_* xor Pad[1..bitlen(C_*)] */
58 ocb3_int_xor_blocks(pt+full_blocks_len, (unsigned char *)ct+full_blocks_len, iPad, last_block_len);
59
60 /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
61 ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
62 for(x=last_block_len; x<ocb->block_len; x++) {
63 if (x == last_block_len)
64 ocb->checksum[x] ^= 0x80;
65 else
66 ocb->checksum[x] ^= 0x00;
67 }
68
69 /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
70 /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
71 for(x=0; x<ocb->block_len; x++) {
72 ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
73 }
74 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77 }
78 else {
79 /* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
80 /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
81 for(x=0; x<ocb->block_len; x++) {
82 ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
83 }
84 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
85 goto LBL_ERR;
86 }
87 }
88
89 err = CRYPT_OK;
90
91 LBL_ERR:
92 #ifdef LTC_CLEAN_STACK
93 zeromem(iOffset_star, MAXBLOCKSIZE);
94 zeromem(iPad, MAXBLOCKSIZE);
95 #endif
96
97 return err;
98 }
99
100 #endif
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_decrypt_verify_memory.c
13 OCB implementation, helper to decrypt block of memory, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Decrypt and compare the tag with OCB
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param nonce The session nonce (length of the block size of the block cipher)
25 @param noncelen The length of the nonce (octets)
26 @param adata The AAD - additional associated data
27 @param adatalen The length of AAD (octets)
28 @param ct The ciphertext
29 @param ctlen The length of the ciphertext (octets)
30 @param pt [out] The plaintext
31 @param tag The tag to compare against
32 @param taglen The length of the tag (octets)
33 @param stat [out] The result of the tag comparison (1==valid, 0==invalid)
34 @return CRYPT_OK if successful regardless of the tag comparison
35 */
36 int ocb3_decrypt_verify_memory(int cipher,
37 const unsigned char *key, unsigned long keylen,
38 const unsigned char *nonce, unsigned long noncelen,
39 const unsigned char *adata, unsigned long adatalen,
40 const unsigned char *ct, unsigned long ctlen,
41 unsigned char *pt,
42 const unsigned char *tag, unsigned long taglen,
43 int *stat)
44 {
45 int err;
46 ocb3_state *ocb;
47 unsigned char *buf;
48 unsigned long buflen;
49
50 LTC_ARGCHK(key != NULL);
51 LTC_ARGCHK(nonce != NULL);
52 LTC_ARGCHK(pt != NULL);
53 LTC_ARGCHK(ct != NULL);
54 LTC_ARGCHK(tag != NULL);
55 LTC_ARGCHK(stat != NULL);
56
57 /* default to zero */
58 *stat = 0;
59
60 /* allocate memory */
61 buf = XMALLOC(taglen);
62 ocb = XMALLOC(sizeof(ocb3_state));
63 if (ocb == NULL || buf == NULL) {
64 if (ocb != NULL) {
65 XFREE(ocb);
66 }
67 if (buf != NULL) {
68 XFREE(buf);
69 }
70 return CRYPT_MEM;
71 }
72
73 if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76
77 if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80
81 if ((err = ocb3_decrypt_last(ocb, ct, ctlen, pt)) != CRYPT_OK) {
82 goto LBL_ERR;
83 }
84
85 buflen = taglen;
86 if ((err = ocb3_done(ocb, buf, &buflen)) != CRYPT_OK) {
87 goto LBL_ERR;
88 }
89
90 /* compare tags */
91 if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) {
92 *stat = 1;
93 }
94
95 err = CRYPT_OK;
96
97 LBL_ERR:
98 #ifdef LTC_CLEAN_STACK
99 zeromem(ocb, sizeof(ocb3_state));
100 #endif
101
102 XFREE(ocb);
103 XFREE(buf);
104 return err;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_done.c
13 OCB implementation, INTERNAL ONLY helper, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Finish OCB processing and compute the tag
21 @param ocb The OCB state
22 @param tag [out] The destination for the authentication tag
23 @param taglen [in/out] The max size and resulting size of the authentication tag
24 @return CRYPT_OK if successful
25 */
26 int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen)
27 {
28 unsigned char tmp[MAXBLOCKSIZE];
29 int err, x;
30
31 LTC_ARGCHK(ocb != NULL);
32 LTC_ARGCHK(tag != NULL);
33 LTC_ARGCHK(taglen != NULL);
34 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
35 goto LBL_ERR;
36 }
37
38 /* finalize AAD processing */
39
40 if (ocb->adata_buffer_bytes>0) {
41 /* Offset_* = Offset_m xor L_* */
42 ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_star, ocb->block_len);
43
44 /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
45 ocb3_int_xor_blocks(tmp, ocb->adata_buffer, ocb->aOffset_current, ocb->adata_buffer_bytes);
46 for(x=ocb->adata_buffer_bytes; x<ocb->block_len; x++) {
47 if (x == ocb->adata_buffer_bytes) {
48 tmp[x] = 0x80 ^ ocb->aOffset_current[x];
49 }
50 else {
51 tmp[x] = 0x00 ^ ocb->aOffset_current[x];
52 }
53 }
54
55 /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
56 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
57 goto LBL_ERR;
58 }
59 ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
60 }
61
62 /* finalize TAG computing */
63
64 /* at this point ocb->aSum_current = HASH(K, A) */
65 /* tag = tag ^ HASH(K, A) */
66 ocb3_int_xor_blocks(tmp, ocb->tag_part, ocb->aSum_current, ocb->block_len);
67
68 /* fix taglen if needed */
69 if ((int)*taglen > ocb->block_len) {
70 *taglen = (unsigned long)ocb->block_len;
71 }
72
73 /* copy tag bytes */
74 for(x=0; x<(int)*taglen; x++) tag[x] = tmp[x];
75
76 err = CRYPT_OK;
77
78 LBL_ERR:
79 #ifdef LTC_CLEAN_STACK
80 zeromem(tmp, MAXBLOCKSIZE);
81 zeromem(ocb, sizeof(*ocb));
82 #endif
83
84 return err;
85 }
86
87 #endif
88
89 /* $Source$ */
90 /* $Revision$ */
91 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_encrypt.c
13 OCB implementation, encrypt data, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Encrypt blocks of data with OCB
21 @param ocb The OCB state
22 @param pt The plaintext (length multiple of the block size of the block cipher)
23 @param ptlen The length of the input (octets)
24 @param ct [out] The ciphertext (same size as the pt)
25 @return CRYPT_OK if successful
26 */
27 int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
28 {
29 unsigned char tmp[MAXBLOCKSIZE];
30 int err, i, full_blocks;
31 unsigned char *pt_b, *ct_b;
32
33 LTC_ARGCHK(ocb != NULL);
34 LTC_ARGCHK(pt != NULL);
35 LTC_ARGCHK(ct != NULL);
36 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
37 return err;
38 }
39 if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 if (ptlen % ocb->block_len) { /* ptlen has to bu multiple of block_len */
44 return CRYPT_INVALID_ARG;
45 }
46
47 full_blocks = ptlen/ocb->block_len;
48 for(i=0; i<full_blocks; i++) {
49 pt_b = (unsigned char *)pt+i*ocb->block_len;
50 ct_b = (unsigned char *)ct+i*ocb->block_len;
51
52 /* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
53 ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);
54
55 /* tmp[] = pt[] XOR ocb->Offset_current[] */
56 ocb3_int_xor_blocks(tmp, pt_b, ocb->Offset_current, ocb->block_len);
57
58 /* encrypt */
59 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
60 goto LBL_ERR;
61 }
62
63 /* ct[] = tmp[] XOR ocb->Offset_current[] */
64 ocb3_int_xor_blocks(ct_b, tmp, ocb->Offset_current, ocb->block_len);
65
66 /* ocb->checksum[] = ocb->checksum[] XOR pt[] */
67 ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);
68
69 ocb->block_index++;
70 }
71
72 err = CRYPT_OK;
73
74 LBL_ERR:
75 #ifdef LTC_CLEAN_STACK
76 zeromem(tmp, sizeof(tmp));
77 #endif
78 return err;
79 }
80
81 #endif
82
83 /* $Source$ */
84 /* $Revision$ */
85 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_encrypt_authenticate_memory.c
13 OCB implementation, encrypt block of memory, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Encrypt and generate an authentication code for a buffer of memory
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param nonce The session nonce (length of the block ciphers block size)
25 @param noncelen The length of the nonce (octets)
26 @param adata The AAD - additional associated data
27 @param adatalen The length of AAD (octets)
28 @param pt The plaintext
29 @param ptlen The length of the plaintext (octets)
30 @param ct [out] The ciphertext
31 @param tag [out] The authentication tag
32 @param taglen [in/out] The max size and resulting size of the authentication tag
33 @return CRYPT_OK if successful
34 */
35 int ocb3_encrypt_authenticate_memory(int cipher,
36 const unsigned char *key, unsigned long keylen,
37 const unsigned char *nonce, unsigned long noncelen,
38 const unsigned char *adata, unsigned long adatalen,
39 const unsigned char *pt, unsigned long ptlen,
40 unsigned char *ct,
41 unsigned char *tag, unsigned long *taglen)
42 {
43 int err;
44 ocb3_state *ocb;
45
46 LTC_ARGCHK(key != NULL);
47 LTC_ARGCHK(nonce != NULL);
48 LTC_ARGCHK(pt != NULL);
49 LTC_ARGCHK(ct != NULL);
50 LTC_ARGCHK(tag != NULL);
51 LTC_ARGCHK(taglen != NULL);
52
53 /* allocate memory */
54 ocb = XMALLOC(sizeof(ocb3_state));
55 if (ocb == NULL) {
56 return CRYPT_MEM;
57 }
58
59 if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen)) != CRYPT_OK) {
60 goto LBL_ERR;
61 }
62
63 if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66
67 if ((err = ocb3_encrypt_last(ocb, pt, ptlen, ct)) != CRYPT_OK) {
68 goto LBL_ERR;
69 }
70
71 err = ocb3_done(ocb, tag, taglen);
72
73 LBL_ERR:
74 #ifdef LTC_CLEAN_STACK
75 zeromem(ocb, sizeof(ocb3_state));
76 #endif
77
78 XFREE(ocb);
79 return err;
80 }
81
82 #endif
83
84 /* $Source$ */
85 /* $Revision$ */
86 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_encrypt_last.c
11 OCB implementation, internal helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Finish an OCB (encryption) stream
19 @param ocb The OCB state
20 @param pt The remaining plaintext
21 @param ptlen The length of the plaintext (octets)
22 @param ct [out] The output buffer
23 @return CRYPT_OK if successful
24 */
25 int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
26 {
27 unsigned char iOffset_star[MAXBLOCKSIZE];
28 unsigned char iPad[MAXBLOCKSIZE];
29 int err, x, full_blocks, full_blocks_len, last_block_len;
30
31 LTC_ARGCHK(ocb != NULL);
32 LTC_ARGCHK(pt != NULL);
33 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
34 goto LBL_ERR;
35 }
36
37 full_blocks = ptlen/ocb->block_len;
38 full_blocks_len = full_blocks * ocb->block_len;
39 last_block_len = ptlen - full_blocks_len;
40
41 /* process full blocks first */
42 if (full_blocks>0) {
43 if ((err = ocb3_encrypt(ocb, pt, full_blocks_len, ct)) != CRYPT_OK) {
44 goto LBL_ERR;
45 }
46 }
47
48 /* at this point: m = ocb->block_index (last block index), Offset_m = ocb->Offset_current */
49
50 if (last_block_len>0) {
51 /* Offset_* = Offset_m xor L_* */
52 ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
53
54 /* Pad = ENCIPHER(K, Offset_*) */
55 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58
59 /* C_* = P_* xor Pad[1..bitlen(P_*)] */
60 ocb3_int_xor_blocks(ct+full_blocks_len, pt+full_blocks_len, iPad, last_block_len);
61
62 /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
63 ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
64 for(x=last_block_len; x<ocb->block_len; x++) {
65 if (x == last_block_len)
66 ocb->checksum[x] ^= 0x80;
67 else
68 ocb->checksum[x] ^= 0x00;
69 }
70
71 /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
72 /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
73 for(x=0; x<ocb->block_len; x++) {
74 ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
75 }
76 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79 }
80 else {
81 /* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
82 /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
83 for(x=0; x<ocb->block_len; x++) {
84 ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
85 }
86 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
87 goto LBL_ERR;
88 }
89 }
90
91 err = CRYPT_OK;
92
93 LBL_ERR:
94 #ifdef LTC_CLEAN_STACK
95 zeromem(iOffset_star, MAXBLOCKSIZE);
96 zeromem(iPad, MAXBLOCKSIZE);
97 #endif
98
99 return err;
100 }
101
102 #endif
103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_init.c
13 OCB implementation, initialize state, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 static const struct {
20 int len;
21 unsigned char poly_div[MAXBLOCKSIZE],
22 poly_mul[MAXBLOCKSIZE];
23 } polys[] = {
24 {
25 8,
26 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
27 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
28 }, {
29 16,
30 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
32 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
34 }
35 };
36
37 /**
38 Initialize an OCB context
39 @param ocb [out] The destination of the OCB state
40 @param cipher The index of the desired cipher
41 @param key The secret key
42 @param keylen The length of the secret key (octets)
43 @param nonce The session nonce
44 @param noncelen The length of the session nonce (octets)
45 @return CRYPT_OK if successful
46 */
47 int ocb3_init(ocb3_state *ocb, int cipher,
48 const unsigned char *key, unsigned long keylen,
49 const unsigned char *nonce, unsigned long noncelen)
50 {
51 int poly, x, y, m, err;
52 unsigned char *previous, *current;
53
54 LTC_ARGCHK(ocb != NULL);
55 LTC_ARGCHK(key != NULL);
56 LTC_ARGCHK(nonce != NULL);
57
58 /* valid cipher? */
59 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
60 return err;
61 }
62 ocb->cipher = cipher;
63
64 /* determine which polys to use */
65 ocb->block_len = cipher_descriptor[cipher].block_length;
66 x = (int)(sizeof(polys)/sizeof(polys[0]));
67 for (poly = 0; poly < x; poly++) {
68 if (polys[poly].len == ocb->block_len) {
69 break;
70 }
71 }
72 if (poly == x) {
73 return CRYPT_INVALID_ARG; /* block_len not found in polys */
74 }
75 if (polys[poly].len != ocb->block_len) {
76 return CRYPT_INVALID_ARG;
77 }
78
79 /* schedule the key */
80 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
81 return err;
82 }
83
84 /* L_* = ENCIPHER(K, zeros(128)) */
85 zeromem(ocb->L_star, ocb->block_len);
86 if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) {
87 return err;
88 }
89
90 /* compute L_$, L_0, L_1, ... */
91 for (x = -1; x < 32; x++) {
92 if (x == -1) { /* gonna compute: L_$ = double(L_*) */
93 current = ocb->L_dollar;
94 previous = ocb->L_star;
95 }
96 else if (x == 0) { /* gonna compute: L_0 = double(L_$) */
97 current = ocb->L_[0];
98 previous = ocb->L_dollar;
99 }
100 else { /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */
101 current = ocb->L_[x];
102 previous = ocb->L_[x-1];
103 }
104 m = previous[0] >> 7;
105 for (y = 0; y < ocb->block_len-1; y++) {
106 current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255;
107 }
108 current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255;
109 if (m == 1) {
110 /* current[] = current[] XOR polys[poly].poly_mul[]*/
111 ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len);
112 }
113 }
114
115 /* initialize ocb->Offset_current = Offset_0 */
116 ocb3_int_calc_offset_zero(ocb, nonce, noncelen);
117
118 /* initialize checksum to all zeros */
119 zeromem(ocb->checksum, ocb->block_len);
120
121 /* set block index */
122 ocb->block_index = 1;
123
124 /* initialize AAD related stuff */
125 ocb->ablock_index = 1;
126 ocb->adata_buffer_bytes = 0;
127 zeromem(ocb->aOffset_current, ocb->block_len);
128 zeromem(ocb->aSum_current, ocb->block_len);
129
130 return CRYPT_OK;
131 }
132
133 #endif
134
135 /* $Source$ */
136 /* $Revision$ */
137 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_int_aad_add_block.c
11 OCB implementation, INTERNALL ONLY helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Add one block of AAD data (internal function)
19 @param ocb The OCB state
20 @param aad_block [in] AAD data (block_len size)
21 @return CRYPT_OK if successful
22 */
23 int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block)
24 {
25 unsigned char tmp[MAXBLOCKSIZE];
26 int err;
27
28 /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
29 ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_[ocb3_int_ntz(ocb->ablock_index)], ocb->block_len);
30
31 /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
32 ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len);
33 if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
34 return err;
35 }
36 ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
37
38 ocb->ablock_index++;
39
40 return CRYPT_OK;
41 }
42
43 #endif
44
45
46 /* $Source$ */
47 /* $Revision$ */
48 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_int_calc_offset_zero.c
11 OCB implementation, INTERNAL ONLY helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Sets 'ocb->Offset_current' to 'Offset_0' value (internal function)
19 @param ocb The OCB state
20 @param nonce The session nonce
21 @param noncelen The length of the session nonce (octets)
22 */
23 void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen)
24 {
25 int x, y, bottom;
26 int idx, shift;
27 unsigned char iNonce[MAXBLOCKSIZE];
28 unsigned char iKtop[MAXBLOCKSIZE];
29 unsigned char iStretch[MAXBLOCKSIZE+8];
30
31 /* Nonce = zeros(127-bitlen(N)) || 1 || N */
32 zeromem(iNonce, sizeof(iNonce));
33 for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) {
34 iNonce[x] = nonce[noncelen-y-1];
35 }
36 iNonce[x] = 0x01;
37
38 /* bottom = str2num(Nonce[123..128]) */
39 bottom = iNonce[ocb->block_len-1] & 0x3F;
40
41 /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */
42 iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0;
43 if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) {
44 zeromem(ocb->Offset_current, ocb->block_len);
45 return;
46 }
47
48 /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
49 for (x = 0; x < ocb->block_len; x++) {
50 iStretch[x] = iKtop[x];
51 }
52 for (y = 0; y < 8; y++) {
53 iStretch[x+y] = iKtop[y] ^ iKtop[y+1];
54 }
55
56 /* Offset_0 = Stretch[1+bottom..128+bottom] */
57 idx = bottom / 8;
58 shift = (bottom % 8);
59 for (x = 0; x < ocb->block_len; x++) {
60 ocb->Offset_current[x] = iStretch[idx+x] << shift;
61 if (shift > 0) {
62 ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift);
63 }
64 }
65 }
66
67 #endif
68
69 /* $Source$ */
70 /* $Revision$ */
71 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file ocb3_int_ntz.c
13 OCB implementation, INTERNAL ONLY helper, by Tom St Denis
14 */
15 #include "tomcrypt.h"
16
17 #ifdef LTC_OCB3_MODE
18
19 /**
20 Returns the number of leading zero bits [from lsb up] (internal function)
21 @param x The 32-bit value to observe
22 @return The number of bits [from the lsb up] that are zero
23 */
24 int ocb3_int_ntz(unsigned long x)
25 {
26 int c;
27 x &= 0xFFFFFFFFUL;
28 c = 0;
29 while ((x & 1) == 0) {
30 ++c;
31 x >>= 1;
32 }
33 return c;
34 }
35
36 #endif
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /**
10 @file ocb3_int_xor_blocks.c
11 OCB implementation, INTERNAL ONLY helper, by Karel Miko
12 */
13 #include "tomcrypt.h"
14
15 #ifdef LTC_OCB3_MODE
16
17 /**
18 Compute xor for two blocks of bytes 'out = block_a XOR block_b' (internal function)
19 @param out The block of bytes (output)
20 @param block_a The block of bytes (input)
21 @param block_b The block of bytes (input)
22 @param block_len The size of block_a, block_b, out
23 */
24 void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len)
25 {
26 int x;
27 if (out == block_a) {
28 for (x = 0; x < (int)block_len; x++) out[x] ^= block_b[x];
29 }
30 else {
31 for (x = 0; x < (int)block_len; x++) out[x] = block_a[x] ^ block_b[x];
32 }
33 }
34
35 #endif
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #include "tomcrypt.h"
12
13 /**
14 @file chc.c
15 CHC support. (Tom St Denis)
16 */
17
18 #ifdef LTC_CHC_HASH
19
20 #define UNDEFED_HASH -17
21
22 /* chc settings */
23 static int cipher_idx=UNDEFED_HASH, /* which cipher */
24 cipher_blocksize; /* blocksize of cipher */
25
26
27 const struct ltc_hash_descriptor chc_desc = {
28 "chc_hash", 12, 0, 0, { 0 }, 0,
29 &chc_init,
30 &chc_process,
31 &chc_done,
32 &chc_test,
33 NULL
34 };
35
36 /**
37 Initialize the CHC state with a given cipher
38 @param cipher The index of the cipher you wish to bind
39 @return CRYPT_OK if successful
40 */
41 int chc_register(int cipher)
42 {
43 int err, kl, idx;
44
45 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
46 return err;
47 }
48
49 /* will it be valid? */
50 kl = cipher_descriptor[cipher].block_length;
51
52 /* must be >64 bit block */
53 if (kl <= 8) {
54 return CRYPT_INVALID_CIPHER;
55 }
56
57 /* can we use the ideal keysize? */
58 if ((err = cipher_descriptor[cipher].keysize(&kl)) != CRYPT_OK) {
59 return err;
60 }
61 /* we require that key size == block size be a valid choice */
62 if (kl != cipher_descriptor[cipher].block_length) {
63 return CRYPT_INVALID_CIPHER;
64 }
65
66 /* determine if chc_hash has been register_hash'ed already */
67 if ((err = hash_is_valid(idx = find_hash("chc_hash"))) != CRYPT_OK) {
68 return err;
69 }
70
71 /* store into descriptor */
72 hash_descriptor[idx].hashsize =
73 hash_descriptor[idx].blocksize = cipher_descriptor[cipher].block_length;
74
75 /* store the idx and block size */
76 cipher_idx = cipher;
77 cipher_blocksize = cipher_descriptor[cipher].block_length;
78 return CRYPT_OK;
79 }
80
81 /**
82 Initialize the hash state
83 @param md The hash state you wish to initialize
84 @return CRYPT_OK if successful
85 */
86 int chc_init(hash_state *md)
87 {
88 symmetric_key *key;
89 unsigned char buf[MAXBLOCKSIZE];
90 int err;
91
92 LTC_ARGCHK(md != NULL);
93
94 /* is the cipher valid? */
95 if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
96 return err;
97 }
98
99 if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
100 return CRYPT_INVALID_CIPHER;
101 }
102
103 if ((key = XMALLOC(sizeof(*key))) == NULL) {
104 return CRYPT_MEM;
105 }
106
107 /* zero key and what not */
108 zeromem(buf, cipher_blocksize);
109 if ((err = cipher_descriptor[cipher_idx].setup(buf, cipher_blocksize, 0, key)) != CRYPT_OK) {
110 XFREE(key);
111 return err;
112 }
113
114 /* encrypt zero block */
115 cipher_descriptor[cipher_idx].ecb_encrypt(buf, md->chc.state, key);
116
117 /* zero other members */
118 md->chc.length = 0;
119 md->chc.curlen = 0;
120 zeromem(md->chc.buf, sizeof(md->chc.buf));
121 XFREE(key);
122 return CRYPT_OK;
123 }
124
125 /*
126 key <= state
127 T0,T1 <= block
128 T0 <= encrypt T0
129 state <= state xor T0 xor T1
130 */
131 static int chc_compress(hash_state *md, unsigned char *buf)
132 {
133 unsigned char T[2][MAXBLOCKSIZE];
134 symmetric_key *key;
135 int err, x;
136
137 if ((key = XMALLOC(sizeof(*key))) == NULL) {
138 return CRYPT_MEM;
139 }
140 if ((err = cipher_descriptor[cipher_idx].setup(md->chc.state, cipher_blocksize, 0, key)) != CRYPT_OK) {
141 XFREE(key);
142 return err;
143 }
144 XMEMCPY(T[1], buf, cipher_blocksize);
145 cipher_descriptor[cipher_idx].ecb_encrypt(buf, T[0], key);
146 for (x = 0; x < cipher_blocksize; x++) {
147 md->chc.state[x] ^= T[0][x] ^ T[1][x];
148 }
149 XFREE(key);
150 #ifdef LTC_CLEAN_STACK
151 zeromem(T, sizeof(T));
152 zeromem(&key, sizeof(key));
153 #endif
154 return CRYPT_OK;
155 }
156
157 /* function for processing blocks */
158 int _chc_process(hash_state * md, const unsigned char *buf, unsigned long len);
159 HASH_PROCESS(_chc_process, chc_compress, chc, (unsigned long)cipher_blocksize)
160
161 /**
162 Process a block of memory though the hash
163 @param md The hash state
164 @param in The data to hash
165 @param inlen The length of the data (octets)
166 @return CRYPT_OK if successful
167 */
168 int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen)
169 {
170 int err;
171
172 LTC_ARGCHK(md != NULL);
173 LTC_ARGCHK(in != NULL);
174
175 /* is the cipher valid? */
176 if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
177 return err;
178 }
179 if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
180 return CRYPT_INVALID_CIPHER;
181 }
182
183 return _chc_process(md, in, inlen);
184 }
185
186 /**
187 Terminate the hash to get the digest
188 @param md The hash state
189 @param out [out] The destination of the hash (length of the block size of the block cipher)
190 @return CRYPT_OK if successful
191 */
192 int chc_done(hash_state *md, unsigned char *out)
193 {
194 int err;
195
196 LTC_ARGCHK(md != NULL);
197 LTC_ARGCHK(out != NULL);
198
199 /* is the cipher valid? */
200 if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
201 return err;
202 }
203 if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
204 return CRYPT_INVALID_CIPHER;
205 }
206
207 if (md->chc.curlen >= sizeof(md->chc.buf)) {
208 return CRYPT_INVALID_ARG;
209 }
210
211 /* increase the length of the message */
212 md->chc.length += md->chc.curlen * 8;
213
214 /* append the '1' bit */
215 md->chc.buf[md->chc.curlen++] = (unsigned char)0x80;
216
217 /* if the length is currently above l-8 bytes we append zeros
218 * then compress. Then we can fall back to padding zeros and length
219 * encoding like normal.
220 */
221 if (md->chc.curlen > (unsigned long)(cipher_blocksize - 8)) {
222 while (md->chc.curlen < (unsigned long)cipher_blocksize) {
223 md->chc.buf[md->chc.curlen++] = (unsigned char)0;
224 }
225 chc_compress(md, md->chc.buf);
226 md->chc.curlen = 0;
227 }
228
229 /* pad upto l-8 bytes of zeroes */
230 while (md->chc.curlen < (unsigned long)(cipher_blocksize - 8)) {
231 md->chc.buf[md->chc.curlen++] = (unsigned char)0;
232 }
233
234 /* store length */
235 STORE64L(md->chc.length, md->chc.buf+(cipher_blocksize-8));
236 chc_compress(md, md->chc.buf);
237
238 /* copy output */
239 XMEMCPY(out, md->chc.state, cipher_blocksize);
240
241 #ifdef LTC_CLEAN_STACK
242 zeromem(md, sizeof(hash_state));
243 #endif
244 return CRYPT_OK;
245 }
246
247 /**
248 Self-test the hash
249 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
250 */
251 int chc_test(void)
252 {
253 static const struct {
254 unsigned char *msg,
255 md[MAXBLOCKSIZE];
256 int len;
257 } tests[] = {
258 {
259 (unsigned char *)"hello world",
260 { 0xcf, 0x57, 0x9d, 0xc3, 0x0a, 0x0e, 0xea, 0x61,
261 0x0d, 0x54, 0x47, 0xc4, 0x3c, 0x06, 0xf5, 0x4e },
262 16
263 }
264 };
265 int x, oldhashidx, idx;
266 unsigned char out[MAXBLOCKSIZE];
267 hash_state md;
268
269 /* AES can be under rijndael or aes... try to find it */
270 if ((idx = find_cipher("aes")) == -1) {
271 if ((idx = find_cipher("rijndael")) == -1) {
272 return CRYPT_NOP;
273 }
274 }
275 oldhashidx = cipher_idx;
276 chc_register(idx);
277
278 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
279 chc_init(&md);
280 chc_process(&md, tests[x].msg, strlen((char *)tests[x].msg));
281 chc_done(&md, out);
282 if (XMEMCMP(out, tests[x].md, tests[x].len)) {
283 return CRYPT_FAIL_TESTVECTOR;
284 }
285 }
286 if (oldhashidx != UNDEFED_HASH) {
287 chc_register(oldhashidx);
288 }
289
290 return CRYPT_OK;
291 }
292
293 #endif
294
295 /* $Source$ */
296 /* $Revision$ */
297 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 #ifndef LTC_NO_FILE
13 /**
14 @file hash_file.c
15 Hash a file, Tom St Denis
16 */
17
18 /**
19 @param hash The index of the hash desired
20 @param fname The name of the file you wish to hash
21 @param out [out] The destination of the digest
22 @param outlen [in/out] The max size and resulting size of the message digest
23 @result CRYPT_OK if successful
24 */
25 int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen)
26 {
27 FILE *in;
28 int err;
29 LTC_ARGCHK(fname != NULL);
30 LTC_ARGCHK(out != NULL);
31 LTC_ARGCHK(outlen != NULL);
32
33 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
34 return err;
35 }
36
37 in = fopen(fname, "rb");
38 if (in == NULL) {
39 return CRYPT_FILE_NOTFOUND;
40 }
41
42 err = hash_filehandle(hash, in, out, outlen);
43 if (fclose(in) != 0) {
44 return CRYPT_ERROR;
45 }
46
47 return err;
48 }
49 #endif /* #ifndef LTC_NO_FILE */
50
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 #ifndef LTC_NO_FILE
13 /**
14 @file hash_filehandle.c
15 Hash open files, Tom St Denis
16 */
17
18 /**
19 Hash data from an open file handle.
20 @param hash The index of the hash you want to use
21 @param in The FILE* handle of the file you want to hash
22 @param out [out] The destination of the digest
23 @param outlen [in/out] The max size and resulting size of the digest
24 @result CRYPT_OK if successful
25 */
26 int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen)
27 {
28 hash_state md;
29 unsigned char buf[512];
30 size_t x;
31 int err;
32
33 LTC_ARGCHK(out != NULL);
34 LTC_ARGCHK(outlen != NULL);
35 LTC_ARGCHK(in != NULL);
36
37 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
38 return err;
39 }
40
41 if (*outlen < hash_descriptor[hash].hashsize) {
42 *outlen = hash_descriptor[hash].hashsize;
43 return CRYPT_BUFFER_OVERFLOW;
44 }
45 if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) {
46 return err;
47 }
48
49 *outlen = hash_descriptor[hash].hashsize;
50 do {
51 x = fread(buf, 1, sizeof(buf), in);
52 if ((err = hash_descriptor[hash].process(&md, buf, x)) != CRYPT_OK) {
53 return err;
54 }
55 } while (x == sizeof(buf));
56 err = hash_descriptor[hash].done(&md, out);
57
58 #ifdef LTC_CLEAN_STACK
59 zeromem(buf, sizeof(buf));
60 #endif
61 return err;
62 }
63 #endif /* #ifndef LTC_NO_FILE */
64
65
66 /* $Source$ */
67 /* $Revision$ */
68 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hash_memory.c
14 Hash memory helper, Tom St Denis
15 */
16
17 /**
18 Hash a block of memory and store the digest.
19 @param hash The index of the hash you wish to use
20 @param in The data you wish to hash
21 @param inlen The length of the data to hash (octets)
22 @param out [out] Where to store the digest
23 @param outlen [in/out] Max size and resulting size of the digest
24 @return CRYPT_OK if successful
25 */
26 int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
27 {
28 hash_state *md;
29 int err;
30
31 LTC_ARGCHK(in != NULL);
32 LTC_ARGCHK(out != NULL);
33 LTC_ARGCHK(outlen != NULL);
34
35 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
36 return err;
37 }
38
39 if (*outlen < hash_descriptor[hash].hashsize) {
40 *outlen = hash_descriptor[hash].hashsize;
41 return CRYPT_BUFFER_OVERFLOW;
42 }
43
44 md = XMALLOC(sizeof(hash_state));
45 if (md == NULL) {
46 return CRYPT_MEM;
47 }
48
49 if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
50 goto LBL_ERR;
51 }
52 if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) {
53 goto LBL_ERR;
54 }
55 err = hash_descriptor[hash].done(md, out);
56 *outlen = hash_descriptor[hash].hashsize;
57 LBL_ERR:
58 #ifdef LTC_CLEAN_STACK
59 zeromem(md, sizeof(hash_state));
60 #endif
61 XFREE(md);
62
63 return err;
64 }
65
66 /* $Source$ */
67 /* $Revision$ */
68 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12 /**
13 @file hash_memory_multi.c
14 Hash (multiple buffers) memory helper, Tom St Denis
15 */
16
17 /**
18 Hash multiple (non-adjacent) blocks of memory at once.
19 @param hash The index of the hash you wish to use
20 @param out [out] Where to store the digest
21 @param outlen [in/out] Max size and resulting size of the digest
22 @param in The data you wish to hash
23 @param inlen The length of the data to hash (octets)
24 @param ... tuples of (data,len) pairs to hash, terminated with a (NULL,x) (x=don't care)
25 @return CRYPT_OK if successful
26 */
27 int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
28 const unsigned char *in, unsigned long inlen, ...)
29 {
30 hash_state *md;
31 int err;
32 va_list args;
33 const unsigned char *curptr;
34 unsigned long curlen;
35
36 LTC_ARGCHK(in != NULL);
37 LTC_ARGCHK(out != NULL);
38 LTC_ARGCHK(outlen != NULL);
39
40 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
41 return err;
42 }
43
44 if (*outlen < hash_descriptor[hash].hashsize) {
45 *outlen = hash_descriptor[hash].hashsize;
46 return CRYPT_BUFFER_OVERFLOW;
47 }
48
49 md = XMALLOC(sizeof(hash_state));
50 if (md == NULL) {
51 return CRYPT_MEM;
52 }
53
54 if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57
58 va_start(args, inlen);
59 curptr = in;
60 curlen = inlen;
61 for (;;) {
62 /* process buf */
63 if ((err = hash_descriptor[hash].process(md, curptr, curlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 /* step to next */
67 curptr = va_arg(args, const unsigned char*);
68 if (curptr == NULL) {
69 break;
70 }
71 curlen = va_arg(args, unsigned long);
72 }
73 err = hash_descriptor[hash].done(md, out);
74 *outlen = hash_descriptor[hash].hashsize;
75 LBL_ERR:
76 #ifdef LTC_CLEAN_STACK
77 zeromem(md, sizeof(hash_state));
78 #endif
79 XFREE(md);
80 va_end(args);
81 return err;
82 }
83
84 /* $Source$ */
85 /* $Revision$ */
86 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param md2.c
14 LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis
15 */
16
17 #ifdef LTC_MD2
18
19 const struct ltc_hash_descriptor md2_desc =
20 {
21 "md2",
22 7,
23 16,
24 16,
25
26 /* OID */
27 { 1, 2, 840, 113549, 2, 2, },
28 6,
29
30 &md2_init,
31 &md2_process,
32 &md2_done,
33 &md2_test,
34 NULL
35 };
36
37 static const unsigned char PI_SUBST[256] = {
38 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
39 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
40 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
41 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
42 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
43 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
44 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
45 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
46 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
47 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
48 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
49 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
50 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
51 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
52 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
53 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
54 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
55 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
56 };
57
58 /* adds 16 bytes to the checksum */
59 static void md2_update_chksum(hash_state *md)
60 {
61 int j;
62 unsigned char L;
63 L = md->md2.chksum[15];
64 for (j = 0; j < 16; j++) {
65
66 /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say
67 otherwise.
68 */
69 L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255);
70 }
71 }
72
73 static void md2_compress(hash_state *md)
74 {
75 int j, k;
76 unsigned char t;
77
78 /* copy block */
79 for (j = 0; j < 16; j++) {
80 md->md2.X[16+j] = md->md2.buf[j];
81 md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j];
82 }
83
84 t = (unsigned char)0;
85
86 /* do 18 rounds */
87 for (j = 0; j < 18; j++) {
88 for (k = 0; k < 48; k++) {
89 t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]);
90 }
91 t = (t + (unsigned char)j) & 255;
92 }
93 }
94
95 /**
96 Initialize the hash state
97 @param md The hash state you wish to initialize
98 @return CRYPT_OK if successful
99 */
100 int md2_init(hash_state *md)
101 {
102 LTC_ARGCHK(md != NULL);
103
104 /* LTC_MD2 uses a zero'ed state... */
105 zeromem(md->md2.X, sizeof(md->md2.X));
106 zeromem(md->md2.chksum, sizeof(md->md2.chksum));
107 zeromem(md->md2.buf, sizeof(md->md2.buf));
108 md->md2.curlen = 0;
109 return CRYPT_OK;
110 }
111
112 /**
113 Process a block of memory though the hash
114 @param md The hash state
115 @param in The data to hash
116 @param inlen The length of the data (octets)
117 @return CRYPT_OK if successful
118 */
119 int md2_process(hash_state *md, const unsigned char *in, unsigned long inlen)
120 {
121 unsigned long n;
122 LTC_ARGCHK(md != NULL);
123 LTC_ARGCHK(in != NULL);
124 if (md-> md2 .curlen > sizeof(md-> md2 .buf)) {
125 return CRYPT_INVALID_ARG;
126 }
127 while (inlen > 0) {
128 n = MIN(inlen, (16 - md->md2.curlen));
129 XMEMCPY(md->md2.buf + md->md2.curlen, in, (size_t)n);
130 md->md2.curlen += n;
131 in += n;
132 inlen -= n;
133
134 /* is 16 bytes full? */
135 if (md->md2.curlen == 16) {
136 md2_compress(md);
137 md2_update_chksum(md);
138 md->md2.curlen = 0;
139 }
140 }
141 return CRYPT_OK;
142 }
143
144 /**
145 Terminate the hash to get the digest
146 @param md The hash state
147 @param out [out] The destination of the hash (16 bytes)
148 @return CRYPT_OK if successful
149 */
150 int md2_done(hash_state * md, unsigned char *out)
151 {
152 unsigned long i, k;
153
154 LTC_ARGCHK(md != NULL);
155 LTC_ARGCHK(out != NULL);
156
157 if (md->md2.curlen >= sizeof(md->md2.buf)) {
158 return CRYPT_INVALID_ARG;
159 }
160
161
162 /* pad the message */
163 k = 16 - md->md2.curlen;
164 for (i = md->md2.curlen; i < 16; i++) {
165 md->md2.buf[i] = (unsigned char)k;
166 }
167
168 /* hash and update */
169 md2_compress(md);
170 md2_update_chksum(md);
171
172 /* hash checksum */
173 XMEMCPY(md->md2.buf, md->md2.chksum, 16);
174 md2_compress(md);
175
176 /* output is lower 16 bytes of X */
177 XMEMCPY(out, md->md2.X, 16);
178
179 #ifdef LTC_CLEAN_STACK
180 zeromem(md, sizeof(hash_state));
181 #endif
182 return CRYPT_OK;
183 }
184
185 /**
186 Self-test the hash
187 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
188 */
189 int md2_test(void)
190 {
191 #ifndef LTC_TEST
192 return CRYPT_NOP;
193 #else
194 static const struct {
195 char *msg;
196 unsigned char md[16];
197 } tests[] = {
198 { "",
199 {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
200 0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73
201 }
202 },
203 { "a",
204 {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
205 0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1
206 }
207 },
208 { "message digest",
209 {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
210 0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0
211 }
212 },
213 { "abcdefghijklmnopqrstuvwxyz",
214 {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
215 0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b
216 }
217 },
218 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
219 {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
220 0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd
221 }
222 },
223 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
224 {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
225 0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8
226 }
227 }
228 };
229 int i;
230 hash_state md;
231 unsigned char buf[16];
232
233 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
234 md2_init(&md);
235 md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
236 md2_done(&md, buf);
237 if (XMEMCMP(buf, tests[i].md, 16) != 0) {
238 return CRYPT_FAIL_TESTVECTOR;
239 }
240 }
241 return CRYPT_OK;
242 #endif
243 }
244
245 #endif
246
247
248 /* $Source$ */
249 /* $Revision$ */
250 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param md4.c
14 Submitted by Dobes Vandermeer (dobes@smartt.com)
15 */
16
17 #ifdef LTC_MD4
18
19 const struct ltc_hash_descriptor md4_desc =
20 {
21 "md4",
22 6,
23 16,
24 64,
25
26 /* OID */
27 { 1, 2, 840, 113549, 2, 4, },
28 6,
29
30 &md4_init,
31 &md4_process,
32 &md4_done,
33 &md4_test,
34 NULL
35 };
36
37 #define S11 3
38 #define S12 7
39 #define S13 11
40 #define S14 19
41 #define S21 3
42 #define S22 5
43 #define S23 9
44 #define S24 13
45 #define S31 3
46 #define S32 9
47 #define S33 11
48 #define S34 15
49
50 /* F, G and H are basic LTC_MD4 functions. */
51 #define F(x, y, z) (z ^ (x & (y ^ z)))
52 #define G(x, y, z) ((x & y) | (z & (x | y)))
53 #define H(x, y, z) ((x) ^ (y) ^ (z))
54
55 /* ROTATE_LEFT rotates x left n bits. */
56 #define ROTATE_LEFT(x, n) ROLc(x, n)
57
58 /* FF, GG and HH are transformations for rounds 1, 2 and 3 */
59 /* Rotation is separate from addition to prevent recomputation */
60
61 #define FF(a, b, c, d, x, s) { \
62 (a) += F ((b), (c), (d)) + (x); \
63 (a) = ROTATE_LEFT ((a), (s)); \
64 }
65 #define GG(a, b, c, d, x, s) { \
66 (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \
67 (a) = ROTATE_LEFT ((a), (s)); \
68 }
69 #define HH(a, b, c, d, x, s) { \
70 (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
71 (a) = ROTATE_LEFT ((a), (s)); \
72 }
73
74 #ifdef LTC_CLEAN_STACK
75 static int _md4_compress(hash_state *md, unsigned char *buf)
76 #else
77 static int md4_compress(hash_state *md, unsigned char *buf)
78 #endif
79 {
80 ulong32 x[16], a, b, c, d;
81 int i;
82
83 /* copy state */
84 a = md->md4.state[0];
85 b = md->md4.state[1];
86 c = md->md4.state[2];
87 d = md->md4.state[3];
88
89 /* copy the state into 512-bits into W[0..15] */
90 for (i = 0; i < 16; i++) {
91 LOAD32L(x[i], buf + (4*i));
92 }
93
94 /* Round 1 */
95 FF (a, b, c, d, x[ 0], S11); /* 1 */
96 FF (d, a, b, c, x[ 1], S12); /* 2 */
97 FF (c, d, a, b, x[ 2], S13); /* 3 */
98 FF (b, c, d, a, x[ 3], S14); /* 4 */
99 FF (a, b, c, d, x[ 4], S11); /* 5 */
100 FF (d, a, b, c, x[ 5], S12); /* 6 */
101 FF (c, d, a, b, x[ 6], S13); /* 7 */
102 FF (b, c, d, a, x[ 7], S14); /* 8 */
103 FF (a, b, c, d, x[ 8], S11); /* 9 */
104 FF (d, a, b, c, x[ 9], S12); /* 10 */
105 FF (c, d, a, b, x[10], S13); /* 11 */
106 FF (b, c, d, a, x[11], S14); /* 12 */
107 FF (a, b, c, d, x[12], S11); /* 13 */
108 FF (d, a, b, c, x[13], S12); /* 14 */
109 FF (c, d, a, b, x[14], S13); /* 15 */
110 FF (b, c, d, a, x[15], S14); /* 16 */
111
112 /* Round 2 */
113 GG (a, b, c, d, x[ 0], S21); /* 17 */
114 GG (d, a, b, c, x[ 4], S22); /* 18 */
115 GG (c, d, a, b, x[ 8], S23); /* 19 */
116 GG (b, c, d, a, x[12], S24); /* 20 */
117 GG (a, b, c, d, x[ 1], S21); /* 21 */
118 GG (d, a, b, c, x[ 5], S22); /* 22 */
119 GG (c, d, a, b, x[ 9], S23); /* 23 */
120 GG (b, c, d, a, x[13], S24); /* 24 */
121 GG (a, b, c, d, x[ 2], S21); /* 25 */
122 GG (d, a, b, c, x[ 6], S22); /* 26 */
123 GG (c, d, a, b, x[10], S23); /* 27 */
124 GG (b, c, d, a, x[14], S24); /* 28 */
125 GG (a, b, c, d, x[ 3], S21); /* 29 */
126 GG (d, a, b, c, x[ 7], S22); /* 30 */
127 GG (c, d, a, b, x[11], S23); /* 31 */
128 GG (b, c, d, a, x[15], S24); /* 32 */
129
130 /* Round 3 */
131 HH (a, b, c, d, x[ 0], S31); /* 33 */
132 HH (d, a, b, c, x[ 8], S32); /* 34 */
133 HH (c, d, a, b, x[ 4], S33); /* 35 */
134 HH (b, c, d, a, x[12], S34); /* 36 */
135 HH (a, b, c, d, x[ 2], S31); /* 37 */
136 HH (d, a, b, c, x[10], S32); /* 38 */
137 HH (c, d, a, b, x[ 6], S33); /* 39 */
138 HH (b, c, d, a, x[14], S34); /* 40 */
139 HH (a, b, c, d, x[ 1], S31); /* 41 */
140 HH (d, a, b, c, x[ 9], S32); /* 42 */
141 HH (c, d, a, b, x[ 5], S33); /* 43 */
142 HH (b, c, d, a, x[13], S34); /* 44 */
143 HH (a, b, c, d, x[ 3], S31); /* 45 */
144 HH (d, a, b, c, x[11], S32); /* 46 */
145 HH (c, d, a, b, x[ 7], S33); /* 47 */
146 HH (b, c, d, a, x[15], S34); /* 48 */
147
148
149 /* Update our state */
150 md->md4.state[0] = md->md4.state[0] + a;
151 md->md4.state[1] = md->md4.state[1] + b;
152 md->md4.state[2] = md->md4.state[2] + c;
153 md->md4.state[3] = md->md4.state[3] + d;
154
155 return CRYPT_OK;
156 }
157
158 #ifdef LTC_CLEAN_STACK
159 static int md4_compress(hash_state *md, unsigned char *buf)
160 {
161 int err;
162 err = _md4_compress(md, buf);
163 burn_stack(sizeof(ulong32) * 20 + sizeof(int));
164 return err;
165 }
166 #endif
167
168 /**
169 Initialize the hash state
170 @param md The hash state you wish to initialize
171 @return CRYPT_OK if successful
172 */
173 int md4_init(hash_state * md)
174 {
175 LTC_ARGCHK(md != NULL);
176 md->md4.state[0] = 0x67452301UL;
177 md->md4.state[1] = 0xefcdab89UL;
178 md->md4.state[2] = 0x98badcfeUL;
179 md->md4.state[3] = 0x10325476UL;
180 md->md4.length = 0;
181 md->md4.curlen = 0;
182 return CRYPT_OK;
183 }
184
185 /**
186 Process a block of memory though the hash
187 @param md The hash state
188 @param in The data to hash
189 @param inlen The length of the data (octets)
190 @return CRYPT_OK if successful
191 */
192 HASH_PROCESS(md4_process, md4_compress, md4, 64)
193
194 /**
195 Terminate the hash to get the digest
196 @param md The hash state
197 @param out [out] The destination of the hash (16 bytes)
198 @return CRYPT_OK if successful
199 */
200 int md4_done(hash_state * md, unsigned char *out)
201 {
202 int i;
203
204 LTC_ARGCHK(md != NULL);
205 LTC_ARGCHK(out != NULL);
206
207 if (md->md4.curlen >= sizeof(md->md4.buf)) {
208 return CRYPT_INVALID_ARG;
209 }
210
211 /* increase the length of the message */
212 md->md4.length += md->md4.curlen * 8;
213
214 /* append the '1' bit */
215 md->md4.buf[md->md4.curlen++] = (unsigned char)0x80;
216
217 /* if the length is currently above 56 bytes we append zeros
218 * then compress. Then we can fall back to padding zeros and length
219 * encoding like normal.
220 */
221 if (md->md4.curlen > 56) {
222 while (md->md4.curlen < 64) {
223 md->md4.buf[md->md4.curlen++] = (unsigned char)0;
224 }
225 md4_compress(md, md->md4.buf);
226 md->md4.curlen = 0;
227 }
228
229 /* pad upto 56 bytes of zeroes */
230 while (md->md4.curlen < 56) {
231 md->md4.buf[md->md4.curlen++] = (unsigned char)0;
232 }
233
234 /* store length */
235 STORE64L(md->md4.length, md->md4.buf+56);
236 md4_compress(md, md->md4.buf);
237
238 /* copy output */
239 for (i = 0; i < 4; i++) {
240 STORE32L(md->md4.state[i], out+(4*i));
241 }
242 #ifdef LTC_CLEAN_STACK
243 zeromem(md, sizeof(hash_state));
244 #endif
245 return CRYPT_OK;
246 }
247
248 /**
249 Self-test the hash
250 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
251 */
252 int md4_test(void)
253 {
254 #ifndef LTC_TEST
255 return CRYPT_NOP;
256 #else
257 static const struct md4_test_case {
258 char *input;
259 unsigned char digest[16];
260 } cases[] = {
261 { "",
262 {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
263 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} },
264 { "a",
265 {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
266 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} },
267 { "abc",
268 {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
269 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} },
270 { "message digest",
271 {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
272 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} },
273 { "abcdefghijklmnopqrstuvwxyz",
274 {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
275 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} },
276 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
277 {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
278 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} },
279 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
280 {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
281 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} },
282 };
283 int i;
284 hash_state md;
285 unsigned char digest[16];
286
287 for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
288 md4_init(&md);
289 md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input));
290 md4_done(&md, digest);
291 if (XMEMCMP(digest, cases[i].digest, 16) != 0) {
292 return CRYPT_FAIL_TESTVECTOR;
293 }
294
295 }
296 return CRYPT_OK;
297 #endif
298 }
299
300 #endif
301
302
303
304 /* $Source$ */
305 /* $Revision$ */
306 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12
13 /**
14 @file md5.c
15 LTC_MD5 hash function by Tom St Denis
16 */
17
18 #ifdef LTC_MD5
19
20 const struct ltc_hash_descriptor md5_desc =
21 {
22 "md5",
23 3,
24 16,
25 64,
26
27 /* OID */
28 { 1, 2, 840, 113549, 2, 5, },
29 6,
30
31 &md5_init,
32 &md5_process,
33 &md5_done,
34 &md5_test,
35 NULL
36 };
37
38 #define F(x,y,z) (z ^ (x & (y ^ z)))
39 #define G(x,y,z) (y ^ (z & (y ^ x)))
40 #define H(x,y,z) (x^y^z)
41 #define I(x,y,z) (y^(x|(~z)))
42
43 #ifdef LTC_SMALL_CODE
44
45 #define FF(a,b,c,d,M,s,t) \
46 a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
47
48 #define GG(a,b,c,d,M,s,t) \
49 a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
50
51 #define HH(a,b,c,d,M,s,t) \
52 a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
53
54 #define II(a,b,c,d,M,s,t) \
55 a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
56
57 static const unsigned char Worder[64] = {
58 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
59 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
60 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
61 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
62 };
63
64 static const unsigned char Rorder[64] = {
65 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
66 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
67 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
68 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
69 };
70
71 static const ulong32 Korder[64] = {
72 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
73 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
74 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
75 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
76 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
77 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
78 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
79 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
80 };
81
82 #else
83
84 #define FF(a,b,c,d,M,s,t) \
85 a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
86
87 #define GG(a,b,c,d,M,s,t) \
88 a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
89
90 #define HH(a,b,c,d,M,s,t) \
91 a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
92
93 #define II(a,b,c,d,M,s,t) \
94 a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
95
96
97 #endif
98
99 #ifdef LTC_CLEAN_STACK
100 static int _md5_compress(hash_state *md, unsigned char *buf)
101 #else
102 static int md5_compress(hash_state *md, unsigned char *buf)
103 #endif
104 {
105 ulong32 i, W[16], a, b, c, d;
106 #ifdef LTC_SMALL_CODE
107 ulong32 t;
108 #endif
109
110 /* copy the state into 512-bits into W[0..15] */
111 for (i = 0; i < 16; i++) {
112 LOAD32L(W[i], buf + (4*i));
113 }
114
115 /* copy state */
116 a = md->md5.state[0];
117 b = md->md5.state[1];
118 c = md->md5.state[2];
119 d = md->md5.state[3];
120
121 #ifdef LTC_SMALL_CODE
122 for (i = 0; i < 16; ++i) {
123 FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
124 t = d; d = c; c = b; b = a; a = t;
125 }
126
127 for (; i < 32; ++i) {
128 GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
129 t = d; d = c; c = b; b = a; a = t;
130 }
131
132 for (; i < 48; ++i) {
133 HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
134 t = d; d = c; c = b; b = a; a = t;
135 }
136
137 for (; i < 64; ++i) {
138 II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
139 t = d; d = c; c = b; b = a; a = t;
140 }
141
142 #else
143 FF(a,b,c,d,W[0],7,0xd76aa478UL)
144 FF(d,a,b,c,W[1],12,0xe8c7b756UL)
145 FF(c,d,a,b,W[2],17,0x242070dbUL)
146 FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
147 FF(a,b,c,d,W[4],7,0xf57c0fafUL)
148 FF(d,a,b,c,W[5],12,0x4787c62aUL)
149 FF(c,d,a,b,W[6],17,0xa8304613UL)
150 FF(b,c,d,a,W[7],22,0xfd469501UL)
151 FF(a,b,c,d,W[8],7,0x698098d8UL)
152 FF(d,a,b,c,W[9],12,0x8b44f7afUL)
153 FF(c,d,a,b,W[10],17,0xffff5bb1UL)
154 FF(b,c,d,a,W[11],22,0x895cd7beUL)
155 FF(a,b,c,d,W[12],7,0x6b901122UL)
156 FF(d,a,b,c,W[13],12,0xfd987193UL)
157 FF(c,d,a,b,W[14],17,0xa679438eUL)
158 FF(b,c,d,a,W[15],22,0x49b40821UL)
159 GG(a,b,c,d,W[1],5,0xf61e2562UL)
160 GG(d,a,b,c,W[6],9,0xc040b340UL)
161 GG(c,d,a,b,W[11],14,0x265e5a51UL)
162 GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
163 GG(a,b,c,d,W[5],5,0xd62f105dUL)
164 GG(d,a,b,c,W[10],9,0x02441453UL)
165 GG(c,d,a,b,W[15],14,0xd8a1e681UL)
166 GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
167 GG(a,b,c,d,W[9],5,0x21e1cde6UL)
168 GG(d,a,b,c,W[14],9,0xc33707d6UL)
169 GG(c,d,a,b,W[3],14,0xf4d50d87UL)
170 GG(b,c,d,a,W[8],20,0x455a14edUL)
171 GG(a,b,c,d,W[13],5,0xa9e3e905UL)
172 GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
173 GG(c,d,a,b,W[7],14,0x676f02d9UL)
174 GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
175 HH(a,b,c,d,W[5],4,0xfffa3942UL)
176 HH(d,a,b,c,W[8],11,0x8771f681UL)
177 HH(c,d,a,b,W[11],16,0x6d9d6122UL)
178 HH(b,c,d,a,W[14],23,0xfde5380cUL)
179 HH(a,b,c,d,W[1],4,0xa4beea44UL)
180 HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
181 HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
182 HH(b,c,d,a,W[10],23,0xbebfbc70UL)
183 HH(a,b,c,d,W[13],4,0x289b7ec6UL)
184 HH(d,a,b,c,W[0],11,0xeaa127faUL)
185 HH(c,d,a,b,W[3],16,0xd4ef3085UL)
186 HH(b,c,d,a,W[6],23,0x04881d05UL)
187 HH(a,b,c,d,W[9],4,0xd9d4d039UL)
188 HH(d,a,b,c,W[12],11,0xe6db99e5UL)
189 HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
190 HH(b,c,d,a,W[2],23,0xc4ac5665UL)
191 II(a,b,c,d,W[0],6,0xf4292244UL)
192 II(d,a,b,c,W[7],10,0x432aff97UL)
193 II(c,d,a,b,W[14],15,0xab9423a7UL)
194 II(b,c,d,a,W[5],21,0xfc93a039UL)
195 II(a,b,c,d,W[12],6,0x655b59c3UL)
196 II(d,a,b,c,W[3],10,0x8f0ccc92UL)
197 II(c,d,a,b,W[10],15,0xffeff47dUL)
198 II(b,c,d,a,W[1],21,0x85845dd1UL)
199 II(a,b,c,d,W[8],6,0x6fa87e4fUL)
200 II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
201 II(c,d,a,b,W[6],15,0xa3014314UL)
202 II(b,c,d,a,W[13],21,0x4e0811a1UL)
203 II(a,b,c,d,W[4],6,0xf7537e82UL)
204 II(d,a,b,c,W[11],10,0xbd3af235UL)
205 II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
206 II(b,c,d,a,W[9],21,0xeb86d391UL)
207 #endif
208
209 md->md5.state[0] = md->md5.state[0] + a;
210 md->md5.state[1] = md->md5.state[1] + b;
211 md->md5.state[2] = md->md5.state[2] + c;
212 md->md5.state[3] = md->md5.state[3] + d;
213
214 return CRYPT_OK;
215 }
216
217 #ifdef LTC_CLEAN_STACK
218 static int md5_compress(hash_state *md, unsigned char *buf)
219 {
220 int err;
221 err = _md5_compress(md, buf);
222 burn_stack(sizeof(ulong32) * 21);
223 return err;
224 }
225 #endif
226
227 /**
228 Initialize the hash state
229 @param md The hash state you wish to initialize
230 @return CRYPT_OK if successful
231 */
232 int md5_init(hash_state * md)
233 {
234 LTC_ARGCHK(md != NULL);
235 md->md5.state[0] = 0x67452301UL;
236 md->md5.state[1] = 0xefcdab89UL;
237 md->md5.state[2] = 0x98badcfeUL;
238 md->md5.state[3] = 0x10325476UL;
239 md->md5.curlen = 0;
240 md->md5.length = 0;
241 return CRYPT_OK;
242 }
243
244 /**
245 Process a block of memory though the hash
246 @param md The hash state
247 @param in The data to hash
248 @param inlen The length of the data (octets)
249 @return CRYPT_OK if successful
250 */
251 HASH_PROCESS(md5_process, md5_compress, md5, 64)
252
253 /**
254 Terminate the hash to get the digest
255 @param md The hash state
256 @param out [out] The destination of the hash (16 bytes)
257 @return CRYPT_OK if successful
258 */
259 int md5_done(hash_state * md, unsigned char *out)
260 {
261 int i;
262
263 LTC_ARGCHK(md != NULL);
264 LTC_ARGCHK(out != NULL);
265
266 if (md->md5.curlen >= sizeof(md->md5.buf)) {
267 return CRYPT_INVALID_ARG;
268 }
269
270
271 /* increase the length of the message */
272 md->md5.length += md->md5.curlen * 8;
273
274 /* append the '1' bit */
275 md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
276
277 /* if the length is currently above 56 bytes we append zeros
278 * then compress. Then we can fall back to padding zeros and length
279 * encoding like normal.
280 */
281 if (md->md5.curlen > 56) {
282 while (md->md5.curlen < 64) {
283 md->md5.buf[md->md5.curlen++] = (unsigned char)0;
284 }
285 md5_compress(md, md->md5.buf);
286 md->md5.curlen = 0;
287 }
288
289 /* pad upto 56 bytes of zeroes */
290 while (md->md5.curlen < 56) {
291 md->md5.buf[md->md5.curlen++] = (unsigned char)0;
292 }
293
294 /* store length */
295 STORE64L(md->md5.length, md->md5.buf+56);
296 md5_compress(md, md->md5.buf);
297
298 /* copy output */
299 for (i = 0; i < 4; i++) {
300 STORE32L(md->md5.state[i], out+(4*i));
301 }
302 #ifdef LTC_CLEAN_STACK
303 zeromem(md, sizeof(hash_state));
304 #endif
305 return CRYPT_OK;
306 }
307
308 /**
309 Self-test the hash
310 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
311 */
312 int md5_test(void)
313 {
314 #ifndef LTC_TEST
315 return CRYPT_NOP;
316 #else
317 static const struct {
318 char *msg;
319 unsigned char hash[16];
320 } tests[] = {
321 { "",
322 { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
323 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
324 { "a",
325 {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
326 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
327 { "abc",
328 { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
329 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
330 { "message digest",
331 { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
332 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
333 { "abcdefghijklmnopqrstuvwxyz",
334 { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
335 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
336 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
337 { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
338 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
339 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
340 { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
341 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
342 { NULL, { 0 } }
343 };
344
345 int i;
346 unsigned char tmp[16];
347 hash_state md;
348
349 for (i = 0; tests[i].msg != NULL; i++) {
350 md5_init(&md);
351 md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
352 md5_done(&md, tmp);
353 if (XMEMCMP(tmp, tests[i].hash, 16) != 0) {
354 return CRYPT_FAIL_TESTVECTOR;
355 }
356 }
357 return CRYPT_OK;
358 #endif
359 }
360
361 #endif
362
363
364
365 /* $Source$ */
366 /* $Revision$ */
367 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param rmd128.c
14 RMD128 Hash function
15 */
16
17 /* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
18 *
19 * This source has been radically overhauled to be portable and work within
20 * the LibTomCrypt API by Tom St Denis
21 */
22
23 #ifdef LTC_RIPEMD128
24
25 const struct ltc_hash_descriptor rmd128_desc =
26 {
27 "rmd128",
28 8,
29 16,
30 64,
31
32 /* OID */
33 { 1, 0, 10118, 3, 0, 50 },
34 6,
35
36 &rmd128_init,
37 &rmd128_process,
38 &rmd128_done,
39 &rmd128_test,
40 NULL
41 };
42
43 /* the four basic functions F(), G() and H() */
44 #define F(x, y, z) ((x) ^ (y) ^ (z))
45 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
46 #define H(x, y, z) (((x) | ~(y)) ^ (z))
47 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
48
49 /* the eight basic operations FF() through III() */
50 #define FF(a, b, c, d, x, s) \
51 (a) += F((b), (c), (d)) + (x);\
52 (a) = ROLc((a), (s));
53
54 #define GG(a, b, c, d, x, s) \
55 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
56 (a) = ROLc((a), (s));
57
58 #define HH(a, b, c, d, x, s) \
59 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
60 (a) = ROLc((a), (s));
61
62 #define II(a, b, c, d, x, s) \
63 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
64 (a) = ROLc((a), (s));
65
66 #define FFF(a, b, c, d, x, s) \
67 (a) += F((b), (c), (d)) + (x);\
68 (a) = ROLc((a), (s));
69
70 #define GGG(a, b, c, d, x, s) \
71 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
72 (a) = ROLc((a), (s));
73
74 #define HHH(a, b, c, d, x, s) \
75 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
76 (a) = ROLc((a), (s));
77
78 #define III(a, b, c, d, x, s) \
79 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
80 (a) = ROLc((a), (s));
81
82 #ifdef LTC_CLEAN_STACK
83 static int _rmd128_compress(hash_state *md, unsigned char *buf)
84 #else
85 static int rmd128_compress(hash_state *md, unsigned char *buf)
86 #endif
87 {
88 ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16];
89 int i;
90
91 /* load words X */
92 for (i = 0; i < 16; i++){
93 LOAD32L(X[i], buf + (4 * i));
94 }
95
96 /* load state */
97 aa = aaa = md->rmd128.state[0];
98 bb = bbb = md->rmd128.state[1];
99 cc = ccc = md->rmd128.state[2];
100 dd = ddd = md->rmd128.state[3];
101
102 /* round 1 */
103 FF(aa, bb, cc, dd, X[ 0], 11);
104 FF(dd, aa, bb, cc, X[ 1], 14);
105 FF(cc, dd, aa, bb, X[ 2], 15);
106 FF(bb, cc, dd, aa, X[ 3], 12);
107 FF(aa, bb, cc, dd, X[ 4], 5);
108 FF(dd, aa, bb, cc, X[ 5], 8);
109 FF(cc, dd, aa, bb, X[ 6], 7);
110 FF(bb, cc, dd, aa, X[ 7], 9);
111 FF(aa, bb, cc, dd, X[ 8], 11);
112 FF(dd, aa, bb, cc, X[ 9], 13);
113 FF(cc, dd, aa, bb, X[10], 14);
114 FF(bb, cc, dd, aa, X[11], 15);
115 FF(aa, bb, cc, dd, X[12], 6);
116 FF(dd, aa, bb, cc, X[13], 7);
117 FF(cc, dd, aa, bb, X[14], 9);
118 FF(bb, cc, dd, aa, X[15], 8);
119
120 /* round 2 */
121 GG(aa, bb, cc, dd, X[ 7], 7);
122 GG(dd, aa, bb, cc, X[ 4], 6);
123 GG(cc, dd, aa, bb, X[13], 8);
124 GG(bb, cc, dd, aa, X[ 1], 13);
125 GG(aa, bb, cc, dd, X[10], 11);
126 GG(dd, aa, bb, cc, X[ 6], 9);
127 GG(cc, dd, aa, bb, X[15], 7);
128 GG(bb, cc, dd, aa, X[ 3], 15);
129 GG(aa, bb, cc, dd, X[12], 7);
130 GG(dd, aa, bb, cc, X[ 0], 12);
131 GG(cc, dd, aa, bb, X[ 9], 15);
132 GG(bb, cc, dd, aa, X[ 5], 9);
133 GG(aa, bb, cc, dd, X[ 2], 11);
134 GG(dd, aa, bb, cc, X[14], 7);
135 GG(cc, dd, aa, bb, X[11], 13);
136 GG(bb, cc, dd, aa, X[ 8], 12);
137
138 /* round 3 */
139 HH(aa, bb, cc, dd, X[ 3], 11);
140 HH(dd, aa, bb, cc, X[10], 13);
141 HH(cc, dd, aa, bb, X[14], 6);
142 HH(bb, cc, dd, aa, X[ 4], 7);
143 HH(aa, bb, cc, dd, X[ 9], 14);
144 HH(dd, aa, bb, cc, X[15], 9);
145 HH(cc, dd, aa, bb, X[ 8], 13);
146 HH(bb, cc, dd, aa, X[ 1], 15);
147 HH(aa, bb, cc, dd, X[ 2], 14);
148 HH(dd, aa, bb, cc, X[ 7], 8);
149 HH(cc, dd, aa, bb, X[ 0], 13);
150 HH(bb, cc, dd, aa, X[ 6], 6);
151 HH(aa, bb, cc, dd, X[13], 5);
152 HH(dd, aa, bb, cc, X[11], 12);
153 HH(cc, dd, aa, bb, X[ 5], 7);
154 HH(bb, cc, dd, aa, X[12], 5);
155
156 /* round 4 */
157 II(aa, bb, cc, dd, X[ 1], 11);
158 II(dd, aa, bb, cc, X[ 9], 12);
159 II(cc, dd, aa, bb, X[11], 14);
160 II(bb, cc, dd, aa, X[10], 15);
161 II(aa, bb, cc, dd, X[ 0], 14);
162 II(dd, aa, bb, cc, X[ 8], 15);
163 II(cc, dd, aa, bb, X[12], 9);
164 II(bb, cc, dd, aa, X[ 4], 8);
165 II(aa, bb, cc, dd, X[13], 9);
166 II(dd, aa, bb, cc, X[ 3], 14);
167 II(cc, dd, aa, bb, X[ 7], 5);
168 II(bb, cc, dd, aa, X[15], 6);
169 II(aa, bb, cc, dd, X[14], 8);
170 II(dd, aa, bb, cc, X[ 5], 6);
171 II(cc, dd, aa, bb, X[ 6], 5);
172 II(bb, cc, dd, aa, X[ 2], 12);
173
174 /* parallel round 1 */
175 III(aaa, bbb, ccc, ddd, X[ 5], 8);
176 III(ddd, aaa, bbb, ccc, X[14], 9);
177 III(ccc, ddd, aaa, bbb, X[ 7], 9);
178 III(bbb, ccc, ddd, aaa, X[ 0], 11);
179 III(aaa, bbb, ccc, ddd, X[ 9], 13);
180 III(ddd, aaa, bbb, ccc, X[ 2], 15);
181 III(ccc, ddd, aaa, bbb, X[11], 15);
182 III(bbb, ccc, ddd, aaa, X[ 4], 5);
183 III(aaa, bbb, ccc, ddd, X[13], 7);
184 III(ddd, aaa, bbb, ccc, X[ 6], 7);
185 III(ccc, ddd, aaa, bbb, X[15], 8);
186 III(bbb, ccc, ddd, aaa, X[ 8], 11);
187 III(aaa, bbb, ccc, ddd, X[ 1], 14);
188 III(ddd, aaa, bbb, ccc, X[10], 14);
189 III(ccc, ddd, aaa, bbb, X[ 3], 12);
190 III(bbb, ccc, ddd, aaa, X[12], 6);
191
192 /* parallel round 2 */
193 HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
194 HHH(ddd, aaa, bbb, ccc, X[11], 13);
195 HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
196 HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
197 HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
198 HHH(ddd, aaa, bbb, ccc, X[13], 8);
199 HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
200 HHH(bbb, ccc, ddd, aaa, X[10], 11);
201 HHH(aaa, bbb, ccc, ddd, X[14], 7);
202 HHH(ddd, aaa, bbb, ccc, X[15], 7);
203 HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
204 HHH(bbb, ccc, ddd, aaa, X[12], 7);
205 HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
206 HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
207 HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
208 HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
209
210 /* parallel round 3 */
211 GGG(aaa, bbb, ccc, ddd, X[15], 9);
212 GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
213 GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
214 GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
215 GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
216 GGG(ddd, aaa, bbb, ccc, X[14], 6);
217 GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
218 GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
219 GGG(aaa, bbb, ccc, ddd, X[11], 12);
220 GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
221 GGG(ccc, ddd, aaa, bbb, X[12], 5);
222 GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
223 GGG(aaa, bbb, ccc, ddd, X[10], 13);
224 GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
225 GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
226 GGG(bbb, ccc, ddd, aaa, X[13], 5);
227
228 /* parallel round 4 */
229 FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
230 FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
231 FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
232 FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
233 FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
234 FFF(ddd, aaa, bbb, ccc, X[11], 14);
235 FFF(ccc, ddd, aaa, bbb, X[15], 6);
236 FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
237 FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
238 FFF(ddd, aaa, bbb, ccc, X[12], 9);
239 FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
240 FFF(bbb, ccc, ddd, aaa, X[13], 9);
241 FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
242 FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
243 FFF(ccc, ddd, aaa, bbb, X[10], 15);
244 FFF(bbb, ccc, ddd, aaa, X[14], 8);
245
246 /* combine results */
247 ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */
248 md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa;
249 md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb;
250 md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc;
251 md->rmd128.state[0] = ddd;
252
253 return CRYPT_OK;
254 }
255
256 #ifdef LTC_CLEAN_STACK
257 static int rmd128_compress(hash_state *md, unsigned char *buf)
258 {
259 int err;
260 err = _rmd128_compress(md, buf);
261 burn_stack(sizeof(ulong32) * 24 + sizeof(int));
262 return err;
263 }
264 #endif
265
266 /**
267 Initialize the hash state
268 @param md The hash state you wish to initialize
269 @return CRYPT_OK if successful
270 */
271 int rmd128_init(hash_state * md)
272 {
273 LTC_ARGCHK(md != NULL);
274 md->rmd128.state[0] = 0x67452301UL;
275 md->rmd128.state[1] = 0xefcdab89UL;
276 md->rmd128.state[2] = 0x98badcfeUL;
277 md->rmd128.state[3] = 0x10325476UL;
278 md->rmd128.curlen = 0;
279 md->rmd128.length = 0;
280 return CRYPT_OK;
281 }
282
283 /**
284 Process a block of memory though the hash
285 @param md The hash state
286 @param in The data to hash
287 @param inlen The length of the data (octets)
288 @return CRYPT_OK if successful
289 */
290 HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64)
291
292 /**
293 Terminate the hash to get the digest
294 @param md The hash state
295 @param out [out] The destination of the hash (16 bytes)
296 @return CRYPT_OK if successful
297 */
298 int rmd128_done(hash_state * md, unsigned char *out)
299 {
300 int i;
301
302 LTC_ARGCHK(md != NULL);
303 LTC_ARGCHK(out != NULL);
304
305 if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) {
306 return CRYPT_INVALID_ARG;
307 }
308
309
310 /* increase the length of the message */
311 md->rmd128.length += md->rmd128.curlen * 8;
312
313 /* append the '1' bit */
314 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80;
315
316 /* if the length is currently above 56 bytes we append zeros
317 * then compress. Then we can fall back to padding zeros and length
318 * encoding like normal.
319 */
320 if (md->rmd128.curlen > 56) {
321 while (md->rmd128.curlen < 64) {
322 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
323 }
324 rmd128_compress(md, md->rmd128.buf);
325 md->rmd128.curlen = 0;
326 }
327
328 /* pad upto 56 bytes of zeroes */
329 while (md->rmd128.curlen < 56) {
330 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
331 }
332
333 /* store length */
334 STORE64L(md->rmd128.length, md->rmd128.buf+56);
335 rmd128_compress(md, md->rmd128.buf);
336
337 /* copy output */
338 for (i = 0; i < 4; i++) {
339 STORE32L(md->rmd128.state[i], out+(4*i));
340 }
341 #ifdef LTC_CLEAN_STACK
342 zeromem(md, sizeof(hash_state));
343 #endif
344 return CRYPT_OK;
345 }
346
347 /**
348 Self-test the hash
349 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
350 */
351 int rmd128_test(void)
352 {
353 #ifndef LTC_TEST
354 return CRYPT_NOP;
355 #else
356 static const struct {
357 char *msg;
358 unsigned char md[16];
359 } tests[] = {
360 { "",
361 { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
362 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 }
363 },
364 { "a",
365 { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
366 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 }
367 },
368 { "abc",
369 { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
370 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 }
371 },
372 { "message digest",
373 { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
374 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 }
375 },
376 { "abcdefghijklmnopqrstuvwxyz",
377 { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
378 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e }
379 },
380 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
381 { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
382 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 }
383 }
384 };
385 int x;
386 unsigned char buf[16];
387 hash_state md;
388
389 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
390 rmd128_init(&md);
391 rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
392 rmd128_done(&md, buf);
393 if (XMEMCMP(buf, tests[x].md, 16) != 0) {
394 #if 0
395 printf("Failed test %d\n", x);
396 #endif
397 return CRYPT_FAIL_TESTVECTOR;
398 }
399 }
400 return CRYPT_OK;
401 #endif
402 }
403
404 #endif
405
406
407 /* $Source$ */
408 /* $Revision$ */
409 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rmd160.c
14 RMD160 hash function
15 */
16
17 /* Implementation of LTC_RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC
18 *
19 * This source has been radically overhauled to be portable and work within
20 * the LibTomCrypt API by Tom St Denis
21 */
22
23 #ifdef LTC_RIPEMD160
24
25 const struct ltc_hash_descriptor rmd160_desc =
26 {
27 "rmd160",
28 9,
29 20,
30 64,
31
32 /* OID */
33 { 1, 3, 36, 3, 2, 1, },
34 6,
35
36 &rmd160_init,
37 &rmd160_process,
38 &rmd160_done,
39 &rmd160_test,
40 NULL
41 };
42
43 /* the five basic functions F(), G() and H() */
44 #define F(x, y, z) ((x) ^ (y) ^ (z))
45 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
46 #define H(x, y, z) (((x) | ~(y)) ^ (z))
47 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
48 #define J(x, y, z) ((x) ^ ((y) | ~(z)))
49
50 /* the ten basic operations FF() through III() */
51 #define FF(a, b, c, d, e, x, s) \
52 (a) += F((b), (c), (d)) + (x);\
53 (a) = ROLc((a), (s)) + (e);\
54 (c) = ROLc((c), 10);
55
56 #define GG(a, b, c, d, e, x, s) \
57 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
58 (a) = ROLc((a), (s)) + (e);\
59 (c) = ROLc((c), 10);
60
61 #define HH(a, b, c, d, e, x, s) \
62 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
63 (a) = ROLc((a), (s)) + (e);\
64 (c) = ROLc((c), 10);
65
66 #define II(a, b, c, d, e, x, s) \
67 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
68 (a) = ROLc((a), (s)) + (e);\
69 (c) = ROLc((c), 10);
70
71 #define JJ(a, b, c, d, e, x, s) \
72 (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
73 (a) = ROLc((a), (s)) + (e);\
74 (c) = ROLc((c), 10);
75
76 #define FFF(a, b, c, d, e, x, s) \
77 (a) += F((b), (c), (d)) + (x);\
78 (a) = ROLc((a), (s)) + (e);\
79 (c) = ROLc((c), 10);
80
81 #define GGG(a, b, c, d, e, x, s) \
82 (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
83 (a) = ROLc((a), (s)) + (e);\
84 (c) = ROLc((c), 10);
85
86 #define HHH(a, b, c, d, e, x, s) \
87 (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
88 (a) = ROLc((a), (s)) + (e);\
89 (c) = ROLc((c), 10);
90
91 #define III(a, b, c, d, e, x, s) \
92 (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
93 (a) = ROLc((a), (s)) + (e);\
94 (c) = ROLc((c), 10);
95
96 #define JJJ(a, b, c, d, e, x, s) \
97 (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
98 (a) = ROLc((a), (s)) + (e);\
99 (c) = ROLc((c), 10);
100
101
102 #ifdef LTC_CLEAN_STACK
103 static int _rmd160_compress(hash_state *md, unsigned char *buf)
104 #else
105 static int rmd160_compress(hash_state *md, unsigned char *buf)
106 #endif
107 {
108 ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16];
109 int i;
110
111 /* load words X */
112 for (i = 0; i < 16; i++){
113 LOAD32L(X[i], buf + (4 * i));
114 }
115
116 /* load state */
117 aa = aaa = md->rmd160.state[0];
118 bb = bbb = md->rmd160.state[1];
119 cc = ccc = md->rmd160.state[2];
120 dd = ddd = md->rmd160.state[3];
121 ee = eee = md->rmd160.state[4];
122
123 /* round 1 */
124 FF(aa, bb, cc, dd, ee, X[ 0], 11);
125 FF(ee, aa, bb, cc, dd, X[ 1], 14);
126 FF(dd, ee, aa, bb, cc, X[ 2], 15);
127 FF(cc, dd, ee, aa, bb, X[ 3], 12);
128 FF(bb, cc, dd, ee, aa, X[ 4], 5);
129 FF(aa, bb, cc, dd, ee, X[ 5], 8);
130 FF(ee, aa, bb, cc, dd, X[ 6], 7);
131 FF(dd, ee, aa, bb, cc, X[ 7], 9);
132 FF(cc, dd, ee, aa, bb, X[ 8], 11);
133 FF(bb, cc, dd, ee, aa, X[ 9], 13);
134 FF(aa, bb, cc, dd, ee, X[10], 14);
135 FF(ee, aa, bb, cc, dd, X[11], 15);
136 FF(dd, ee, aa, bb, cc, X[12], 6);
137 FF(cc, dd, ee, aa, bb, X[13], 7);
138 FF(bb, cc, dd, ee, aa, X[14], 9);
139 FF(aa, bb, cc, dd, ee, X[15], 8);
140
141 /* round 2 */
142 GG(ee, aa, bb, cc, dd, X[ 7], 7);
143 GG(dd, ee, aa, bb, cc, X[ 4], 6);
144 GG(cc, dd, ee, aa, bb, X[13], 8);
145 GG(bb, cc, dd, ee, aa, X[ 1], 13);
146 GG(aa, bb, cc, dd, ee, X[10], 11);
147 GG(ee, aa, bb, cc, dd, X[ 6], 9);
148 GG(dd, ee, aa, bb, cc, X[15], 7);
149 GG(cc, dd, ee, aa, bb, X[ 3], 15);
150 GG(bb, cc, dd, ee, aa, X[12], 7);
151 GG(aa, bb, cc, dd, ee, X[ 0], 12);
152 GG(ee, aa, bb, cc, dd, X[ 9], 15);
153 GG(dd, ee, aa, bb, cc, X[ 5], 9);
154 GG(cc, dd, ee, aa, bb, X[ 2], 11);
155 GG(bb, cc, dd, ee, aa, X[14], 7);
156 GG(aa, bb, cc, dd, ee, X[11], 13);
157 GG(ee, aa, bb, cc, dd, X[ 8], 12);
158
159 /* round 3 */
160 HH(dd, ee, aa, bb, cc, X[ 3], 11);
161 HH(cc, dd, ee, aa, bb, X[10], 13);
162 HH(bb, cc, dd, ee, aa, X[14], 6);
163 HH(aa, bb, cc, dd, ee, X[ 4], 7);
164 HH(ee, aa, bb, cc, dd, X[ 9], 14);
165 HH(dd, ee, aa, bb, cc, X[15], 9);
166 HH(cc, dd, ee, aa, bb, X[ 8], 13);
167 HH(bb, cc, dd, ee, aa, X[ 1], 15);
168 HH(aa, bb, cc, dd, ee, X[ 2], 14);
169 HH(ee, aa, bb, cc, dd, X[ 7], 8);
170 HH(dd, ee, aa, bb, cc, X[ 0], 13);
171 HH(cc, dd, ee, aa, bb, X[ 6], 6);
172 HH(bb, cc, dd, ee, aa, X[13], 5);
173 HH(aa, bb, cc, dd, ee, X[11], 12);
174 HH(ee, aa, bb, cc, dd, X[ 5], 7);
175 HH(dd, ee, aa, bb, cc, X[12], 5);
176
177 /* round 4 */
178 II(cc, dd, ee, aa, bb, X[ 1], 11);
179 II(bb, cc, dd, ee, aa, X[ 9], 12);
180 II(aa, bb, cc, dd, ee, X[11], 14);
181 II(ee, aa, bb, cc, dd, X[10], 15);
182 II(dd, ee, aa, bb, cc, X[ 0], 14);
183 II(cc, dd, ee, aa, bb, X[ 8], 15);
184 II(bb, cc, dd, ee, aa, X[12], 9);
185 II(aa, bb, cc, dd, ee, X[ 4], 8);
186 II(ee, aa, bb, cc, dd, X[13], 9);
187 II(dd, ee, aa, bb, cc, X[ 3], 14);
188 II(cc, dd, ee, aa, bb, X[ 7], 5);
189 II(bb, cc, dd, ee, aa, X[15], 6);
190 II(aa, bb, cc, dd, ee, X[14], 8);
191 II(ee, aa, bb, cc, dd, X[ 5], 6);
192 II(dd, ee, aa, bb, cc, X[ 6], 5);
193 II(cc, dd, ee, aa, bb, X[ 2], 12);
194
195 /* round 5 */
196 JJ(bb, cc, dd, ee, aa, X[ 4], 9);
197 JJ(aa, bb, cc, dd, ee, X[ 0], 15);
198 JJ(ee, aa, bb, cc, dd, X[ 5], 5);
199 JJ(dd, ee, aa, bb, cc, X[ 9], 11);
200 JJ(cc, dd, ee, aa, bb, X[ 7], 6);
201 JJ(bb, cc, dd, ee, aa, X[12], 8);
202 JJ(aa, bb, cc, dd, ee, X[ 2], 13);
203 JJ(ee, aa, bb, cc, dd, X[10], 12);
204 JJ(dd, ee, aa, bb, cc, X[14], 5);
205 JJ(cc, dd, ee, aa, bb, X[ 1], 12);
206 JJ(bb, cc, dd, ee, aa, X[ 3], 13);
207 JJ(aa, bb, cc, dd, ee, X[ 8], 14);
208 JJ(ee, aa, bb, cc, dd, X[11], 11);
209 JJ(dd, ee, aa, bb, cc, X[ 6], 8);
210 JJ(cc, dd, ee, aa, bb, X[15], 5);
211 JJ(bb, cc, dd, ee, aa, X[13], 6);
212
213 /* parallel round 1 */
214 JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
215 JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
216 JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
217 JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
218 JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
219 JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
220 JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
221 JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
222 JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
223 JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
224 JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
225 JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
226 JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
227 JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
228 JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
229 JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
230
231 /* parallel round 2 */
232 III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
233 III(ddd, eee, aaa, bbb, ccc, X[11], 13);
234 III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
235 III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
236 III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
237 III(eee, aaa, bbb, ccc, ddd, X[13], 8);
238 III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
239 III(ccc, ddd, eee, aaa, bbb, X[10], 11);
240 III(bbb, ccc, ddd, eee, aaa, X[14], 7);
241 III(aaa, bbb, ccc, ddd, eee, X[15], 7);
242 III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
243 III(ddd, eee, aaa, bbb, ccc, X[12], 7);
244 III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
245 III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
246 III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
247 III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
248
249 /* parallel round 3 */
250 HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
251 HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
252 HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
253 HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
254 HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
255 HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
256 HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
257 HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
258 HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
259 HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
260 HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
261 HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
262 HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
263 HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
264 HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
265 HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
266
267 /* parallel round 4 */
268 GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
269 GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
270 GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
271 GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
272 GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
273 GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
274 GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
275 GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
276 GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
277 GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
278 GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
279 GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
280 GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
281 GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
282 GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
283 GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
284
285 /* parallel round 5 */
286 FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
287 FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
288 FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
289 FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
290 FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
291 FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
292 FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
293 FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
294 FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
295 FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
296 FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
297 FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
298 FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
299 FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
300 FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
301 FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
302
303 /* combine results */
304 ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */
305 md->rmd160.state[1] = md->rmd160.state[2] + dd + eee;
306 md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa;
307 md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb;
308 md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc;
309 md->rmd160.state[0] = ddd;
310
311 return CRYPT_OK;
312 }
313
314 #ifdef LTC_CLEAN_STACK
315 static int rmd160_compress(hash_state *md, unsigned char *buf)
316 {
317 int err;
318 err = _rmd160_compress(md, buf);
319 burn_stack(sizeof(ulong32) * 26 + sizeof(int));
320 return err;
321 }
322 #endif
323
324 /**
325 Initialize the hash state
326 @param md The hash state you wish to initialize
327 @return CRYPT_OK if successful
328 */
329 int rmd160_init(hash_state * md)
330 {
331 LTC_ARGCHK(md != NULL);
332 md->rmd160.state[0] = 0x67452301UL;
333 md->rmd160.state[1] = 0xefcdab89UL;
334 md->rmd160.state[2] = 0x98badcfeUL;
335 md->rmd160.state[3] = 0x10325476UL;
336 md->rmd160.state[4] = 0xc3d2e1f0UL;
337 md->rmd160.curlen = 0;
338 md->rmd160.length = 0;
339 return CRYPT_OK;
340 }
341
342 /**
343 Process a block of memory though the hash
344 @param md The hash state
345 @param in The data to hash
346 @param inlen The length of the data (octets)
347 @return CRYPT_OK if successful
348 */
349 HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64)
350
351 /**
352 Terminate the hash to get the digest
353 @param md The hash state
354 @param out [out] The destination of the hash (20 bytes)
355 @return CRYPT_OK if successful
356 */
357 int rmd160_done(hash_state * md, unsigned char *out)
358 {
359 int i;
360
361 LTC_ARGCHK(md != NULL);
362 LTC_ARGCHK(out != NULL);
363
364 if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) {
365 return CRYPT_INVALID_ARG;
366 }
367
368
369 /* increase the length of the message */
370 md->rmd160.length += md->rmd160.curlen * 8;
371
372 /* append the '1' bit */
373 md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80;
374
375 /* if the length is currently above 56 bytes we append zeros
376 * then compress. Then we can fall back to padding zeros and length
377 * encoding like normal.
378 */
379 if (md->rmd160.curlen > 56) {
380 while (md->rmd160.curlen < 64) {
381 md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
382 }
383 rmd160_compress(md, md->rmd160.buf);
384 md->rmd160.curlen = 0;
385 }
386
387 /* pad upto 56 bytes of zeroes */
388 while (md->rmd160.curlen < 56) {
389 md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
390 }
391
392 /* store length */
393 STORE64L(md->rmd160.length, md->rmd160.buf+56);
394 rmd160_compress(md, md->rmd160.buf);
395
396 /* copy output */
397 for (i = 0; i < 5; i++) {
398 STORE32L(md->rmd160.state[i], out+(4*i));
399 }
400 #ifdef LTC_CLEAN_STACK
401 zeromem(md, sizeof(hash_state));
402 #endif
403 return CRYPT_OK;
404 }
405
406 /**
407 Self-test the hash
408 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
409 */
410 int rmd160_test(void)
411 {
412 #ifndef LTC_TEST
413 return CRYPT_NOP;
414 #else
415 static const struct {
416 char *msg;
417 unsigned char md[20];
418 } tests[] = {
419 { "",
420 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
421 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }
422 },
423 { "a",
424 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
425 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }
426 },
427 { "abc",
428 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
429 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }
430 },
431 { "message digest",
432 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
433 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }
434 },
435 { "abcdefghijklmnopqrstuvwxyz",
436 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
437 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }
438 },
439 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
440 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
441 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }
442 }
443 };
444 int x;
445 unsigned char buf[20];
446 hash_state md;
447
448 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
449 rmd160_init(&md);
450 rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
451 rmd160_done(&md, buf);
452 if (XMEMCMP(buf, tests[x].md, 20) != 0) {
453 #if 0
454 printf("Failed test %d\n", x);
455 #endif
456 return CRYPT_FAIL_TESTVECTOR;
457 }
458 }
459 return CRYPT_OK;
460 #endif
461 }
462
463 #endif
464
465
466 /* $Source$ */
467 /* $Revision$ */
468 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param rmd256.c
14 RLTC_MD256 Hash function
15 */
16
17 #ifdef LTC_RIPEMD256
18
19 const struct ltc_hash_descriptor rmd256_desc =
20 {
21 "rmd256",
22 8,
23 32,
24 64,
25
26 /* OID */
27 { 1, 3, 36, 3, 2, 3 },
28 6,
29
30 &rmd256_init,
31 &rmd256_process,
32 &rmd256_done,
33 &rmd256_test,
34 NULL
35 };
36
37 /* the four basic functions F(), G() and H() */
38 #define F(x, y, z) ((x) ^ (y) ^ (z))
39 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
40 #define H(x, y, z) (((x) | ~(y)) ^ (z))
41 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
42
43 /* the eight basic operations FF() through III() */
44 #define FF(a, b, c, d, x, s) \
45 (a) += F((b), (c), (d)) + (x);\
46 (a) = ROLc((a), (s));
47
48 #define GG(a, b, c, d, x, s) \
49 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
50 (a) = ROLc((a), (s));
51
52 #define HH(a, b, c, d, x, s) \
53 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
54 (a) = ROLc((a), (s));
55
56 #define II(a, b, c, d, x, s) \
57 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
58 (a) = ROLc((a), (s));
59
60 #define FFF(a, b, c, d, x, s) \
61 (a) += F((b), (c), (d)) + (x);\
62 (a) = ROLc((a), (s));
63
64 #define GGG(a, b, c, d, x, s) \
65 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
66 (a) = ROLc((a), (s));
67
68 #define HHH(a, b, c, d, x, s) \
69 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
70 (a) = ROLc((a), (s));
71
72 #define III(a, b, c, d, x, s) \
73 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
74 (a) = ROLc((a), (s));
75
76 #ifdef LTC_CLEAN_STACK
77 static int _rmd256_compress(hash_state *md, unsigned char *buf)
78 #else
79 static int rmd256_compress(hash_state *md, unsigned char *buf)
80 #endif
81 {
82 ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16];
83 int i;
84
85 /* load words X */
86 for (i = 0; i < 16; i++){
87 LOAD32L(X[i], buf + (4 * i));
88 }
89
90 /* load state */
91 aa = md->rmd256.state[0];
92 bb = md->rmd256.state[1];
93 cc = md->rmd256.state[2];
94 dd = md->rmd256.state[3];
95 aaa = md->rmd256.state[4];
96 bbb = md->rmd256.state[5];
97 ccc = md->rmd256.state[6];
98 ddd = md->rmd256.state[7];
99
100 /* round 1 */
101 FF(aa, bb, cc, dd, X[ 0], 11);
102 FF(dd, aa, bb, cc, X[ 1], 14);
103 FF(cc, dd, aa, bb, X[ 2], 15);
104 FF(bb, cc, dd, aa, X[ 3], 12);
105 FF(aa, bb, cc, dd, X[ 4], 5);
106 FF(dd, aa, bb, cc, X[ 5], 8);
107 FF(cc, dd, aa, bb, X[ 6], 7);
108 FF(bb, cc, dd, aa, X[ 7], 9);
109 FF(aa, bb, cc, dd, X[ 8], 11);
110 FF(dd, aa, bb, cc, X[ 9], 13);
111 FF(cc, dd, aa, bb, X[10], 14);
112 FF(bb, cc, dd, aa, X[11], 15);
113 FF(aa, bb, cc, dd, X[12], 6);
114 FF(dd, aa, bb, cc, X[13], 7);
115 FF(cc, dd, aa, bb, X[14], 9);
116 FF(bb, cc, dd, aa, X[15], 8);
117
118 /* parallel round 1 */
119 III(aaa, bbb, ccc, ddd, X[ 5], 8);
120 III(ddd, aaa, bbb, ccc, X[14], 9);
121 III(ccc, ddd, aaa, bbb, X[ 7], 9);
122 III(bbb, ccc, ddd, aaa, X[ 0], 11);
123 III(aaa, bbb, ccc, ddd, X[ 9], 13);
124 III(ddd, aaa, bbb, ccc, X[ 2], 15);
125 III(ccc, ddd, aaa, bbb, X[11], 15);
126 III(bbb, ccc, ddd, aaa, X[ 4], 5);
127 III(aaa, bbb, ccc, ddd, X[13], 7);
128 III(ddd, aaa, bbb, ccc, X[ 6], 7);
129 III(ccc, ddd, aaa, bbb, X[15], 8);
130 III(bbb, ccc, ddd, aaa, X[ 8], 11);
131 III(aaa, bbb, ccc, ddd, X[ 1], 14);
132 III(ddd, aaa, bbb, ccc, X[10], 14);
133 III(ccc, ddd, aaa, bbb, X[ 3], 12);
134 III(bbb, ccc, ddd, aaa, X[12], 6);
135
136 tmp = aa; aa = aaa; aaa = tmp;
137
138 /* round 2 */
139 GG(aa, bb, cc, dd, X[ 7], 7);
140 GG(dd, aa, bb, cc, X[ 4], 6);
141 GG(cc, dd, aa, bb, X[13], 8);
142 GG(bb, cc, dd, aa, X[ 1], 13);
143 GG(aa, bb, cc, dd, X[10], 11);
144 GG(dd, aa, bb, cc, X[ 6], 9);
145 GG(cc, dd, aa, bb, X[15], 7);
146 GG(bb, cc, dd, aa, X[ 3], 15);
147 GG(aa, bb, cc, dd, X[12], 7);
148 GG(dd, aa, bb, cc, X[ 0], 12);
149 GG(cc, dd, aa, bb, X[ 9], 15);
150 GG(bb, cc, dd, aa, X[ 5], 9);
151 GG(aa, bb, cc, dd, X[ 2], 11);
152 GG(dd, aa, bb, cc, X[14], 7);
153 GG(cc, dd, aa, bb, X[11], 13);
154 GG(bb, cc, dd, aa, X[ 8], 12);
155
156 /* parallel round 2 */
157 HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
158 HHH(ddd, aaa, bbb, ccc, X[11], 13);
159 HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
160 HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
161 HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
162 HHH(ddd, aaa, bbb, ccc, X[13], 8);
163 HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
164 HHH(bbb, ccc, ddd, aaa, X[10], 11);
165 HHH(aaa, bbb, ccc, ddd, X[14], 7);
166 HHH(ddd, aaa, bbb, ccc, X[15], 7);
167 HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
168 HHH(bbb, ccc, ddd, aaa, X[12], 7);
169 HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
170 HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
171 HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
172 HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
173
174 tmp = bb; bb = bbb; bbb = tmp;
175
176 /* round 3 */
177 HH(aa, bb, cc, dd, X[ 3], 11);
178 HH(dd, aa, bb, cc, X[10], 13);
179 HH(cc, dd, aa, bb, X[14], 6);
180 HH(bb, cc, dd, aa, X[ 4], 7);
181 HH(aa, bb, cc, dd, X[ 9], 14);
182 HH(dd, aa, bb, cc, X[15], 9);
183 HH(cc, dd, aa, bb, X[ 8], 13);
184 HH(bb, cc, dd, aa, X[ 1], 15);
185 HH(aa, bb, cc, dd, X[ 2], 14);
186 HH(dd, aa, bb, cc, X[ 7], 8);
187 HH(cc, dd, aa, bb, X[ 0], 13);
188 HH(bb, cc, dd, aa, X[ 6], 6);
189 HH(aa, bb, cc, dd, X[13], 5);
190 HH(dd, aa, bb, cc, X[11], 12);
191 HH(cc, dd, aa, bb, X[ 5], 7);
192 HH(bb, cc, dd, aa, X[12], 5);
193
194 /* parallel round 3 */
195 GGG(aaa, bbb, ccc, ddd, X[15], 9);
196 GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
197 GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
198 GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
199 GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
200 GGG(ddd, aaa, bbb, ccc, X[14], 6);
201 GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
202 GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
203 GGG(aaa, bbb, ccc, ddd, X[11], 12);
204 GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
205 GGG(ccc, ddd, aaa, bbb, X[12], 5);
206 GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
207 GGG(aaa, bbb, ccc, ddd, X[10], 13);
208 GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
209 GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
210 GGG(bbb, ccc, ddd, aaa, X[13], 5);
211
212 tmp = cc; cc = ccc; ccc = tmp;
213
214 /* round 4 */
215 II(aa, bb, cc, dd, X[ 1], 11);
216 II(dd, aa, bb, cc, X[ 9], 12);
217 II(cc, dd, aa, bb, X[11], 14);
218 II(bb, cc, dd, aa, X[10], 15);
219 II(aa, bb, cc, dd, X[ 0], 14);
220 II(dd, aa, bb, cc, X[ 8], 15);
221 II(cc, dd, aa, bb, X[12], 9);
222 II(bb, cc, dd, aa, X[ 4], 8);
223 II(aa, bb, cc, dd, X[13], 9);
224 II(dd, aa, bb, cc, X[ 3], 14);
225 II(cc, dd, aa, bb, X[ 7], 5);
226 II(bb, cc, dd, aa, X[15], 6);
227 II(aa, bb, cc, dd, X[14], 8);
228 II(dd, aa, bb, cc, X[ 5], 6);
229 II(cc, dd, aa, bb, X[ 6], 5);
230 II(bb, cc, dd, aa, X[ 2], 12);
231
232 /* parallel round 4 */
233 FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
234 FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
235 FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
236 FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
237 FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
238 FFF(ddd, aaa, bbb, ccc, X[11], 14);
239 FFF(ccc, ddd, aaa, bbb, X[15], 6);
240 FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
241 FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
242 FFF(ddd, aaa, bbb, ccc, X[12], 9);
243 FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
244 FFF(bbb, ccc, ddd, aaa, X[13], 9);
245 FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
246 FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
247 FFF(ccc, ddd, aaa, bbb, X[10], 15);
248 FFF(bbb, ccc, ddd, aaa, X[14], 8);
249
250 tmp = dd; dd = ddd; ddd = tmp;
251
252 /* combine results */
253 md->rmd256.state[0] += aa;
254 md->rmd256.state[1] += bb;
255 md->rmd256.state[2] += cc;
256 md->rmd256.state[3] += dd;
257 md->rmd256.state[4] += aaa;
258 md->rmd256.state[5] += bbb;
259 md->rmd256.state[6] += ccc;
260 md->rmd256.state[7] += ddd;
261
262 return CRYPT_OK;
263 }
264
265 #ifdef LTC_CLEAN_STACK
266 static int rmd256_compress(hash_state *md, unsigned char *buf)
267 {
268 int err;
269 err = _rmd256_compress(md, buf);
270 burn_stack(sizeof(ulong32) * 25 + sizeof(int));
271 return err;
272 }
273 #endif
274
275 /**
276 Initialize the hash state
277 @param md The hash state you wish to initialize
278 @return CRYPT_OK if successful
279 */
280 int rmd256_init(hash_state * md)
281 {
282 LTC_ARGCHK(md != NULL);
283 md->rmd256.state[0] = 0x67452301UL;
284 md->rmd256.state[1] = 0xefcdab89UL;
285 md->rmd256.state[2] = 0x98badcfeUL;
286 md->rmd256.state[3] = 0x10325476UL;
287 md->rmd256.state[4] = 0x76543210UL;
288 md->rmd256.state[5] = 0xfedcba98UL;
289 md->rmd256.state[6] = 0x89abcdefUL;
290 md->rmd256.state[7] = 0x01234567UL;
291 md->rmd256.curlen = 0;
292 md->rmd256.length = 0;
293 return CRYPT_OK;
294 }
295
296 /**
297 Process a block of memory though the hash
298 @param md The hash state
299 @param in The data to hash
300 @param inlen The length of the data (octets)
301 @return CRYPT_OK if successful
302 */
303 HASH_PROCESS(rmd256_process, rmd256_compress, rmd256, 64)
304
305 /**
306 Terminate the hash to get the digest
307 @param md The hash state
308 @param out [out] The destination of the hash (16 bytes)
309 @return CRYPT_OK if successful
310 */
311 int rmd256_done(hash_state * md, unsigned char *out)
312 {
313 int i;
314
315 LTC_ARGCHK(md != NULL);
316 LTC_ARGCHK(out != NULL);
317
318 if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) {
319 return CRYPT_INVALID_ARG;
320 }
321
322
323 /* increase the length of the message */
324 md->rmd256.length += md->rmd256.curlen * 8;
325
326 /* append the '1' bit */
327 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80;
328
329 /* if the length is currently above 56 bytes we append zeros
330 * then compress. Then we can fall back to padding zeros and length
331 * encoding like normal.
332 */
333 if (md->rmd256.curlen > 56) {
334 while (md->rmd256.curlen < 64) {
335 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
336 }
337 rmd256_compress(md, md->rmd256.buf);
338 md->rmd256.curlen = 0;
339 }
340
341 /* pad upto 56 bytes of zeroes */
342 while (md->rmd256.curlen < 56) {
343 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
344 }
345
346 /* store length */
347 STORE64L(md->rmd256.length, md->rmd256.buf+56);
348 rmd256_compress(md, md->rmd256.buf);
349
350 /* copy output */
351 for (i = 0; i < 8; i++) {
352 STORE32L(md->rmd256.state[i], out+(4*i));
353 }
354 #ifdef LTC_CLEAN_STACK
355 zeromem(md, sizeof(hash_state));
356 #endif
357 return CRYPT_OK;
358 }
359
360 /**
361 Self-test the hash
362 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
363 */
364 int rmd256_test(void)
365 {
366 #ifndef LTC_TEST
367 return CRYPT_NOP;
368 #else
369 static const struct {
370 char *msg;
371 unsigned char md[32];
372 } tests[] = {
373 { "",
374 { 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18,
375 0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a,
376 0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63,
377 0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d }
378 },
379 { "a",
380 { 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9,
381 0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c,
382 0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf,
383 0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 }
384 },
385 { "abc",
386 { 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb,
387 0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1,
388 0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e,
389 0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 }
390 },
391 { "message digest",
392 { 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a,
393 0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90,
394 0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55,
395 0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e }
396 },
397 { "abcdefghijklmnopqrstuvwxyz",
398 { 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16,
399 0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc,
400 0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87,
401 0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 }
402 },
403 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
404 { 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20,
405 0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f,
406 0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1,
407 0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 }
408 }
409 };
410 int x;
411 unsigned char buf[32];
412 hash_state md;
413
414 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
415 rmd256_init(&md);
416 rmd256_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
417 rmd256_done(&md, buf);
418 if (XMEMCMP(buf, tests[x].md, 32) != 0) {
419 #if 0
420 printf("Failed test %d\n", x);
421 #endif
422 return CRYPT_FAIL_TESTVECTOR;
423 }
424 }
425 return CRYPT_OK;
426 #endif
427 }
428
429 #endif
430
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rmd320.c
14 RMD320 hash function
15 */
16
17 #ifdef LTC_RIPEMD320
18
19 const struct ltc_hash_descriptor rmd320_desc =
20 {
21 "rmd320",
22 9,
23 40,
24 64,
25
26 /* OID */
27 { 0 },
28 0,
29
30 &rmd320_init,
31 &rmd320_process,
32 &rmd320_done,
33 &rmd320_test,
34 NULL
35 };
36
37 /* the five basic functions F(), G() and H() */
38 #define F(x, y, z) ((x) ^ (y) ^ (z))
39 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
40 #define H(x, y, z) (((x) | ~(y)) ^ (z))
41 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
42 #define J(x, y, z) ((x) ^ ((y) | ~(z)))
43
44 /* the ten basic operations FF() through III() */
45 #define FF(a, b, c, d, e, x, s) \
46 (a) += F((b), (c), (d)) + (x);\
47 (a) = ROLc((a), (s)) + (e);\
48 (c) = ROLc((c), 10);
49
50 #define GG(a, b, c, d, e, x, s) \
51 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
52 (a) = ROLc((a), (s)) + (e);\
53 (c) = ROLc((c), 10);
54
55 #define HH(a, b, c, d, e, x, s) \
56 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
57 (a) = ROLc((a), (s)) + (e);\
58 (c) = ROLc((c), 10);
59
60 #define II(a, b, c, d, e, x, s) \
61 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
62 (a) = ROLc((a), (s)) + (e);\
63 (c) = ROLc((c), 10);
64
65 #define JJ(a, b, c, d, e, x, s) \
66 (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
67 (a) = ROLc((a), (s)) + (e);\
68 (c) = ROLc((c), 10);
69
70 #define FFF(a, b, c, d, e, x, s) \
71 (a) += F((b), (c), (d)) + (x);\
72 (a) = ROLc((a), (s)) + (e);\
73 (c) = ROLc((c), 10);
74
75 #define GGG(a, b, c, d, e, x, s) \
76 (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
77 (a) = ROLc((a), (s)) + (e);\
78 (c) = ROLc((c), 10);
79
80 #define HHH(a, b, c, d, e, x, s) \
81 (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
82 (a) = ROLc((a), (s)) + (e);\
83 (c) = ROLc((c), 10);
84
85 #define III(a, b, c, d, e, x, s) \
86 (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
87 (a) = ROLc((a), (s)) + (e);\
88 (c) = ROLc((c), 10);
89
90 #define JJJ(a, b, c, d, e, x, s) \
91 (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
92 (a) = ROLc((a), (s)) + (e);\
93 (c) = ROLc((c), 10);
94
95
96 #ifdef LTC_CLEAN_STACK
97 static int _rmd320_compress(hash_state *md, unsigned char *buf)
98 #else
99 static int rmd320_compress(hash_state *md, unsigned char *buf)
100 #endif
101 {
102 ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16];
103 int i;
104
105 /* load words X */
106 for (i = 0; i < 16; i++){
107 LOAD32L(X[i], buf + (4 * i));
108 }
109
110 /* load state */
111 aa = md->rmd320.state[0];
112 bb = md->rmd320.state[1];
113 cc = md->rmd320.state[2];
114 dd = md->rmd320.state[3];
115 ee = md->rmd320.state[4];
116 aaa = md->rmd320.state[5];
117 bbb = md->rmd320.state[6];
118 ccc = md->rmd320.state[7];
119 ddd = md->rmd320.state[8];
120 eee = md->rmd320.state[9];
121
122 /* round 1 */
123 FF(aa, bb, cc, dd, ee, X[ 0], 11);
124 FF(ee, aa, bb, cc, dd, X[ 1], 14);
125 FF(dd, ee, aa, bb, cc, X[ 2], 15);
126 FF(cc, dd, ee, aa, bb, X[ 3], 12);
127 FF(bb, cc, dd, ee, aa, X[ 4], 5);
128 FF(aa, bb, cc, dd, ee, X[ 5], 8);
129 FF(ee, aa, bb, cc, dd, X[ 6], 7);
130 FF(dd, ee, aa, bb, cc, X[ 7], 9);
131 FF(cc, dd, ee, aa, bb, X[ 8], 11);
132 FF(bb, cc, dd, ee, aa, X[ 9], 13);
133 FF(aa, bb, cc, dd, ee, X[10], 14);
134 FF(ee, aa, bb, cc, dd, X[11], 15);
135 FF(dd, ee, aa, bb, cc, X[12], 6);
136 FF(cc, dd, ee, aa, bb, X[13], 7);
137 FF(bb, cc, dd, ee, aa, X[14], 9);
138 FF(aa, bb, cc, dd, ee, X[15], 8);
139
140 /* parallel round 1 */
141 JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
142 JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
143 JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
144 JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
145 JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
146 JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
147 JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
148 JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
149 JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
150 JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
151 JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
152 JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
153 JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
154 JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
155 JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
156 JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
157
158 tmp = aa; aa = aaa; aaa = tmp;
159
160 /* round 2 */
161 GG(ee, aa, bb, cc, dd, X[ 7], 7);
162 GG(dd, ee, aa, bb, cc, X[ 4], 6);
163 GG(cc, dd, ee, aa, bb, X[13], 8);
164 GG(bb, cc, dd, ee, aa, X[ 1], 13);
165 GG(aa, bb, cc, dd, ee, X[10], 11);
166 GG(ee, aa, bb, cc, dd, X[ 6], 9);
167 GG(dd, ee, aa, bb, cc, X[15], 7);
168 GG(cc, dd, ee, aa, bb, X[ 3], 15);
169 GG(bb, cc, dd, ee, aa, X[12], 7);
170 GG(aa, bb, cc, dd, ee, X[ 0], 12);
171 GG(ee, aa, bb, cc, dd, X[ 9], 15);
172 GG(dd, ee, aa, bb, cc, X[ 5], 9);
173 GG(cc, dd, ee, aa, bb, X[ 2], 11);
174 GG(bb, cc, dd, ee, aa, X[14], 7);
175 GG(aa, bb, cc, dd, ee, X[11], 13);
176 GG(ee, aa, bb, cc, dd, X[ 8], 12);
177
178 /* parallel round 2 */
179 III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
180 III(ddd, eee, aaa, bbb, ccc, X[11], 13);
181 III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
182 III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
183 III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
184 III(eee, aaa, bbb, ccc, ddd, X[13], 8);
185 III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
186 III(ccc, ddd, eee, aaa, bbb, X[10], 11);
187 III(bbb, ccc, ddd, eee, aaa, X[14], 7);
188 III(aaa, bbb, ccc, ddd, eee, X[15], 7);
189 III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
190 III(ddd, eee, aaa, bbb, ccc, X[12], 7);
191 III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
192 III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
193 III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
194 III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
195
196 tmp = bb; bb = bbb; bbb = tmp;
197
198 /* round 3 */
199 HH(dd, ee, aa, bb, cc, X[ 3], 11);
200 HH(cc, dd, ee, aa, bb, X[10], 13);
201 HH(bb, cc, dd, ee, aa, X[14], 6);
202 HH(aa, bb, cc, dd, ee, X[ 4], 7);
203 HH(ee, aa, bb, cc, dd, X[ 9], 14);
204 HH(dd, ee, aa, bb, cc, X[15], 9);
205 HH(cc, dd, ee, aa, bb, X[ 8], 13);
206 HH(bb, cc, dd, ee, aa, X[ 1], 15);
207 HH(aa, bb, cc, dd, ee, X[ 2], 14);
208 HH(ee, aa, bb, cc, dd, X[ 7], 8);
209 HH(dd, ee, aa, bb, cc, X[ 0], 13);
210 HH(cc, dd, ee, aa, bb, X[ 6], 6);
211 HH(bb, cc, dd, ee, aa, X[13], 5);
212 HH(aa, bb, cc, dd, ee, X[11], 12);
213 HH(ee, aa, bb, cc, dd, X[ 5], 7);
214 HH(dd, ee, aa, bb, cc, X[12], 5);
215
216 /* parallel round 3 */
217 HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
218 HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
219 HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
220 HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
221 HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
222 HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
223 HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
224 HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
225 HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
226 HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
227 HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
228 HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
229 HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
230 HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
231 HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
232 HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
233
234 tmp = cc; cc = ccc; ccc = tmp;
235
236 /* round 4 */
237 II(cc, dd, ee, aa, bb, X[ 1], 11);
238 II(bb, cc, dd, ee, aa, X[ 9], 12);
239 II(aa, bb, cc, dd, ee, X[11], 14);
240 II(ee, aa, bb, cc, dd, X[10], 15);
241 II(dd, ee, aa, bb, cc, X[ 0], 14);
242 II(cc, dd, ee, aa, bb, X[ 8], 15);
243 II(bb, cc, dd, ee, aa, X[12], 9);
244 II(aa, bb, cc, dd, ee, X[ 4], 8);
245 II(ee, aa, bb, cc, dd, X[13], 9);
246 II(dd, ee, aa, bb, cc, X[ 3], 14);
247 II(cc, dd, ee, aa, bb, X[ 7], 5);
248 II(bb, cc, dd, ee, aa, X[15], 6);
249 II(aa, bb, cc, dd, ee, X[14], 8);
250 II(ee, aa, bb, cc, dd, X[ 5], 6);
251 II(dd, ee, aa, bb, cc, X[ 6], 5);
252 II(cc, dd, ee, aa, bb, X[ 2], 12);
253
254 /* parallel round 4 */
255 GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
256 GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
257 GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
258 GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
259 GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
260 GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
261 GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
262 GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
263 GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
264 GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
265 GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
266 GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
267 GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
268 GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
269 GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
270 GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
271
272 tmp = dd; dd = ddd; ddd = tmp;
273
274 /* round 5 */
275 JJ(bb, cc, dd, ee, aa, X[ 4], 9);
276 JJ(aa, bb, cc, dd, ee, X[ 0], 15);
277 JJ(ee, aa, bb, cc, dd, X[ 5], 5);
278 JJ(dd, ee, aa, bb, cc, X[ 9], 11);
279 JJ(cc, dd, ee, aa, bb, X[ 7], 6);
280 JJ(bb, cc, dd, ee, aa, X[12], 8);
281 JJ(aa, bb, cc, dd, ee, X[ 2], 13);
282 JJ(ee, aa, bb, cc, dd, X[10], 12);
283 JJ(dd, ee, aa, bb, cc, X[14], 5);
284 JJ(cc, dd, ee, aa, bb, X[ 1], 12);
285 JJ(bb, cc, dd, ee, aa, X[ 3], 13);
286 JJ(aa, bb, cc, dd, ee, X[ 8], 14);
287 JJ(ee, aa, bb, cc, dd, X[11], 11);
288 JJ(dd, ee, aa, bb, cc, X[ 6], 8);
289 JJ(cc, dd, ee, aa, bb, X[15], 5);
290 JJ(bb, cc, dd, ee, aa, X[13], 6);
291
292 /* parallel round 5 */
293 FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
294 FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
295 FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
296 FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
297 FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
298 FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
299 FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
300 FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
301 FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
302 FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
303 FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
304 FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
305 FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
306 FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
307 FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
308 FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
309
310 tmp = ee; ee = eee; eee = tmp;
311
312 /* combine results */
313 md->rmd320.state[0] += aa;
314 md->rmd320.state[1] += bb;
315 md->rmd320.state[2] += cc;
316 md->rmd320.state[3] += dd;
317 md->rmd320.state[4] += ee;
318 md->rmd320.state[5] += aaa;
319 md->rmd320.state[6] += bbb;
320 md->rmd320.state[7] += ccc;
321 md->rmd320.state[8] += ddd;
322 md->rmd320.state[9] += eee;
323
324 return CRYPT_OK;
325 }
326
327 #ifdef LTC_CLEAN_STACK
328 static int rmd320_compress(hash_state *md, unsigned char *buf)
329 {
330 int err;
331 err = _rmd320_compress(md, buf);
332 burn_stack(sizeof(ulong32) * 27 + sizeof(int));
333 return err;
334 }
335 #endif
336
337 /**
338 Initialize the hash state
339 @param md The hash state you wish to initialize
340 @return CRYPT_OK if successful
341 */
342 int rmd320_init(hash_state * md)
343 {
344 LTC_ARGCHK(md != NULL);
345 md->rmd320.state[0] = 0x67452301UL;
346 md->rmd320.state[1] = 0xefcdab89UL;
347 md->rmd320.state[2] = 0x98badcfeUL;
348 md->rmd320.state[3] = 0x10325476UL;
349 md->rmd320.state[4] = 0xc3d2e1f0UL;
350 md->rmd320.state[5] = 0x76543210UL;
351 md->rmd320.state[6] = 0xfedcba98UL;
352 md->rmd320.state[7] = 0x89abcdefUL;
353 md->rmd320.state[8] = 0x01234567UL;
354 md->rmd320.state[9] = 0x3c2d1e0fUL;
355 md->rmd320.curlen = 0;
356 md->rmd320.length = 0;
357 return CRYPT_OK;
358 }
359
360 /**
361 Process a block of memory though the hash
362 @param md The hash state
363 @param in The data to hash
364 @param inlen The length of the data (octets)
365 @return CRYPT_OK if successful
366 */
367 HASH_PROCESS(rmd320_process, rmd320_compress, rmd320, 64)
368
369 /**
370 Terminate the hash to get the digest
371 @param md The hash state
372 @param out [out] The destination of the hash (20 bytes)
373 @return CRYPT_OK if successful
374 */
375 int rmd320_done(hash_state * md, unsigned char *out)
376 {
377 int i;
378
379 LTC_ARGCHK(md != NULL);
380 LTC_ARGCHK(out != NULL);
381
382 if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) {
383 return CRYPT_INVALID_ARG;
384 }
385
386
387 /* increase the length of the message */
388 md->rmd320.length += md->rmd320.curlen * 8;
389
390 /* append the '1' bit */
391 md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80;
392
393 /* if the length is currently above 56 bytes we append zeros
394 * then compress. Then we can fall back to padding zeros and length
395 * encoding like normal.
396 */
397 if (md->rmd320.curlen > 56) {
398 while (md->rmd320.curlen < 64) {
399 md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
400 }
401 rmd320_compress(md, md->rmd320.buf);
402 md->rmd320.curlen = 0;
403 }
404
405 /* pad upto 56 bytes of zeroes */
406 while (md->rmd320.curlen < 56) {
407 md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
408 }
409
410 /* store length */
411 STORE64L(md->rmd320.length, md->rmd320.buf+56);
412 rmd320_compress(md, md->rmd320.buf);
413
414 /* copy output */
415 for (i = 0; i < 10; i++) {
416 STORE32L(md->rmd320.state[i], out+(4*i));
417 }
418 #ifdef LTC_CLEAN_STACK
419 zeromem(md, sizeof(hash_state));
420 #endif
421 return CRYPT_OK;
422 }
423
424 /**
425 Self-test the hash
426 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
427 */
428 int rmd320_test(void)
429 {
430 #ifndef LTC_TEST
431 return CRYPT_NOP;
432 #else
433 static const struct {
434 char *msg;
435 unsigned char md[40];
436 } tests[] = {
437 { "",
438 { 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1,
439 0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25,
440 0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e,
441 0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 }
442 },
443 { "a",
444 { 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5,
445 0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57,
446 0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54,
447 0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d }
448 },
449 { "abc",
450 { 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d,
451 0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08,
452 0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74,
453 0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d }
454 },
455 { "message digest",
456 { 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68,
457 0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa,
458 0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d,
459 0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 }
460 },
461 { "abcdefghijklmnopqrstuvwxyz",
462 { 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93,
463 0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4,
464 0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed,
465 0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 }
466 },
467 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
468 { 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4,
469 0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59,
470 0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b,
471 0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac }
472 }
473 };
474 int x;
475 unsigned char buf[40];
476 hash_state md;
477
478 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
479 rmd320_init(&md);
480 rmd320_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
481 rmd320_done(&md, buf);
482 if (XMEMCMP(buf, tests[x].md, 40) != 0) {
483 #if 0
484 printf("Failed test %d\n", x);
485 #endif
486 return CRYPT_FAIL_TESTVECTOR;
487 }
488 }
489 return CRYPT_OK;
490 #endif
491 }
492
493 #endif
494
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file sha1.c
14 LTC_SHA1 code by Tom St Denis
15 */
16
17
18 #ifdef LTC_SHA1
19
20 const struct ltc_hash_descriptor sha1_desc =
21 {
22 "sha1",
23 2,
24 20,
25 64,
26
27 /* OID */
28 { 1, 3, 14, 3, 2, 26, },
29 6,
30
31 &sha1_init,
32 &sha1_process,
33 &sha1_done,
34 &sha1_test,
35 NULL
36 };
37
38 #define F0(x,y,z) (z ^ (x & (y ^ z)))
39 #define F1(x,y,z) (x ^ y ^ z)
40 #define F2(x,y,z) ((x & y) | (z & (x | y)))
41 #define F3(x,y,z) (x ^ y ^ z)
42
43 #ifdef LTC_CLEAN_STACK
44 static int _sha1_compress(hash_state *md, unsigned char *buf)
45 #else
46 static int sha1_compress(hash_state *md, unsigned char *buf)
47 #endif
48 {
49 ulong32 a,b,c,d,e,W[80],i;
50 #ifdef LTC_SMALL_CODE
51 ulong32 t;
52 #endif
53
54 /* copy the state into 512-bits into W[0..15] */
55 for (i = 0; i < 16; i++) {
56 LOAD32H(W[i], buf + (4*i));
57 }
58
59 /* copy state */
60 a = md->sha1.state[0];
61 b = md->sha1.state[1];
62 c = md->sha1.state[2];
63 d = md->sha1.state[3];
64 e = md->sha1.state[4];
65
66 /* expand it */
67 for (i = 16; i < 80; i++) {
68 W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
69 }
70
71 /* compress */
72 /* round one */
73 #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
74 #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
75 #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
76 #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
77
78 #ifdef LTC_SMALL_CODE
79
80 for (i = 0; i < 20; ) {
81 FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
82 }
83
84 for (; i < 40; ) {
85 FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
86 }
87
88 for (; i < 60; ) {
89 FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
90 }
91
92 for (; i < 80; ) {
93 FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
94 }
95
96 #else
97
98 for (i = 0; i < 20; ) {
99 FF0(a,b,c,d,e,i++);
100 FF0(e,a,b,c,d,i++);
101 FF0(d,e,a,b,c,i++);
102 FF0(c,d,e,a,b,i++);
103 FF0(b,c,d,e,a,i++);
104 }
105
106 /* round two */
107 for (; i < 40; ) {
108 FF1(a,b,c,d,e,i++);
109 FF1(e,a,b,c,d,i++);
110 FF1(d,e,a,b,c,i++);
111 FF1(c,d,e,a,b,i++);
112 FF1(b,c,d,e,a,i++);
113 }
114
115 /* round three */
116 for (; i < 60; ) {
117 FF2(a,b,c,d,e,i++);
118 FF2(e,a,b,c,d,i++);
119 FF2(d,e,a,b,c,i++);
120 FF2(c,d,e,a,b,i++);
121 FF2(b,c,d,e,a,i++);
122 }
123
124 /* round four */
125 for (; i < 80; ) {
126 FF3(a,b,c,d,e,i++);
127 FF3(e,a,b,c,d,i++);
128 FF3(d,e,a,b,c,i++);
129 FF3(c,d,e,a,b,i++);
130 FF3(b,c,d,e,a,i++);
131 }
132 #endif
133
134 #undef FF0
135 #undef FF1
136 #undef FF2
137 #undef FF3
138
139 /* store */
140 md->sha1.state[0] = md->sha1.state[0] + a;
141 md->sha1.state[1] = md->sha1.state[1] + b;
142 md->sha1.state[2] = md->sha1.state[2] + c;
143 md->sha1.state[3] = md->sha1.state[3] + d;
144 md->sha1.state[4] = md->sha1.state[4] + e;
145
146 return CRYPT_OK;
147 }
148
149 #ifdef LTC_CLEAN_STACK
150 static int sha1_compress(hash_state *md, unsigned char *buf)
151 {
152 int err;
153 err = _sha1_compress(md, buf);
154 burn_stack(sizeof(ulong32) * 87);
155 return err;
156 }
157 #endif
158
159 /**
160 Initialize the hash state
161 @param md The hash state you wish to initialize
162 @return CRYPT_OK if successful
163 */
164 int sha1_init(hash_state * md)
165 {
166 LTC_ARGCHK(md != NULL);
167 md->sha1.state[0] = 0x67452301UL;
168 md->sha1.state[1] = 0xefcdab89UL;
169 md->sha1.state[2] = 0x98badcfeUL;
170 md->sha1.state[3] = 0x10325476UL;
171 md->sha1.state[4] = 0xc3d2e1f0UL;
172 md->sha1.curlen = 0;
173 md->sha1.length = 0;
174 return CRYPT_OK;
175 }
176
177 /**
178 Process a block of memory though the hash
179 @param md The hash state
180 @param in The data to hash
181 @param inlen The length of the data (octets)
182 @return CRYPT_OK if successful
183 */
184 HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
185
186 /**
187 Terminate the hash to get the digest
188 @param md The hash state
189 @param out [out] The destination of the hash (20 bytes)
190 @return CRYPT_OK if successful
191 */
192 int sha1_done(hash_state * md, unsigned char *out)
193 {
194 int i;
195
196 LTC_ARGCHK(md != NULL);
197 LTC_ARGCHK(out != NULL);
198
199 if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
200 return CRYPT_INVALID_ARG;
201 }
202
203 /* increase the length of the message */
204 md->sha1.length += md->sha1.curlen * 8;
205
206 /* append the '1' bit */
207 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
208
209 /* if the length is currently above 56 bytes we append zeros
210 * then compress. Then we can fall back to padding zeros and length
211 * encoding like normal.
212 */
213 if (md->sha1.curlen > 56) {
214 while (md->sha1.curlen < 64) {
215 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
216 }
217 sha1_compress(md, md->sha1.buf);
218 md->sha1.curlen = 0;
219 }
220
221 /* pad upto 56 bytes of zeroes */
222 while (md->sha1.curlen < 56) {
223 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
224 }
225
226 /* store length */
227 STORE64H(md->sha1.length, md->sha1.buf+56);
228 sha1_compress(md, md->sha1.buf);
229
230 /* copy output */
231 for (i = 0; i < 5; i++) {
232 STORE32H(md->sha1.state[i], out+(4*i));
233 }
234 #ifdef LTC_CLEAN_STACK
235 zeromem(md, sizeof(hash_state));
236 #endif
237 return CRYPT_OK;
238 }
239
240 /**
241 Self-test the hash
242 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
243 */
244 int sha1_test(void)
245 {
246 #ifndef LTC_TEST
247 return CRYPT_NOP;
248 #else
249 static const struct {
250 char *msg;
251 unsigned char hash[20];
252 } tests[] = {
253 { "abc",
254 { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
255 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
256 0x9c, 0xd0, 0xd8, 0x9d }
257 },
258 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
259 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
260 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
261 0xE5, 0x46, 0x70, 0xF1 }
262 }
263 };
264
265 int i;
266 unsigned char tmp[20];
267 hash_state md;
268
269 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
270 sha1_init(&md);
271 sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
272 sha1_done(&md, tmp);
273 if (XMEMCMP(tmp, tests[i].hash, 20) != 0) {
274 return CRYPT_FAIL_TESTVECTOR;
275 }
276 }
277 return CRYPT_OK;
278 #endif
279 }
280
281 #endif
282
283
284
285 /* $Source$ */
286 /* $Revision$ */
287 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @param sha224.c
12 LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis)
13 */
14
15 const struct ltc_hash_descriptor sha224_desc =
16 {
17 "sha224",
18 10,
19 28,
20 64,
21
22 /* OID */
23 { 2, 16, 840, 1, 101, 3, 4, 2, 4, },
24 9,
25
26 &sha224_init,
27 &sha256_process,
28 &sha224_done,
29 &sha224_test,
30 NULL
31 };
32
33 /* init the sha256 er... sha224 state ;-) */
34 /**
35 Initialize the hash state
36 @param md The hash state you wish to initialize
37 @return CRYPT_OK if successful
38 */
39 int sha224_init(hash_state * md)
40 {
41 LTC_ARGCHK(md != NULL);
42
43 md->sha256.curlen = 0;
44 md->sha256.length = 0;
45 md->sha256.state[0] = 0xc1059ed8UL;
46 md->sha256.state[1] = 0x367cd507UL;
47 md->sha256.state[2] = 0x3070dd17UL;
48 md->sha256.state[3] = 0xf70e5939UL;
49 md->sha256.state[4] = 0xffc00b31UL;
50 md->sha256.state[5] = 0x68581511UL;
51 md->sha256.state[6] = 0x64f98fa7UL;
52 md->sha256.state[7] = 0xbefa4fa4UL;
53 return CRYPT_OK;
54 }
55
56 /**
57 Terminate the hash to get the digest
58 @param md The hash state
59 @param out [out] The destination of the hash (28 bytes)
60 @return CRYPT_OK if successful
61 */
62 int sha224_done(hash_state * md, unsigned char *out)
63 {
64 unsigned char buf[32];
65 int err;
66
67 LTC_ARGCHK(md != NULL);
68 LTC_ARGCHK(out != NULL);
69
70 err = sha256_done(md, buf);
71 XMEMCPY(out, buf, 28);
72 #ifdef LTC_CLEAN_STACK
73 zeromem(buf, sizeof(buf));
74 #endif
75 return err;
76 }
77
78 /**
79 Self-test the hash
80 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
81 */
82 int sha224_test(void)
83 {
84 #ifndef LTC_TEST
85 return CRYPT_NOP;
86 #else
87 static const struct {
88 char *msg;
89 unsigned char hash[28];
90 } tests[] = {
91 { "abc",
92 { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8,
93 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2,
94 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd,
95 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 }
96 },
97 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
98 { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
99 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
100 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
101 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
102 },
103 };
104
105 int i;
106 unsigned char tmp[28];
107 hash_state md;
108
109 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
110 sha224_init(&md);
111 sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
112 sha224_done(&md, tmp);
113 if (XMEMCMP(tmp, tests[i].hash, 28) != 0) {
114 return CRYPT_FAIL_TESTVECTOR;
115 }
116 }
117 return CRYPT_OK;
118 #endif
119 }
120
121
122 /* $Source$ */
123 /* $Revision$ */
124 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file sha256.c
14 LTC_SHA256 by Tom St Denis
15 */
16
17 #ifdef LTC_SHA256
18
19 const struct ltc_hash_descriptor sha256_desc =
20 {
21 "sha256",
22 0,
23 32,
24 64,
25
26 /* OID */
27 { 2, 16, 840, 1, 101, 3, 4, 2, 1, },
28 9,
29
30 &sha256_init,
31 &sha256_process,
32 &sha256_done,
33 &sha256_test,
34 NULL
35 };
36
37 #ifdef LTC_SMALL_CODE
38 /* the K array */
39 static const ulong32 K[64] = {
40 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
41 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
42 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
43 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
44 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
45 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
46 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
47 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
48 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
49 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
50 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
51 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
52 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
53 };
54 #endif
55
56 /* Various logical functions */
57 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
58 #define Maj(x,y,z) (((x | y) & z) | (x & y))
59 #define S(x, n) RORc((x),(n))
60 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
61 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
62 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
63 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
64 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
65
66 /* compress 512-bits */
67 #ifdef LTC_CLEAN_STACK
68 static int _sha256_compress(hash_state * md, unsigned char *buf)
69 #else
70 static int sha256_compress(hash_state * md, unsigned char *buf)
71 #endif
72 {
73 ulong32 S[8], W[64], t0, t1;
74 #ifdef LTC_SMALL_CODE
75 ulong32 t;
76 #endif
77 int i;
78
79 /* copy state into S */
80 for (i = 0; i < 8; i++) {
81 S[i] = md->sha256.state[i];
82 }
83
84 /* copy the state into 512-bits into W[0..15] */
85 for (i = 0; i < 16; i++) {
86 LOAD32H(W[i], buf + (4*i));
87 }
88
89 /* fill W[16..63] */
90 for (i = 16; i < 64; i++) {
91 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
92 }
93
94 /* Compress */
95 #ifdef LTC_SMALL_CODE
96 #define RND(a,b,c,d,e,f,g,h,i) \
97 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
98 t1 = Sigma0(a) + Maj(a, b, c); \
99 d += t0; \
100 h = t0 + t1;
101
102 for (i = 0; i < 64; ++i) {
103 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
104 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
105 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
106 }
107 #else
108 #define RND(a,b,c,d,e,f,g,h,i,ki) \
109 t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
110 t1 = Sigma0(a) + Maj(a, b, c); \
111 d += t0; \
112 h = t0 + t1;
113
114 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
115 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
116 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
117 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
118 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
119 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
120 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
121 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
122 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
123 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
124 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
125 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
126 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
127 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
128 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
129 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
130 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
131 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
132 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
133 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
134 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
135 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
136 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
137 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
138 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
139 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
140 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
141 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
142 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
143 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
144 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
145 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
146 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
147 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
148 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
149 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
150 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
151 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
152 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
153 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
154 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
155 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
156 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
157 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
158 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
159 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
160 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
161 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
162 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
163 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
164 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
165 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
166 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
167 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
168 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
169 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
170 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
171 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
172 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
173 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
174 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
175 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
176 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
177 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
178
179 #undef RND
180
181 #endif
182
183 /* feedback */
184 for (i = 0; i < 8; i++) {
185 md->sha256.state[i] = md->sha256.state[i] + S[i];
186 }
187 return CRYPT_OK;
188 }
189
190 #ifdef LTC_CLEAN_STACK
191 static int sha256_compress(hash_state * md, unsigned char *buf)
192 {
193 int err;
194 err = _sha256_compress(md, buf);
195 burn_stack(sizeof(ulong32) * 74);
196 return err;
197 }
198 #endif
199
200 /**
201 Initialize the hash state
202 @param md The hash state you wish to initialize
203 @return CRYPT_OK if successful
204 */
205 int sha256_init(hash_state * md)
206 {
207 LTC_ARGCHK(md != NULL);
208
209 md->sha256.curlen = 0;
210 md->sha256.length = 0;
211 md->sha256.state[0] = 0x6A09E667UL;
212 md->sha256.state[1] = 0xBB67AE85UL;
213 md->sha256.state[2] = 0x3C6EF372UL;
214 md->sha256.state[3] = 0xA54FF53AUL;
215 md->sha256.state[4] = 0x510E527FUL;
216 md->sha256.state[5] = 0x9B05688CUL;
217 md->sha256.state[6] = 0x1F83D9ABUL;
218 md->sha256.state[7] = 0x5BE0CD19UL;
219 return CRYPT_OK;
220 }
221
222 /**
223 Process a block of memory though the hash
224 @param md The hash state
225 @param in The data to hash
226 @param inlen The length of the data (octets)
227 @return CRYPT_OK if successful
228 */
229 HASH_PROCESS(sha256_process, sha256_compress, sha256, 64)
230
231 /**
232 Terminate the hash to get the digest
233 @param md The hash state
234 @param out [out] The destination of the hash (32 bytes)
235 @return CRYPT_OK if successful
236 */
237 int sha256_done(hash_state * md, unsigned char *out)
238 {
239 int i;
240
241 LTC_ARGCHK(md != NULL);
242 LTC_ARGCHK(out != NULL);
243
244 if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
245 return CRYPT_INVALID_ARG;
246 }
247
248
249 /* increase the length of the message */
250 md->sha256.length += md->sha256.curlen * 8;
251
252 /* append the '1' bit */
253 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
254
255 /* if the length is currently above 56 bytes we append zeros
256 * then compress. Then we can fall back to padding zeros and length
257 * encoding like normal.
258 */
259 if (md->sha256.curlen > 56) {
260 while (md->sha256.curlen < 64) {
261 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
262 }
263 sha256_compress(md, md->sha256.buf);
264 md->sha256.curlen = 0;
265 }
266
267 /* pad upto 56 bytes of zeroes */
268 while (md->sha256.curlen < 56) {
269 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
270 }
271
272 /* store length */
273 STORE64H(md->sha256.length, md->sha256.buf+56);
274 sha256_compress(md, md->sha256.buf);
275
276 /* copy output */
277 for (i = 0; i < 8; i++) {
278 STORE32H(md->sha256.state[i], out+(4*i));
279 }
280 #ifdef LTC_CLEAN_STACK
281 zeromem(md, sizeof(hash_state));
282 #endif
283 return CRYPT_OK;
284 }
285
286 /**
287 Self-test the hash
288 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
289 */
290 int sha256_test(void)
291 {
292 #ifndef LTC_TEST
293 return CRYPT_NOP;
294 #else
295 static const struct {
296 char *msg;
297 unsigned char hash[32];
298 } tests[] = {
299 { "abc",
300 { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
301 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
302 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
303 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
304 },
305 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
306 { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
307 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
308 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
309 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
310 },
311 };
312
313 int i;
314 unsigned char tmp[32];
315 hash_state md;
316
317 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
318 sha256_init(&md);
319 sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
320 sha256_done(&md, tmp);
321 if (XMEMCMP(tmp, tests[i].hash, 32) != 0) {
322 return CRYPT_FAIL_TESTVECTOR;
323 }
324 }
325 return CRYPT_OK;
326 #endif
327 }
328
329 #ifdef LTC_SHA224
330 #include "sha224.c.inc"
331 #endif
332
333 #endif
334
335
336
337 /* $Source$ */
338 /* $Revision$ */
339 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 /**
11 @param sha384.c
12 LTC_SHA384 hash included in sha512.c, Tom St Denis
13 */
14
15 const struct ltc_hash_descriptor sha384_desc =
16 {
17 "sha384",
18 4,
19 48,
20 128,
21
22 /* OID */
23 { 2, 16, 840, 1, 101, 3, 4, 2, 2, },
24 9,
25
26 &sha384_init,
27 &sha512_process,
28 &sha384_done,
29 &sha384_test,
30 NULL
31 };
32
33 /**
34 Initialize the hash state
35 @param md The hash state you wish to initialize
36 @return CRYPT_OK if successful
37 */
38 int sha384_init(hash_state * md)
39 {
40 LTC_ARGCHK(md != NULL);
41
42 md->sha512.curlen = 0;
43 md->sha512.length = 0;
44 md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8);
45 md->sha512.state[1] = CONST64(0x629a292a367cd507);
46 md->sha512.state[2] = CONST64(0x9159015a3070dd17);
47 md->sha512.state[3] = CONST64(0x152fecd8f70e5939);
48 md->sha512.state[4] = CONST64(0x67332667ffc00b31);
49 md->sha512.state[5] = CONST64(0x8eb44a8768581511);
50 md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7);
51 md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4);
52 return CRYPT_OK;
53 }
54
55 /**
56 Terminate the hash to get the digest
57 @param md The hash state
58 @param out [out] The destination of the hash (48 bytes)
59 @return CRYPT_OK if successful
60 */
61 int sha384_done(hash_state * md, unsigned char *out)
62 {
63 unsigned char buf[64];
64
65 LTC_ARGCHK(md != NULL);
66 LTC_ARGCHK(out != NULL);
67
68 if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
69 return CRYPT_INVALID_ARG;
70 }
71
72 sha512_done(md, buf);
73 XMEMCPY(out, buf, 48);
74 #ifdef LTC_CLEAN_STACK
75 zeromem(buf, sizeof(buf));
76 #endif
77 return CRYPT_OK;
78 }
79
80 /**
81 Self-test the hash
82 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
83 */
84 int sha384_test(void)
85 {
86 #ifndef LTC_TEST
87 return CRYPT_NOP;
88 #else
89 static const struct {
90 char *msg;
91 unsigned char hash[48];
92 } tests[] = {
93 { "abc",
94 { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
95 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
96 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
97 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
98 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
99 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
100 },
101 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
102 { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
103 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
104 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
105 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
106 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
107 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }
108 },
109 };
110
111 int i;
112 unsigned char tmp[48];
113 hash_state md;
114
115 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
116 sha384_init(&md);
117 sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
118 sha384_done(&md, tmp);
119 if (XMEMCMP(tmp, tests[i].hash, 48) != 0) {
120 return CRYPT_FAIL_TESTVECTOR;
121 }
122 }
123 return CRYPT_OK;
124 #endif
125 }
126
127
128
129
130
131
132 /* $Source$ */
133 /* $Revision$ */
134 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @param sha512.c
14 LTC_SHA512 by Tom St Denis
15 */
16
17 #ifdef LTC_SHA512
18
19 const struct ltc_hash_descriptor sha512_desc =
20 {
21 "sha512",
22 5,
23 64,
24 128,
25
26 /* OID */
27 { 2, 16, 840, 1, 101, 3, 4, 2, 3, },
28 9,
29
30 &sha512_init,
31 &sha512_process,
32 &sha512_done,
33 &sha512_test,
34 NULL
35 };
36
37 /* the K array */
38 static const ulong64 K[80] = {
39 CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
40 CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
41 CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
42 CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
43 CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
44 CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
45 CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
46 CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
47 CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
48 CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
49 CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
50 CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
51 CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
52 CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
53 CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
54 CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
55 CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
56 CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
57 CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
58 CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
59 CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
60 CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
61 CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
62 CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
63 CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
64 CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
65 CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
66 CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
67 CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
68 CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
69 CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
70 CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
71 CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
72 CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
73 CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
74 CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
75 CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
76 CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
77 CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
78 CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
79 };
80
81 /* Various logical functions */
82 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
83 #define Maj(x,y,z) (((x | y) & z) | (x & y))
84 #define S(x, n) ROR64c(x, n)
85 #define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
86 #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
87 #define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
88 #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
89 #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
90
91 /* compress 1024-bits */
92 #ifdef LTC_CLEAN_STACK
93 static int _sha512_compress(hash_state * md, unsigned char *buf)
94 #else
95 static int sha512_compress(hash_state * md, unsigned char *buf)
96 #endif
97 {
98 ulong64 S[8], W[80], t0, t1;
99 int i;
100
101 /* copy state into S */
102 for (i = 0; i < 8; i++) {
103 S[i] = md->sha512.state[i];
104 }
105
106 /* copy the state into 1024-bits into W[0..15] */
107 for (i = 0; i < 16; i++) {
108 LOAD64H(W[i], buf + (8*i));
109 }
110
111 /* fill W[16..79] */
112 for (i = 16; i < 80; i++) {
113 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
114 }
115
116 /* Compress */
117 #ifdef LTC_SMALL_CODE
118 for (i = 0; i < 80; i++) {
119 t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
120 t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
121 S[7] = S[6];
122 S[6] = S[5];
123 S[5] = S[4];
124 S[4] = S[3] + t0;
125 S[3] = S[2];
126 S[2] = S[1];
127 S[1] = S[0];
128 S[0] = t0 + t1;
129 }
130 #else
131 #define RND(a,b,c,d,e,f,g,h,i) \
132 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
133 t1 = Sigma0(a) + Maj(a, b, c); \
134 d += t0; \
135 h = t0 + t1;
136
137 for (i = 0; i < 80; i += 8) {
138 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
139 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
140 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
141 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
142 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
143 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
144 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
145 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
146 }
147 #endif
148
149
150 /* feedback */
151 for (i = 0; i < 8; i++) {
152 md->sha512.state[i] = md->sha512.state[i] + S[i];
153 }
154
155 return CRYPT_OK;
156 }
157
158 /* compress 1024-bits */
159 #ifdef LTC_CLEAN_STACK
160 static int sha512_compress(hash_state * md, unsigned char *buf)
161 {
162 int err;
163 err = _sha512_compress(md, buf);
164 burn_stack(sizeof(ulong64) * 90 + sizeof(int));
165 return err;
166 }
167 #endif
168
169 /**
170 Initialize the hash state
171 @param md The hash state you wish to initialize
172 @return CRYPT_OK if successful
173 */
174 int sha512_init(hash_state * md)
175 {
176 LTC_ARGCHK(md != NULL);
177 md->sha512.curlen = 0;
178 md->sha512.length = 0;
179 md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
180 md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
181 md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
182 md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
183 md->sha512.state[4] = CONST64(0x510e527fade682d1);
184 md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
185 md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
186 md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
187 return CRYPT_OK;
188 }
189
190 /**
191 Process a block of memory though the hash
192 @param md The hash state
193 @param in The data to hash
194 @param inlen The length of the data (octets)
195 @return CRYPT_OK if successful
196 */
197 HASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
198
199 /**
200 Terminate the hash to get the digest
201 @param md The hash state
202 @param out [out] The destination of the hash (64 bytes)
203 @return CRYPT_OK if successful
204 */
205 int sha512_done(hash_state * md, unsigned char *out)
206 {
207 int i;
208
209 LTC_ARGCHK(md != NULL);
210 LTC_ARGCHK(out != NULL);
211
212 if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
213 return CRYPT_INVALID_ARG;
214 }
215
216 /* increase the length of the message */
217 md->sha512.length += md->sha512.curlen * CONST64(8);
218
219 /* append the '1' bit */
220 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
221
222 /* if the length is currently above 112 bytes we append zeros
223 * then compress. Then we can fall back to padding zeros and length
224 * encoding like normal.
225 */
226 if (md->sha512.curlen > 112) {
227 while (md->sha512.curlen < 128) {
228 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
229 }
230 sha512_compress(md, md->sha512.buf);
231 md->sha512.curlen = 0;
232 }
233
234 /* pad upto 120 bytes of zeroes
235 * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
236 * > 2^64 bits of data... :-)
237 */
238 while (md->sha512.curlen < 120) {
239 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
240 }
241
242 /* store length */
243 STORE64H(md->sha512.length, md->sha512.buf+120);
244 sha512_compress(md, md->sha512.buf);
245
246 /* copy output */
247 for (i = 0; i < 8; i++) {
248 STORE64H(md->sha512.state[i], out+(8*i));
249 }
250 #ifdef LTC_CLEAN_STACK
251 zeromem(md, sizeof(hash_state));
252 #endif
253 return CRYPT_OK;
254 }
255
256 /**
257 Self-test the hash
258 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
259 */
260 int sha512_test(void)
261 {
262 #ifndef LTC_TEST
263 return CRYPT_NOP;
264 #else
265 static const struct {
266 char *msg;
267 unsigned char hash[64];
268 } tests[] = {
269 { "abc",
270 { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
271 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
272 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
273 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
274 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
275 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
276 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
277 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
278 },
279 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
280 { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
281 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
282 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
283 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
284 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
285 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
286 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
287 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
288 },
289 };
290
291 int i;
292 unsigned char tmp[64];
293 hash_state md;
294
295 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
296 sha512_init(&md);
297 sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
298 sha512_done(&md, tmp);
299 if (XMEMCMP(tmp, tests[i].hash, 64) != 0) {
300 return CRYPT_FAIL_TESTVECTOR;
301 }
302 }
303 return CRYPT_OK;
304 #endif
305 }
306
307 #ifdef LTC_SHA384
308 #include "sha384.c.inc"
309 #endif
310
311 #endif
312
313
314
315
316 /* $Source$ */
317 /* $Revision$ */
318 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #include "tomcrypt.h"
12
13 /**
14 @file tiger.c
15 Tiger hash function, Tom St Denis
16 */
17
18 #ifdef LTC_TIGER
19
20 const struct ltc_hash_descriptor tiger_desc =
21 {
22 "tiger",
23 1,
24 24,
25 64,
26
27 /* OID */
28 { 1, 3, 6, 1, 4, 1, 11591, 12, 2, },
29 9,
30
31 &tiger_init,
32 &tiger_process,
33 &tiger_done,
34 &tiger_test,
35 NULL
36 };
37
38 #define t1 (table)
39 #define t2 (table+256)
40 #define t3 (table+256*2)
41 #define t4 (table+256*3)
42
43 static const ulong64 table[4*256] = {
44 CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */,
45 CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */,
46 CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */,
47 CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */,
48 CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */,
49 CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */,
50 CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */,
51 CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */,
52 CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */,
53 CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */,
54 CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */,
55 CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */,
56 CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */,
57 CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */,
58 CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */,
59 CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */,
60 CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */,
61 CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */,
62 CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */,
63 CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */,
64 CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */,
65 CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */,
66 CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */,
67 CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */,
68 CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */,
69 CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */,
70 CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */,
71 CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */,
72 CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */,
73 CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */,
74 CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */,
75 CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */,
76 CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */,
77 CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */,
78 CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */,
79 CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */,
80 CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */,
81 CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */,
82 CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */,
83 CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */,
84 CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */,
85 CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */,
86 CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */,
87 CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */,
88 CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */,
89 CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */,
90 CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */,
91 CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */,
92 CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */,
93 CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */,
94 CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */,
95 CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */,
96 CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */,
97 CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */,
98 CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */,
99 CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */,
100 CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */,
101 CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */,
102 CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */,
103 CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */,
104 CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */,
105 CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */,
106 CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */,
107 CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */,
108 CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */,
109 CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */,
110 CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */,
111 CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */,
112 CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */,
113 CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */,
114 CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */,
115 CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */,
116 CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */,
117 CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */,
118 CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */,
119 CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */,
120 CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */,
121 CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */,
122 CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */,
123 CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */,
124 CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */,
125 CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */,
126 CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */,
127 CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */,
128 CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */,
129 CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */,
130 CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */,
131 CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */,
132 CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */,
133 CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */,
134 CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */,
135 CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */,
136 CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */,
137 CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */,
138 CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */,
139 CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */,
140 CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */,
141 CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */,
142 CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */,
143 CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */,
144 CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */,
145 CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */,
146 CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */,
147 CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */,
148 CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */,
149 CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */,
150 CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */,
151 CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */,
152 CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */,
153 CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */,
154 CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */,
155 CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */,
156 CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */,
157 CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */,
158 CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */,
159 CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */,
160 CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */,
161 CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */,
162 CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */,
163 CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */,
164 CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */,
165 CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */,
166 CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */,
167 CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */,
168 CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */,
169 CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */,
170 CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */,
171 CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */,
172 CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */,
173 CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */,
174 CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */,
175 CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */,
176 CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */,
177 CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */,
178 CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */,
179 CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */,
180 CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */,
181 CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */,
182 CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */,
183 CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */,
184 CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */,
185 CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */,
186 CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */,
187 CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */,
188 CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */,
189 CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */,
190 CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */,
191 CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */,
192 CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */,
193 CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */,
194 CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */,
195 CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */,
196 CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */,
197 CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */,
198 CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */,
199 CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */,
200 CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */,
201 CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */,
202 CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */,
203 CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */,
204 CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */,
205 CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */,
206 CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */,
207 CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */,
208 CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */,
209 CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */,
210 CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */,
211 CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */,
212 CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */,
213 CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */,
214 CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */,
215 CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */,
216 CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */,
217 CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */,
218 CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */,
219 CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */,
220 CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */,
221 CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */,
222 CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */,
223 CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */,
224 CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */,
225 CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */,
226 CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */,
227 CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */,
228 CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */,
229 CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */,
230 CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */,
231 CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */,
232 CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */,
233 CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */,
234 CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */,
235 CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */,
236 CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */,
237 CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */,
238 CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */,
239 CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */,
240 CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */,
241 CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */,
242 CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */,
243 CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */,
244 CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */,
245 CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */,
246 CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */,
247 CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */,
248 CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */,
249 CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */,
250 CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */,
251 CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */,
252 CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */,
253 CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */,
254 CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */,
255 CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */,
256 CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */,
257 CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */,
258 CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */,
259 CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */,
260 CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */,
261 CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */,
262 CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */,
263 CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */,
264 CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */,
265 CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */,
266 CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */,
267 CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */,
268 CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */,
269 CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */,
270 CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */,
271 CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */,
272 CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */,
273 CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */,
274 CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */,
275 CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */,
276 CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */,
277 CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */,
278 CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */,
279 CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */,
280 CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */,
281 CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */,
282 CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */,
283 CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */,
284 CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */,
285 CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */,
286 CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */,
287 CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */,
288 CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */,
289 CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */,
290 CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */,
291 CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */,
292 CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */,
293 CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */,
294 CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */,
295 CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */,
296 CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */,
297 CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */,
298 CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */,
299 CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */,
300 CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */,
301 CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */,
302 CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */,
303 CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */,
304 CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */,
305 CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */,
306 CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */,
307 CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */,
308 CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */,
309 CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */,
310 CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */,
311 CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */,
312 CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */,
313 CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */,
314 CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */,
315 CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */,
316 CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */,
317 CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */,
318 CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */,
319 CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */,
320 CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */,
321 CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */,
322 CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */,
323 CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */,
324 CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */,
325 CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */,
326 CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */,
327 CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */,
328 CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */,
329 CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */,
330 CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */,
331 CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */,
332 CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */,
333 CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */,
334 CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */,
335 CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */,
336 CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */,
337 CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */,
338 CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */,
339 CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */,
340 CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */,
341 CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */,
342 CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */,
343 CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */,
344 CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */,
345 CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */,
346 CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */,
347 CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */,
348 CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */,
349 CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */,
350 CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */,
351 CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */,
352 CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */,
353 CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */,
354 CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */,
355 CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */,
356 CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */,
357 CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */,
358 CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */,
359 CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */,
360 CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */,
361 CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */,
362 CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */,
363 CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */,
364 CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */,
365 CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */,
366 CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */,
367 CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */,
368 CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */,
369 CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */,
370 CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */,
371 CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */,
372 CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */,
373 CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */,
374 CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */,
375 CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */,
376 CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */,
377 CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */,
378 CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */,
379 CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */,
380 CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */,
381 CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */,
382 CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */,
383 CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */,
384 CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */,
385 CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */,
386 CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */,
387 CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */,
388 CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */,
389 CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */,
390 CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */,
391 CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */,
392 CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */,
393 CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */,
394 CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */,
395 CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */,
396 CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */,
397 CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */,
398 CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */,
399 CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */,
400 CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */,
401 CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */,
402 CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */,
403 CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */,
404 CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */,
405 CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */,
406 CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */,
407 CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */,
408 CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */,
409 CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */,
410 CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */,
411 CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */,
412 CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */,
413 CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */,
414 CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */,
415 CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */,
416 CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */,
417 CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */,
418 CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */,
419 CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */,
420 CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */,
421 CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */,
422 CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */,
423 CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */,
424 CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */,
425 CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */,
426 CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */,
427 CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */,
428 CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */,
429 CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */,
430 CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */,
431 CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */,
432 CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */,
433 CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */,
434 CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */,
435 CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */,
436 CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */,
437 CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */,
438 CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */,
439 CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */,
440 CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */,
441 CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */,
442 CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */,
443 CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */,
444 CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */,
445 CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */,
446 CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */,
447 CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */,
448 CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */,
449 CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */,
450 CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */,
451 CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */,
452 CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */,
453 CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */,
454 CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */,
455 CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */,
456 CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */,
457 CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */,
458 CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */,
459 CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */,
460 CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */,
461 CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */,
462 CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */,
463 CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */,
464 CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */,
465 CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */,
466 CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */,
467 CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */,
468 CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */,
469 CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */,
470 CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */,
471 CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */,
472 CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */,
473 CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */,
474 CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */,
475 CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */,
476 CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */,
477 CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */,
478 CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */,
479 CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */,
480 CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */,
481 CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */,
482 CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */,
483 CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */,
484 CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */,
485 CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */,
486 CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */,
487 CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */,
488 CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */,
489 CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */,
490 CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */,
491 CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */,
492 CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */,
493 CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */,
494 CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */,
495 CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */,
496 CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */,
497 CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */,
498 CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */,
499 CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */,
500 CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */,
501 CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */,
502 CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */,
503 CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */,
504 CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */,
505 CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */,
506 CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */,
507 CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */,
508 CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */,
509 CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */,
510 CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */,
511 CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */,
512 CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */,
513 CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */,
514 CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */,
515 CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */,
516 CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */,
517 CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */,
518 CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */,
519 CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */,
520 CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */,
521 CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */,
522 CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */,
523 CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */,
524 CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */,
525 CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */,
526 CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */,
527 CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */,
528 CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */,
529 CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */,
530 CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */,
531 CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */,
532 CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */,
533 CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */,
534 CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */,
535 CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */,
536 CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */,
537 CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */,
538 CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */,
539 CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */,
540 CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */,
541 CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */,
542 CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */,
543 CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */,
544 CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */,
545 CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */,
546 CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */,
547 CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */,
548 CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */,
549 CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */,
550 CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */,
551 CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */,
552 CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */,
553 CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */,
554 CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */,
555 CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */};
556
557 #ifdef _MSC_VER
558 #define INLINE __inline
559 #else
560 #define INLINE
561 #endif
562
563 /* one round of the hash function */
564 INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul)
565 {
566 ulong64 tmp;
567 tmp = (*c ^= x);
568 *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)];
569 tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]);
570 switch (mul) {
571 case 5: *b = (tmp << 2) + tmp; break;
572 case 7: *b = (tmp << 3) - tmp; break;
573 case 9: *b = (tmp << 3) + tmp; break;
574 }
575 }
576
577 /* one complete pass */
578 static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul)
579 {
580 tiger_round(a,b,c,x[0],mul);
581 tiger_round(b,c,a,x[1],mul);
582 tiger_round(c,a,b,x[2],mul);
583 tiger_round(a,b,c,x[3],mul);
584 tiger_round(b,c,a,x[4],mul);
585 tiger_round(c,a,b,x[5],mul);
586 tiger_round(a,b,c,x[6],mul);
587 tiger_round(b,c,a,x[7],mul);
588 }
589
590 /* The key mixing schedule */
591 static void key_schedule(ulong64 *x)
592 {
593 x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5);
594 x[1] ^= x[0];
595 x[2] += x[1];
596 x[3] -= x[2] ^ ((~x[1])<<19);
597 x[4] ^= x[3];
598 x[5] += x[4];
599 x[6] -= x[5] ^ ((~x[4])>>23);
600 x[7] ^= x[6];
601 x[0] += x[7];
602 x[1] -= x[0] ^ ((~x[7])<<19);
603 x[2] ^= x[1];
604 x[3] += x[2];
605 x[4] -= x[3] ^ ((~x[2])>>23);
606 x[5] ^= x[4];
607 x[6] += x[5];
608 x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF);
609 }
610
611 #ifdef LTC_CLEAN_STACK
612 static int _tiger_compress(hash_state *md, unsigned char *buf)
613 #else
614 static int tiger_compress(hash_state *md, unsigned char *buf)
615 #endif
616 {
617 ulong64 a, b, c, x[8];
618 unsigned long i;
619
620 /* load words */
621 for (i = 0; i < 8; i++) {
622 LOAD64L(x[i],&buf[8*i]);
623 }
624 a = md->tiger.state[0];
625 b = md->tiger.state[1];
626 c = md->tiger.state[2];
627
628 pass(&a,&b,&c,x,5);
629 key_schedule(x);
630 pass(&c,&a,&b,x,7);
631 key_schedule(x);
632 pass(&b,&c,&a,x,9);
633
634 /* store state */
635 md->tiger.state[0] = a ^ md->tiger.state[0];
636 md->tiger.state[1] = b - md->tiger.state[1];
637 md->tiger.state[2] = c + md->tiger.state[2];
638
639 return CRYPT_OK;
640 }
641
642 #ifdef LTC_CLEAN_STACK
643 static int tiger_compress(hash_state *md, unsigned char *buf)
644 {
645 int err;
646 err = _tiger_compress(md, buf);
647 burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long));
648 return err;
649 }
650 #endif
651
652 /**
653 Initialize the hash state
654 @param md The hash state you wish to initialize
655 @return CRYPT_OK if successful
656 */
657 int tiger_init(hash_state *md)
658 {
659 LTC_ARGCHK(md != NULL);
660 md->tiger.state[0] = CONST64(0x0123456789ABCDEF);
661 md->tiger.state[1] = CONST64(0xFEDCBA9876543210);
662 md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187);
663 md->tiger.curlen = 0;
664 md->tiger.length = 0;
665 return CRYPT_OK;
666 }
667
668 /**
669 Process a block of memory though the hash
670 @param md The hash state
671 @param in The data to hash
672 @param inlen The length of the data (octets)
673 @return CRYPT_OK if successful
674 */
675 HASH_PROCESS(tiger_process, tiger_compress, tiger, 64)
676
677 /**
678 Terminate the hash to get the digest
679 @param md The hash state
680 @param out [out] The destination of the hash (24 bytes)
681 @return CRYPT_OK if successful
682 */
683 int tiger_done(hash_state * md, unsigned char *out)
684 {
685 LTC_ARGCHK(md != NULL);
686 LTC_ARGCHK(out != NULL);
687
688 if (md->tiger.curlen >= sizeof(md->tiger.buf)) {
689 return CRYPT_INVALID_ARG;
690 }
691
692 /* increase the length of the message */
693 md->tiger.length += md->tiger.curlen * 8;
694
695 /* append the '1' bit */
696 md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01;
697
698 /* if the length is currently above 56 bytes we append zeros
699 * then compress. Then we can fall back to padding zeros and length
700 * encoding like normal. */
701 if (md->tiger.curlen > 56) {
702 while (md->tiger.curlen < 64) {
703 md->tiger.buf[md->tiger.curlen++] = (unsigned char)0;
704 }
705 tiger_compress(md, md->tiger.buf);
706 md->tiger.curlen = 0;
707 }
708
709 /* pad upto 56 bytes of zeroes */
710 while (md->tiger.curlen < 56) {
711 md->tiger.buf[md->tiger.curlen++] = (unsigned char)0;
712 }
713
714 /* store length */
715 STORE64L(md->tiger.length, md->tiger.buf+56);
716 tiger_compress(md, md->tiger.buf);
717
718 /* copy output */
719 STORE64L(md->tiger.state[0], &out[0]);
720 STORE64L(md->tiger.state[1], &out[8]);
721 STORE64L(md->tiger.state[2], &out[16]);
722 #ifdef LTC_CLEAN_STACK
723 zeromem(md, sizeof(hash_state));
724 #endif
725
726 return CRYPT_OK;
727 }
728
729 /**
730 Self-test the hash
731 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
732 */
733 int tiger_test(void)
734 {
735 #ifndef LTC_TEST
736 return CRYPT_NOP;
737 #else
738 static const struct {
739 char *msg;
740 unsigned char hash[24];
741 } tests[] = {
742 { "",
743 { 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24,
744 0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16,
745 0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 }
746 },
747 { "abc",
748 { 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2,
749 0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52,
750 0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 }
751 },
752 { "Tiger",
753 { 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f,
754 0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27,
755 0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 }
756 },
757 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
758 { 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87,
759 0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47,
760 0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 }
761 },
762 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
763 { 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00,
764 0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76,
765 0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 }
766 },
767 };
768
769 int i;
770 unsigned char tmp[24];
771 hash_state md;
772
773 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
774 tiger_init(&md);
775 tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
776 tiger_done(&md, tmp);
777 if (XMEMCMP(tmp, tests[i].hash, 24) != 0) {
778 return CRYPT_FAIL_TESTVECTOR;
779 }
780 }
781 return CRYPT_OK;
782 #endif
783 }
784
785 #endif
786
787 /*
788 Hash of "":
789 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
790 Hash of "abc":
791 F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
792 Hash of "Tiger":
793 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
794 Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
795 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
796 Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789":
797 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
798 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham":
799 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
800 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.":
801 EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
802 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.":
803 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
804 Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
805 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
806 */
807
808
809
810
811 /* $Source$ */
812 /* $Revision$ */
813 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /**
12 @file whirl.c
13 LTC_WHIRLPOOL (using their new sbox) hash function by Tom St Denis
14 */
15
16 #include "tomcrypt.h"
17
18 #ifdef LTC_WHIRLPOOL
19
20 const struct ltc_hash_descriptor whirlpool_desc =
21 {
22 "whirlpool",
23 11,
24 64,
25 64,
26
27 /* OID */
28 { 1, 0, 10118, 3, 0, 55 },
29 6,
30
31 &whirlpool_init,
32 &whirlpool_process,
33 &whirlpool_done,
34 &whirlpool_test,
35 NULL
36 };
37
38 /* the sboxes */
39 #include "whirltab.c.inc"
40
41 /* get a_{i,j} */
42 #define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
43
44 /* shortcut macro to perform three functions at once */
45 #define theta_pi_gamma(a, i) \
46 SB0(GB(a, i-0, 7)) ^ \
47 SB1(GB(a, i-1, 6)) ^ \
48 SB2(GB(a, i-2, 5)) ^ \
49 SB3(GB(a, i-3, 4)) ^ \
50 SB4(GB(a, i-4, 3)) ^ \
51 SB5(GB(a, i-5, 2)) ^ \
52 SB6(GB(a, i-6, 1)) ^ \
53 SB7(GB(a, i-7, 0))
54
55 #ifdef LTC_CLEAN_STACK
56 static int _whirlpool_compress(hash_state *md, unsigned char *buf)
57 #else
58 static int whirlpool_compress(hash_state *md, unsigned char *buf)
59 #endif
60 {
61 ulong64 K[2][8], T[3][8];
62 int x, y;
63
64 /* load the block/state */
65 for (x = 0; x < 8; x++) {
66 K[0][x] = md->whirlpool.state[x];
67
68 LOAD64H(T[0][x], buf + (8 * x));
69 T[2][x] = T[0][x];
70 T[0][x] ^= K[0][x];
71 }
72
73 /* do rounds 1..10 */
74 for (x = 0; x < 10; x += 2) {
75 /* odd round */
76 /* apply main transform to K[0] into K[1] */
77 for (y = 0; y < 8; y++) {
78 K[1][y] = theta_pi_gamma(K[0], y);
79 }
80 /* xor the constant */
81 K[1][0] ^= cont[x];
82
83 /* apply main transform to T[0] into T[1] */
84 for (y = 0; y < 8; y++) {
85 T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y];
86 }
87
88 /* even round */
89 /* apply main transform to K[1] into K[0] */
90 for (y = 0; y < 8; y++) {
91 K[0][y] = theta_pi_gamma(K[1], y);
92 }
93 /* xor the constant */
94 K[0][0] ^= cont[x+1];
95
96 /* apply main transform to T[1] into T[0] */
97 for (y = 0; y < 8; y++) {
98 T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y];
99 }
100 }
101
102 /* store state */
103 for (x = 0; x < 8; x++) {
104 md->whirlpool.state[x] ^= T[0][x] ^ T[2][x];
105 }
106
107 return CRYPT_OK;
108 }
109
110
111 #ifdef LTC_CLEAN_STACK
112 static int whirlpool_compress(hash_state *md, unsigned char *buf)
113 {
114 int err;
115 err = _whirlpool_compress(md, buf);
116 burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int)));
117 return err;
118 }
119 #endif
120
121
122 /**
123 Initialize the hash state
124 @param md The hash state you wish to initialize
125 @return CRYPT_OK if successful
126 */
127 int whirlpool_init(hash_state * md)
128 {
129 LTC_ARGCHK(md != NULL);
130 zeromem(&md->whirlpool, sizeof(md->whirlpool));
131 return CRYPT_OK;
132 }
133
134 /**
135 Process a block of memory though the hash
136 @param md The hash state
137 @param in The data to hash
138 @param inlen The length of the data (octets)
139 @return CRYPT_OK if successful
140 */
141 HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64)
142
143 /**
144 Terminate the hash to get the digest
145 @param md The hash state
146 @param out [out] The destination of the hash (64 bytes)
147 @return CRYPT_OK if successful
148 */
149 int whirlpool_done(hash_state * md, unsigned char *out)
150 {
151 int i;
152
153 LTC_ARGCHK(md != NULL);
154 LTC_ARGCHK(out != NULL);
155
156 if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) {
157 return CRYPT_INVALID_ARG;
158 }
159
160 /* increase the length of the message */
161 md->whirlpool.length += md->whirlpool.curlen * 8;
162
163 /* append the '1' bit */
164 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80;
165
166 /* if the length is currently above 32 bytes we append zeros
167 * then compress. Then we can fall back to padding zeros and length
168 * encoding like normal.
169 */
170 if (md->whirlpool.curlen > 32) {
171 while (md->whirlpool.curlen < 64) {
172 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
173 }
174 whirlpool_compress(md, md->whirlpool.buf);
175 md->whirlpool.curlen = 0;
176 }
177
178 /* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths) */
179 while (md->whirlpool.curlen < 56) {
180 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
181 }
182
183 /* store length */
184 STORE64H(md->whirlpool.length, md->whirlpool.buf+56);
185 whirlpool_compress(md, md->whirlpool.buf);
186
187 /* copy output */
188 for (i = 0; i < 8; i++) {
189 STORE64H(md->whirlpool.state[i], out+(8*i));
190 }
191 #ifdef LTC_CLEAN_STACK
192 zeromem(md, sizeof(*md));
193 #endif
194 return CRYPT_OK;
195 }
196
197 /**
198 Self-test the hash
199 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
200 */
201 int whirlpool_test(void)
202 {
203 #ifndef LTC_TEST
204 return CRYPT_NOP;
205 #else
206 static const struct {
207 int len;
208 unsigned char msg[128], hash[64];
209 } tests[] = {
210
211 /* NULL Message */
212 {
213 0,
214 { 0x00 },
215 { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26,
216 0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7,
217 0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57,
218 0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 }
219 },
220
221
222 /* 448-bits of 0 bits */
223 {
224
225 56,
226 { 0x00 },
227 { 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03,
228 0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70,
229 0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61,
230 0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 }
231 },
232
233 /* 520-bits of 0 bits */
234 {
235 65,
236 { 0x00 },
237 { 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D,
238 0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4,
239 0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF,
240 0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 }
241 },
242
243 /* 512-bits, leading set */
244 {
245 64,
246 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
250 { 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A,
251 0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94,
252 0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6,
253 0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB }
254 },
255
256 /* 512-bits, leading set of second byte */
257 {
258 64,
259 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
263 { 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E,
264 0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F,
265 0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35,
266 0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 }
267 },
268
269 /* 512-bits, leading set of last byte */
270 {
271 64,
272 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
276 { 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6,
277 0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F,
278 0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B,
279 0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 }
280 },
281
282 };
283
284 int i;
285 unsigned char tmp[64];
286 hash_state md;
287
288 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
289 whirlpool_init(&md);
290 whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len);
291 whirlpool_done(&md, tmp);
292 if (XMEMCMP(tmp, tests[i].hash, 64) != 0) {
293 #if 0
294 printf("\nFailed test %d\n", i);
295 for (i = 0; i < 64; ) {
296 printf("%02x ", tmp[i]);
297 if (!(++i & 15)) printf("\n");
298 }
299 #endif
300 return CRYPT_FAIL_TESTVECTOR;
301 }
302 }
303 return CRYPT_OK;
304 #endif
305 }
306
307
308 #endif
309
310
311 /* $Source$ */
312 /* $Revision$ */
313 /* $Date$ */
0 /**
1 @file whirltab.c
2 LTC_WHIRLPOOL tables, Tom St Denis
3 */
4 static const ulong64 sbox0[] = {
5 CONST64(0x18186018c07830d8), CONST64(0x23238c2305af4626), CONST64(0xc6c63fc67ef991b8), CONST64(0xe8e887e8136fcdfb),
6 CONST64(0x878726874ca113cb), CONST64(0xb8b8dab8a9626d11), CONST64(0x0101040108050209), CONST64(0x4f4f214f426e9e0d),
7 CONST64(0x3636d836adee6c9b), CONST64(0xa6a6a2a6590451ff), CONST64(0xd2d26fd2debdb90c), CONST64(0xf5f5f3f5fb06f70e),
8 CONST64(0x7979f979ef80f296), CONST64(0x6f6fa16f5fcede30), CONST64(0x91917e91fcef3f6d), CONST64(0x52525552aa07a4f8),
9 CONST64(0x60609d6027fdc047), CONST64(0xbcbccabc89766535), CONST64(0x9b9b569baccd2b37), CONST64(0x8e8e028e048c018a),
10 CONST64(0xa3a3b6a371155bd2), CONST64(0x0c0c300c603c186c), CONST64(0x7b7bf17bff8af684), CONST64(0x3535d435b5e16a80),
11 CONST64(0x1d1d741de8693af5), CONST64(0xe0e0a7e05347ddb3), CONST64(0xd7d77bd7f6acb321), CONST64(0xc2c22fc25eed999c),
12 CONST64(0x2e2eb82e6d965c43), CONST64(0x4b4b314b627a9629), CONST64(0xfefedffea321e15d), CONST64(0x575741578216aed5),
13 CONST64(0x15155415a8412abd), CONST64(0x7777c1779fb6eee8), CONST64(0x3737dc37a5eb6e92), CONST64(0xe5e5b3e57b56d79e),
14 CONST64(0x9f9f469f8cd92313), CONST64(0xf0f0e7f0d317fd23), CONST64(0x4a4a354a6a7f9420), CONST64(0xdada4fda9e95a944),
15 CONST64(0x58587d58fa25b0a2), CONST64(0xc9c903c906ca8fcf), CONST64(0x2929a429558d527c), CONST64(0x0a0a280a5022145a),
16 CONST64(0xb1b1feb1e14f7f50), CONST64(0xa0a0baa0691a5dc9), CONST64(0x6b6bb16b7fdad614), CONST64(0x85852e855cab17d9),
17 CONST64(0xbdbdcebd8173673c), CONST64(0x5d5d695dd234ba8f), CONST64(0x1010401080502090), CONST64(0xf4f4f7f4f303f507),
18 CONST64(0xcbcb0bcb16c08bdd), CONST64(0x3e3ef83eedc67cd3), CONST64(0x0505140528110a2d), CONST64(0x676781671fe6ce78),
19 CONST64(0xe4e4b7e47353d597), CONST64(0x27279c2725bb4e02), CONST64(0x4141194132588273), CONST64(0x8b8b168b2c9d0ba7),
20 CONST64(0xa7a7a6a7510153f6), CONST64(0x7d7de97dcf94fab2), CONST64(0x95956e95dcfb3749), CONST64(0xd8d847d88e9fad56),
21 CONST64(0xfbfbcbfb8b30eb70), CONST64(0xeeee9fee2371c1cd), CONST64(0x7c7ced7cc791f8bb), CONST64(0x6666856617e3cc71),
22 CONST64(0xdddd53dda68ea77b), CONST64(0x17175c17b84b2eaf), CONST64(0x4747014702468e45), CONST64(0x9e9e429e84dc211a),
23 CONST64(0xcaca0fca1ec589d4), CONST64(0x2d2db42d75995a58), CONST64(0xbfbfc6bf9179632e), CONST64(0x07071c07381b0e3f),
24 CONST64(0xadad8ead012347ac), CONST64(0x5a5a755aea2fb4b0), CONST64(0x838336836cb51bef), CONST64(0x3333cc3385ff66b6),
25 CONST64(0x636391633ff2c65c), CONST64(0x02020802100a0412), CONST64(0xaaaa92aa39384993), CONST64(0x7171d971afa8e2de),
26 CONST64(0xc8c807c80ecf8dc6), CONST64(0x19196419c87d32d1), CONST64(0x494939497270923b), CONST64(0xd9d943d9869aaf5f),
27 CONST64(0xf2f2eff2c31df931), CONST64(0xe3e3abe34b48dba8), CONST64(0x5b5b715be22ab6b9), CONST64(0x88881a8834920dbc),
28 CONST64(0x9a9a529aa4c8293e), CONST64(0x262698262dbe4c0b), CONST64(0x3232c8328dfa64bf), CONST64(0xb0b0fab0e94a7d59),
29 CONST64(0xe9e983e91b6acff2), CONST64(0x0f0f3c0f78331e77), CONST64(0xd5d573d5e6a6b733), CONST64(0x80803a8074ba1df4),
30 CONST64(0xbebec2be997c6127), CONST64(0xcdcd13cd26de87eb), CONST64(0x3434d034bde46889), CONST64(0x48483d487a759032),
31 CONST64(0xffffdbffab24e354), CONST64(0x7a7af57af78ff48d), CONST64(0x90907a90f4ea3d64), CONST64(0x5f5f615fc23ebe9d),
32 CONST64(0x202080201da0403d), CONST64(0x6868bd6867d5d00f), CONST64(0x1a1a681ad07234ca), CONST64(0xaeae82ae192c41b7),
33 CONST64(0xb4b4eab4c95e757d), CONST64(0x54544d549a19a8ce), CONST64(0x93937693ece53b7f), CONST64(0x222288220daa442f),
34 CONST64(0x64648d6407e9c863), CONST64(0xf1f1e3f1db12ff2a), CONST64(0x7373d173bfa2e6cc), CONST64(0x12124812905a2482),
35 CONST64(0x40401d403a5d807a), CONST64(0x0808200840281048), CONST64(0xc3c32bc356e89b95), CONST64(0xecec97ec337bc5df),
36 CONST64(0xdbdb4bdb9690ab4d), CONST64(0xa1a1bea1611f5fc0), CONST64(0x8d8d0e8d1c830791), CONST64(0x3d3df43df5c97ac8),
37 CONST64(0x97976697ccf1335b), CONST64(0x0000000000000000), CONST64(0xcfcf1bcf36d483f9), CONST64(0x2b2bac2b4587566e),
38 CONST64(0x7676c57697b3ece1), CONST64(0x8282328264b019e6), CONST64(0xd6d67fd6fea9b128), CONST64(0x1b1b6c1bd87736c3),
39 CONST64(0xb5b5eeb5c15b7774), CONST64(0xafaf86af112943be), CONST64(0x6a6ab56a77dfd41d), CONST64(0x50505d50ba0da0ea),
40 CONST64(0x45450945124c8a57), CONST64(0xf3f3ebf3cb18fb38), CONST64(0x3030c0309df060ad), CONST64(0xefef9bef2b74c3c4),
41 CONST64(0x3f3ffc3fe5c37eda), CONST64(0x55554955921caac7), CONST64(0xa2a2b2a2791059db), CONST64(0xeaea8fea0365c9e9),
42 CONST64(0x656589650fecca6a), CONST64(0xbabad2bab9686903), CONST64(0x2f2fbc2f65935e4a), CONST64(0xc0c027c04ee79d8e),
43 CONST64(0xdede5fdebe81a160), CONST64(0x1c1c701ce06c38fc), CONST64(0xfdfdd3fdbb2ee746), CONST64(0x4d4d294d52649a1f),
44 CONST64(0x92927292e4e03976), CONST64(0x7575c9758fbceafa), CONST64(0x06061806301e0c36), CONST64(0x8a8a128a249809ae),
45 CONST64(0xb2b2f2b2f940794b), CONST64(0xe6e6bfe66359d185), CONST64(0x0e0e380e70361c7e), CONST64(0x1f1f7c1ff8633ee7),
46 CONST64(0x6262956237f7c455), CONST64(0xd4d477d4eea3b53a), CONST64(0xa8a89aa829324d81), CONST64(0x96966296c4f43152),
47 CONST64(0xf9f9c3f99b3aef62), CONST64(0xc5c533c566f697a3), CONST64(0x2525942535b14a10), CONST64(0x59597959f220b2ab),
48 CONST64(0x84842a8454ae15d0), CONST64(0x7272d572b7a7e4c5), CONST64(0x3939e439d5dd72ec), CONST64(0x4c4c2d4c5a619816),
49 CONST64(0x5e5e655eca3bbc94), CONST64(0x7878fd78e785f09f), CONST64(0x3838e038ddd870e5), CONST64(0x8c8c0a8c14860598),
50 CONST64(0xd1d163d1c6b2bf17), CONST64(0xa5a5aea5410b57e4), CONST64(0xe2e2afe2434dd9a1), CONST64(0x616199612ff8c24e),
51 CONST64(0xb3b3f6b3f1457b42), CONST64(0x2121842115a54234), CONST64(0x9c9c4a9c94d62508), CONST64(0x1e1e781ef0663cee),
52 CONST64(0x4343114322528661), CONST64(0xc7c73bc776fc93b1), CONST64(0xfcfcd7fcb32be54f), CONST64(0x0404100420140824),
53 CONST64(0x51515951b208a2e3), CONST64(0x99995e99bcc72f25), CONST64(0x6d6da96d4fc4da22), CONST64(0x0d0d340d68391a65),
54 CONST64(0xfafacffa8335e979), CONST64(0xdfdf5bdfb684a369), CONST64(0x7e7ee57ed79bfca9), CONST64(0x242490243db44819),
55 CONST64(0x3b3bec3bc5d776fe), CONST64(0xabab96ab313d4b9a), CONST64(0xcece1fce3ed181f0), CONST64(0x1111441188552299),
56 CONST64(0x8f8f068f0c890383), CONST64(0x4e4e254e4a6b9c04), CONST64(0xb7b7e6b7d1517366), CONST64(0xebeb8beb0b60cbe0),
57 CONST64(0x3c3cf03cfdcc78c1), CONST64(0x81813e817cbf1ffd), CONST64(0x94946a94d4fe3540), CONST64(0xf7f7fbf7eb0cf31c),
58 CONST64(0xb9b9deb9a1676f18), CONST64(0x13134c13985f268b), CONST64(0x2c2cb02c7d9c5851), CONST64(0xd3d36bd3d6b8bb05),
59 CONST64(0xe7e7bbe76b5cd38c), CONST64(0x6e6ea56e57cbdc39), CONST64(0xc4c437c46ef395aa), CONST64(0x03030c03180f061b),
60 CONST64(0x565645568a13acdc), CONST64(0x44440d441a49885e), CONST64(0x7f7fe17fdf9efea0), CONST64(0xa9a99ea921374f88),
61 CONST64(0x2a2aa82a4d825467), CONST64(0xbbbbd6bbb16d6b0a), CONST64(0xc1c123c146e29f87), CONST64(0x53535153a202a6f1),
62 CONST64(0xdcdc57dcae8ba572), CONST64(0x0b0b2c0b58271653), CONST64(0x9d9d4e9d9cd32701), CONST64(0x6c6cad6c47c1d82b),
63 CONST64(0x3131c43195f562a4), CONST64(0x7474cd7487b9e8f3), CONST64(0xf6f6fff6e309f115), CONST64(0x464605460a438c4c),
64 CONST64(0xacac8aac092645a5), CONST64(0x89891e893c970fb5), CONST64(0x14145014a04428b4), CONST64(0xe1e1a3e15b42dfba),
65 CONST64(0x16165816b04e2ca6), CONST64(0x3a3ae83acdd274f7), CONST64(0x6969b9696fd0d206), CONST64(0x09092409482d1241),
66 CONST64(0x7070dd70a7ade0d7), CONST64(0xb6b6e2b6d954716f), CONST64(0xd0d067d0ceb7bd1e), CONST64(0xeded93ed3b7ec7d6),
67 CONST64(0xcccc17cc2edb85e2), CONST64(0x424215422a578468), CONST64(0x98985a98b4c22d2c), CONST64(0xa4a4aaa4490e55ed),
68 CONST64(0x2828a0285d885075), CONST64(0x5c5c6d5cda31b886), CONST64(0xf8f8c7f8933fed6b), CONST64(0x8686228644a411c2)
69 };
70
71 #ifdef LTC_SMALL_CODE
72
73 #define SB0(x) sbox0[x]
74 #define SB1(x) ROR64c(sbox0[x], 8)
75 #define SB2(x) ROR64c(sbox0[x], 16)
76 #define SB3(x) ROR64c(sbox0[x], 24)
77 #define SB4(x) ROR64c(sbox0[x], 32)
78 #define SB5(x) ROR64c(sbox0[x], 40)
79 #define SB6(x) ROR64c(sbox0[x], 48)
80 #define SB7(x) ROR64c(sbox0[x], 56)
81
82 #else
83
84 #define SB0(x) sbox0[x]
85 #define SB1(x) sbox1[x]
86 #define SB2(x) sbox2[x]
87 #define SB3(x) sbox3[x]
88 #define SB4(x) sbox4[x]
89 #define SB5(x) sbox5[x]
90 #define SB6(x) sbox6[x]
91 #define SB7(x) sbox7[x]
92
93
94 static const ulong64 sbox1[] = {
95 CONST64(0xd818186018c07830), CONST64(0x2623238c2305af46), CONST64(0xb8c6c63fc67ef991), CONST64(0xfbe8e887e8136fcd),
96 CONST64(0xcb878726874ca113), CONST64(0x11b8b8dab8a9626d), CONST64(0x0901010401080502), CONST64(0x0d4f4f214f426e9e),
97 CONST64(0x9b3636d836adee6c), CONST64(0xffa6a6a2a6590451), CONST64(0x0cd2d26fd2debdb9), CONST64(0x0ef5f5f3f5fb06f7),
98 CONST64(0x967979f979ef80f2), CONST64(0x306f6fa16f5fcede), CONST64(0x6d91917e91fcef3f), CONST64(0xf852525552aa07a4),
99 CONST64(0x4760609d6027fdc0), CONST64(0x35bcbccabc897665), CONST64(0x379b9b569baccd2b), CONST64(0x8a8e8e028e048c01),
100 CONST64(0xd2a3a3b6a371155b), CONST64(0x6c0c0c300c603c18), CONST64(0x847b7bf17bff8af6), CONST64(0x803535d435b5e16a),
101 CONST64(0xf51d1d741de8693a), CONST64(0xb3e0e0a7e05347dd), CONST64(0x21d7d77bd7f6acb3), CONST64(0x9cc2c22fc25eed99),
102 CONST64(0x432e2eb82e6d965c), CONST64(0x294b4b314b627a96), CONST64(0x5dfefedffea321e1), CONST64(0xd5575741578216ae),
103 CONST64(0xbd15155415a8412a), CONST64(0xe87777c1779fb6ee), CONST64(0x923737dc37a5eb6e), CONST64(0x9ee5e5b3e57b56d7),
104 CONST64(0x139f9f469f8cd923), CONST64(0x23f0f0e7f0d317fd), CONST64(0x204a4a354a6a7f94), CONST64(0x44dada4fda9e95a9),
105 CONST64(0xa258587d58fa25b0), CONST64(0xcfc9c903c906ca8f), CONST64(0x7c2929a429558d52), CONST64(0x5a0a0a280a502214),
106 CONST64(0x50b1b1feb1e14f7f), CONST64(0xc9a0a0baa0691a5d), CONST64(0x146b6bb16b7fdad6), CONST64(0xd985852e855cab17),
107 CONST64(0x3cbdbdcebd817367), CONST64(0x8f5d5d695dd234ba), CONST64(0x9010104010805020), CONST64(0x07f4f4f7f4f303f5),
108 CONST64(0xddcbcb0bcb16c08b), CONST64(0xd33e3ef83eedc67c), CONST64(0x2d0505140528110a), CONST64(0x78676781671fe6ce),
109 CONST64(0x97e4e4b7e47353d5), CONST64(0x0227279c2725bb4e), CONST64(0x7341411941325882), CONST64(0xa78b8b168b2c9d0b),
110 CONST64(0xf6a7a7a6a7510153), CONST64(0xb27d7de97dcf94fa), CONST64(0x4995956e95dcfb37), CONST64(0x56d8d847d88e9fad),
111 CONST64(0x70fbfbcbfb8b30eb), CONST64(0xcdeeee9fee2371c1), CONST64(0xbb7c7ced7cc791f8), CONST64(0x716666856617e3cc),
112 CONST64(0x7bdddd53dda68ea7), CONST64(0xaf17175c17b84b2e), CONST64(0x454747014702468e), CONST64(0x1a9e9e429e84dc21),
113 CONST64(0xd4caca0fca1ec589), CONST64(0x582d2db42d75995a), CONST64(0x2ebfbfc6bf917963), CONST64(0x3f07071c07381b0e),
114 CONST64(0xacadad8ead012347), CONST64(0xb05a5a755aea2fb4), CONST64(0xef838336836cb51b), CONST64(0xb63333cc3385ff66),
115 CONST64(0x5c636391633ff2c6), CONST64(0x1202020802100a04), CONST64(0x93aaaa92aa393849), CONST64(0xde7171d971afa8e2),
116 CONST64(0xc6c8c807c80ecf8d), CONST64(0xd119196419c87d32), CONST64(0x3b49493949727092), CONST64(0x5fd9d943d9869aaf),
117 CONST64(0x31f2f2eff2c31df9), CONST64(0xa8e3e3abe34b48db), CONST64(0xb95b5b715be22ab6), CONST64(0xbc88881a8834920d),
118 CONST64(0x3e9a9a529aa4c829), CONST64(0x0b262698262dbe4c), CONST64(0xbf3232c8328dfa64), CONST64(0x59b0b0fab0e94a7d),
119 CONST64(0xf2e9e983e91b6acf), CONST64(0x770f0f3c0f78331e), CONST64(0x33d5d573d5e6a6b7), CONST64(0xf480803a8074ba1d),
120 CONST64(0x27bebec2be997c61), CONST64(0xebcdcd13cd26de87), CONST64(0x893434d034bde468), CONST64(0x3248483d487a7590),
121 CONST64(0x54ffffdbffab24e3), CONST64(0x8d7a7af57af78ff4), CONST64(0x6490907a90f4ea3d), CONST64(0x9d5f5f615fc23ebe),
122 CONST64(0x3d202080201da040), CONST64(0x0f6868bd6867d5d0), CONST64(0xca1a1a681ad07234), CONST64(0xb7aeae82ae192c41),
123 CONST64(0x7db4b4eab4c95e75), CONST64(0xce54544d549a19a8), CONST64(0x7f93937693ece53b), CONST64(0x2f222288220daa44),
124 CONST64(0x6364648d6407e9c8), CONST64(0x2af1f1e3f1db12ff), CONST64(0xcc7373d173bfa2e6), CONST64(0x8212124812905a24),
125 CONST64(0x7a40401d403a5d80), CONST64(0x4808082008402810), CONST64(0x95c3c32bc356e89b), CONST64(0xdfecec97ec337bc5),
126 CONST64(0x4ddbdb4bdb9690ab), CONST64(0xc0a1a1bea1611f5f), CONST64(0x918d8d0e8d1c8307), CONST64(0xc83d3df43df5c97a),
127 CONST64(0x5b97976697ccf133), CONST64(0x0000000000000000), CONST64(0xf9cfcf1bcf36d483), CONST64(0x6e2b2bac2b458756),
128 CONST64(0xe17676c57697b3ec), CONST64(0xe68282328264b019), CONST64(0x28d6d67fd6fea9b1), CONST64(0xc31b1b6c1bd87736),
129 CONST64(0x74b5b5eeb5c15b77), CONST64(0xbeafaf86af112943), CONST64(0x1d6a6ab56a77dfd4), CONST64(0xea50505d50ba0da0),
130 CONST64(0x5745450945124c8a), CONST64(0x38f3f3ebf3cb18fb), CONST64(0xad3030c0309df060), CONST64(0xc4efef9bef2b74c3),
131 CONST64(0xda3f3ffc3fe5c37e), CONST64(0xc755554955921caa), CONST64(0xdba2a2b2a2791059), CONST64(0xe9eaea8fea0365c9),
132 CONST64(0x6a656589650fecca), CONST64(0x03babad2bab96869), CONST64(0x4a2f2fbc2f65935e), CONST64(0x8ec0c027c04ee79d),
133 CONST64(0x60dede5fdebe81a1), CONST64(0xfc1c1c701ce06c38), CONST64(0x46fdfdd3fdbb2ee7), CONST64(0x1f4d4d294d52649a),
134 CONST64(0x7692927292e4e039), CONST64(0xfa7575c9758fbcea), CONST64(0x3606061806301e0c), CONST64(0xae8a8a128a249809),
135 CONST64(0x4bb2b2f2b2f94079), CONST64(0x85e6e6bfe66359d1), CONST64(0x7e0e0e380e70361c), CONST64(0xe71f1f7c1ff8633e),
136 CONST64(0x556262956237f7c4), CONST64(0x3ad4d477d4eea3b5), CONST64(0x81a8a89aa829324d), CONST64(0x5296966296c4f431),
137 CONST64(0x62f9f9c3f99b3aef), CONST64(0xa3c5c533c566f697), CONST64(0x102525942535b14a), CONST64(0xab59597959f220b2),
138 CONST64(0xd084842a8454ae15), CONST64(0xc57272d572b7a7e4), CONST64(0xec3939e439d5dd72), CONST64(0x164c4c2d4c5a6198),
139 CONST64(0x945e5e655eca3bbc), CONST64(0x9f7878fd78e785f0), CONST64(0xe53838e038ddd870), CONST64(0x988c8c0a8c148605),
140 CONST64(0x17d1d163d1c6b2bf), CONST64(0xe4a5a5aea5410b57), CONST64(0xa1e2e2afe2434dd9), CONST64(0x4e616199612ff8c2),
141 CONST64(0x42b3b3f6b3f1457b), CONST64(0x342121842115a542), CONST64(0x089c9c4a9c94d625), CONST64(0xee1e1e781ef0663c),
142 CONST64(0x6143431143225286), CONST64(0xb1c7c73bc776fc93), CONST64(0x4ffcfcd7fcb32be5), CONST64(0x2404041004201408),
143 CONST64(0xe351515951b208a2), CONST64(0x2599995e99bcc72f), CONST64(0x226d6da96d4fc4da), CONST64(0x650d0d340d68391a),
144 CONST64(0x79fafacffa8335e9), CONST64(0x69dfdf5bdfb684a3), CONST64(0xa97e7ee57ed79bfc), CONST64(0x19242490243db448),
145 CONST64(0xfe3b3bec3bc5d776), CONST64(0x9aabab96ab313d4b), CONST64(0xf0cece1fce3ed181), CONST64(0x9911114411885522),
146 CONST64(0x838f8f068f0c8903), CONST64(0x044e4e254e4a6b9c), CONST64(0x66b7b7e6b7d15173), CONST64(0xe0ebeb8beb0b60cb),
147 CONST64(0xc13c3cf03cfdcc78), CONST64(0xfd81813e817cbf1f), CONST64(0x4094946a94d4fe35), CONST64(0x1cf7f7fbf7eb0cf3),
148 CONST64(0x18b9b9deb9a1676f), CONST64(0x8b13134c13985f26), CONST64(0x512c2cb02c7d9c58), CONST64(0x05d3d36bd3d6b8bb),
149 CONST64(0x8ce7e7bbe76b5cd3), CONST64(0x396e6ea56e57cbdc), CONST64(0xaac4c437c46ef395), CONST64(0x1b03030c03180f06),
150 CONST64(0xdc565645568a13ac), CONST64(0x5e44440d441a4988), CONST64(0xa07f7fe17fdf9efe), CONST64(0x88a9a99ea921374f),
151 CONST64(0x672a2aa82a4d8254), CONST64(0x0abbbbd6bbb16d6b), CONST64(0x87c1c123c146e29f), CONST64(0xf153535153a202a6),
152 CONST64(0x72dcdc57dcae8ba5), CONST64(0x530b0b2c0b582716), CONST64(0x019d9d4e9d9cd327), CONST64(0x2b6c6cad6c47c1d8),
153 CONST64(0xa43131c43195f562), CONST64(0xf37474cd7487b9e8), CONST64(0x15f6f6fff6e309f1), CONST64(0x4c464605460a438c),
154 CONST64(0xa5acac8aac092645), CONST64(0xb589891e893c970f), CONST64(0xb414145014a04428), CONST64(0xbae1e1a3e15b42df),
155 CONST64(0xa616165816b04e2c), CONST64(0xf73a3ae83acdd274), CONST64(0x066969b9696fd0d2), CONST64(0x4109092409482d12),
156 CONST64(0xd77070dd70a7ade0), CONST64(0x6fb6b6e2b6d95471), CONST64(0x1ed0d067d0ceb7bd), CONST64(0xd6eded93ed3b7ec7),
157 CONST64(0xe2cccc17cc2edb85), CONST64(0x68424215422a5784), CONST64(0x2c98985a98b4c22d), CONST64(0xeda4a4aaa4490e55),
158 CONST64(0x752828a0285d8850), CONST64(0x865c5c6d5cda31b8), CONST64(0x6bf8f8c7f8933fed), CONST64(0xc28686228644a411)
159 };
160
161 static const ulong64 sbox2[] = {
162 CONST64(0x30d818186018c078), CONST64(0x462623238c2305af), CONST64(0x91b8c6c63fc67ef9), CONST64(0xcdfbe8e887e8136f),
163 CONST64(0x13cb878726874ca1), CONST64(0x6d11b8b8dab8a962), CONST64(0x0209010104010805), CONST64(0x9e0d4f4f214f426e),
164 CONST64(0x6c9b3636d836adee), CONST64(0x51ffa6a6a2a65904), CONST64(0xb90cd2d26fd2debd), CONST64(0xf70ef5f5f3f5fb06),
165 CONST64(0xf2967979f979ef80), CONST64(0xde306f6fa16f5fce), CONST64(0x3f6d91917e91fcef), CONST64(0xa4f852525552aa07),
166 CONST64(0xc04760609d6027fd), CONST64(0x6535bcbccabc8976), CONST64(0x2b379b9b569baccd), CONST64(0x018a8e8e028e048c),
167 CONST64(0x5bd2a3a3b6a37115), CONST64(0x186c0c0c300c603c), CONST64(0xf6847b7bf17bff8a), CONST64(0x6a803535d435b5e1),
168 CONST64(0x3af51d1d741de869), CONST64(0xddb3e0e0a7e05347), CONST64(0xb321d7d77bd7f6ac), CONST64(0x999cc2c22fc25eed),
169 CONST64(0x5c432e2eb82e6d96), CONST64(0x96294b4b314b627a), CONST64(0xe15dfefedffea321), CONST64(0xaed5575741578216),
170 CONST64(0x2abd15155415a841), CONST64(0xeee87777c1779fb6), CONST64(0x6e923737dc37a5eb), CONST64(0xd79ee5e5b3e57b56),
171 CONST64(0x23139f9f469f8cd9), CONST64(0xfd23f0f0e7f0d317), CONST64(0x94204a4a354a6a7f), CONST64(0xa944dada4fda9e95),
172 CONST64(0xb0a258587d58fa25), CONST64(0x8fcfc9c903c906ca), CONST64(0x527c2929a429558d), CONST64(0x145a0a0a280a5022),
173 CONST64(0x7f50b1b1feb1e14f), CONST64(0x5dc9a0a0baa0691a), CONST64(0xd6146b6bb16b7fda), CONST64(0x17d985852e855cab),
174 CONST64(0x673cbdbdcebd8173), CONST64(0xba8f5d5d695dd234), CONST64(0x2090101040108050), CONST64(0xf507f4f4f7f4f303),
175 CONST64(0x8bddcbcb0bcb16c0), CONST64(0x7cd33e3ef83eedc6), CONST64(0x0a2d050514052811), CONST64(0xce78676781671fe6),
176 CONST64(0xd597e4e4b7e47353), CONST64(0x4e0227279c2725bb), CONST64(0x8273414119413258), CONST64(0x0ba78b8b168b2c9d),
177 CONST64(0x53f6a7a7a6a75101), CONST64(0xfab27d7de97dcf94), CONST64(0x374995956e95dcfb), CONST64(0xad56d8d847d88e9f),
178 CONST64(0xeb70fbfbcbfb8b30), CONST64(0xc1cdeeee9fee2371), CONST64(0xf8bb7c7ced7cc791), CONST64(0xcc716666856617e3),
179 CONST64(0xa77bdddd53dda68e), CONST64(0x2eaf17175c17b84b), CONST64(0x8e45474701470246), CONST64(0x211a9e9e429e84dc),
180 CONST64(0x89d4caca0fca1ec5), CONST64(0x5a582d2db42d7599), CONST64(0x632ebfbfc6bf9179), CONST64(0x0e3f07071c07381b),
181 CONST64(0x47acadad8ead0123), CONST64(0xb4b05a5a755aea2f), CONST64(0x1bef838336836cb5), CONST64(0x66b63333cc3385ff),
182 CONST64(0xc65c636391633ff2), CONST64(0x041202020802100a), CONST64(0x4993aaaa92aa3938), CONST64(0xe2de7171d971afa8),
183 CONST64(0x8dc6c8c807c80ecf), CONST64(0x32d119196419c87d), CONST64(0x923b494939497270), CONST64(0xaf5fd9d943d9869a),
184 CONST64(0xf931f2f2eff2c31d), CONST64(0xdba8e3e3abe34b48), CONST64(0xb6b95b5b715be22a), CONST64(0x0dbc88881a883492),
185 CONST64(0x293e9a9a529aa4c8), CONST64(0x4c0b262698262dbe), CONST64(0x64bf3232c8328dfa), CONST64(0x7d59b0b0fab0e94a),
186 CONST64(0xcff2e9e983e91b6a), CONST64(0x1e770f0f3c0f7833), CONST64(0xb733d5d573d5e6a6), CONST64(0x1df480803a8074ba),
187 CONST64(0x6127bebec2be997c), CONST64(0x87ebcdcd13cd26de), CONST64(0x68893434d034bde4), CONST64(0x903248483d487a75),
188 CONST64(0xe354ffffdbffab24), CONST64(0xf48d7a7af57af78f), CONST64(0x3d6490907a90f4ea), CONST64(0xbe9d5f5f615fc23e),
189 CONST64(0x403d202080201da0), CONST64(0xd00f6868bd6867d5), CONST64(0x34ca1a1a681ad072), CONST64(0x41b7aeae82ae192c),
190 CONST64(0x757db4b4eab4c95e), CONST64(0xa8ce54544d549a19), CONST64(0x3b7f93937693ece5), CONST64(0x442f222288220daa),
191 CONST64(0xc86364648d6407e9), CONST64(0xff2af1f1e3f1db12), CONST64(0xe6cc7373d173bfa2), CONST64(0x248212124812905a),
192 CONST64(0x807a40401d403a5d), CONST64(0x1048080820084028), CONST64(0x9b95c3c32bc356e8), CONST64(0xc5dfecec97ec337b),
193 CONST64(0xab4ddbdb4bdb9690), CONST64(0x5fc0a1a1bea1611f), CONST64(0x07918d8d0e8d1c83), CONST64(0x7ac83d3df43df5c9),
194 CONST64(0x335b97976697ccf1), CONST64(0x0000000000000000), CONST64(0x83f9cfcf1bcf36d4), CONST64(0x566e2b2bac2b4587),
195 CONST64(0xece17676c57697b3), CONST64(0x19e68282328264b0), CONST64(0xb128d6d67fd6fea9), CONST64(0x36c31b1b6c1bd877),
196 CONST64(0x7774b5b5eeb5c15b), CONST64(0x43beafaf86af1129), CONST64(0xd41d6a6ab56a77df), CONST64(0xa0ea50505d50ba0d),
197 CONST64(0x8a5745450945124c), CONST64(0xfb38f3f3ebf3cb18), CONST64(0x60ad3030c0309df0), CONST64(0xc3c4efef9bef2b74),
198 CONST64(0x7eda3f3ffc3fe5c3), CONST64(0xaac755554955921c), CONST64(0x59dba2a2b2a27910), CONST64(0xc9e9eaea8fea0365),
199 CONST64(0xca6a656589650fec), CONST64(0x6903babad2bab968), CONST64(0x5e4a2f2fbc2f6593), CONST64(0x9d8ec0c027c04ee7),
200 CONST64(0xa160dede5fdebe81), CONST64(0x38fc1c1c701ce06c), CONST64(0xe746fdfdd3fdbb2e), CONST64(0x9a1f4d4d294d5264),
201 CONST64(0x397692927292e4e0), CONST64(0xeafa7575c9758fbc), CONST64(0x0c3606061806301e), CONST64(0x09ae8a8a128a2498),
202 CONST64(0x794bb2b2f2b2f940), CONST64(0xd185e6e6bfe66359), CONST64(0x1c7e0e0e380e7036), CONST64(0x3ee71f1f7c1ff863),
203 CONST64(0xc4556262956237f7), CONST64(0xb53ad4d477d4eea3), CONST64(0x4d81a8a89aa82932), CONST64(0x315296966296c4f4),
204 CONST64(0xef62f9f9c3f99b3a), CONST64(0x97a3c5c533c566f6), CONST64(0x4a102525942535b1), CONST64(0xb2ab59597959f220),
205 CONST64(0x15d084842a8454ae), CONST64(0xe4c57272d572b7a7), CONST64(0x72ec3939e439d5dd), CONST64(0x98164c4c2d4c5a61),
206 CONST64(0xbc945e5e655eca3b), CONST64(0xf09f7878fd78e785), CONST64(0x70e53838e038ddd8), CONST64(0x05988c8c0a8c1486),
207 CONST64(0xbf17d1d163d1c6b2), CONST64(0x57e4a5a5aea5410b), CONST64(0xd9a1e2e2afe2434d), CONST64(0xc24e616199612ff8),
208 CONST64(0x7b42b3b3f6b3f145), CONST64(0x42342121842115a5), CONST64(0x25089c9c4a9c94d6), CONST64(0x3cee1e1e781ef066),
209 CONST64(0x8661434311432252), CONST64(0x93b1c7c73bc776fc), CONST64(0xe54ffcfcd7fcb32b), CONST64(0x0824040410042014),
210 CONST64(0xa2e351515951b208), CONST64(0x2f2599995e99bcc7), CONST64(0xda226d6da96d4fc4), CONST64(0x1a650d0d340d6839),
211 CONST64(0xe979fafacffa8335), CONST64(0xa369dfdf5bdfb684), CONST64(0xfca97e7ee57ed79b), CONST64(0x4819242490243db4),
212 CONST64(0x76fe3b3bec3bc5d7), CONST64(0x4b9aabab96ab313d), CONST64(0x81f0cece1fce3ed1), CONST64(0x2299111144118855),
213 CONST64(0x03838f8f068f0c89), CONST64(0x9c044e4e254e4a6b), CONST64(0x7366b7b7e6b7d151), CONST64(0xcbe0ebeb8beb0b60),
214 CONST64(0x78c13c3cf03cfdcc), CONST64(0x1ffd81813e817cbf), CONST64(0x354094946a94d4fe), CONST64(0xf31cf7f7fbf7eb0c),
215 CONST64(0x6f18b9b9deb9a167), CONST64(0x268b13134c13985f), CONST64(0x58512c2cb02c7d9c), CONST64(0xbb05d3d36bd3d6b8),
216 CONST64(0xd38ce7e7bbe76b5c), CONST64(0xdc396e6ea56e57cb), CONST64(0x95aac4c437c46ef3), CONST64(0x061b03030c03180f),
217 CONST64(0xacdc565645568a13), CONST64(0x885e44440d441a49), CONST64(0xfea07f7fe17fdf9e), CONST64(0x4f88a9a99ea92137),
218 CONST64(0x54672a2aa82a4d82), CONST64(0x6b0abbbbd6bbb16d), CONST64(0x9f87c1c123c146e2), CONST64(0xa6f153535153a202),
219 CONST64(0xa572dcdc57dcae8b), CONST64(0x16530b0b2c0b5827), CONST64(0x27019d9d4e9d9cd3), CONST64(0xd82b6c6cad6c47c1),
220 CONST64(0x62a43131c43195f5), CONST64(0xe8f37474cd7487b9), CONST64(0xf115f6f6fff6e309), CONST64(0x8c4c464605460a43),
221 CONST64(0x45a5acac8aac0926), CONST64(0x0fb589891e893c97), CONST64(0x28b414145014a044), CONST64(0xdfbae1e1a3e15b42),
222 CONST64(0x2ca616165816b04e), CONST64(0x74f73a3ae83acdd2), CONST64(0xd2066969b9696fd0), CONST64(0x124109092409482d),
223 CONST64(0xe0d77070dd70a7ad), CONST64(0x716fb6b6e2b6d954), CONST64(0xbd1ed0d067d0ceb7), CONST64(0xc7d6eded93ed3b7e),
224 CONST64(0x85e2cccc17cc2edb), CONST64(0x8468424215422a57), CONST64(0x2d2c98985a98b4c2), CONST64(0x55eda4a4aaa4490e),
225 CONST64(0x50752828a0285d88), CONST64(0xb8865c5c6d5cda31), CONST64(0xed6bf8f8c7f8933f), CONST64(0x11c28686228644a4)
226 };
227
228 static const ulong64 sbox3[] = {
229 CONST64(0x7830d818186018c0), CONST64(0xaf462623238c2305), CONST64(0xf991b8c6c63fc67e), CONST64(0x6fcdfbe8e887e813),
230 CONST64(0xa113cb878726874c), CONST64(0x626d11b8b8dab8a9), CONST64(0x0502090101040108), CONST64(0x6e9e0d4f4f214f42),
231 CONST64(0xee6c9b3636d836ad), CONST64(0x0451ffa6a6a2a659), CONST64(0xbdb90cd2d26fd2de), CONST64(0x06f70ef5f5f3f5fb),
232 CONST64(0x80f2967979f979ef), CONST64(0xcede306f6fa16f5f), CONST64(0xef3f6d91917e91fc), CONST64(0x07a4f852525552aa),
233 CONST64(0xfdc04760609d6027), CONST64(0x766535bcbccabc89), CONST64(0xcd2b379b9b569bac), CONST64(0x8c018a8e8e028e04),
234 CONST64(0x155bd2a3a3b6a371), CONST64(0x3c186c0c0c300c60), CONST64(0x8af6847b7bf17bff), CONST64(0xe16a803535d435b5),
235 CONST64(0x693af51d1d741de8), CONST64(0x47ddb3e0e0a7e053), CONST64(0xacb321d7d77bd7f6), CONST64(0xed999cc2c22fc25e),
236 CONST64(0x965c432e2eb82e6d), CONST64(0x7a96294b4b314b62), CONST64(0x21e15dfefedffea3), CONST64(0x16aed55757415782),
237 CONST64(0x412abd15155415a8), CONST64(0xb6eee87777c1779f), CONST64(0xeb6e923737dc37a5), CONST64(0x56d79ee5e5b3e57b),
238 CONST64(0xd923139f9f469f8c), CONST64(0x17fd23f0f0e7f0d3), CONST64(0x7f94204a4a354a6a), CONST64(0x95a944dada4fda9e),
239 CONST64(0x25b0a258587d58fa), CONST64(0xca8fcfc9c903c906), CONST64(0x8d527c2929a42955), CONST64(0x22145a0a0a280a50),
240 CONST64(0x4f7f50b1b1feb1e1), CONST64(0x1a5dc9a0a0baa069), CONST64(0xdad6146b6bb16b7f), CONST64(0xab17d985852e855c),
241 CONST64(0x73673cbdbdcebd81), CONST64(0x34ba8f5d5d695dd2), CONST64(0x5020901010401080), CONST64(0x03f507f4f4f7f4f3),
242 CONST64(0xc08bddcbcb0bcb16), CONST64(0xc67cd33e3ef83eed), CONST64(0x110a2d0505140528), CONST64(0xe6ce78676781671f),
243 CONST64(0x53d597e4e4b7e473), CONST64(0xbb4e0227279c2725), CONST64(0x5882734141194132), CONST64(0x9d0ba78b8b168b2c),
244 CONST64(0x0153f6a7a7a6a751), CONST64(0x94fab27d7de97dcf), CONST64(0xfb374995956e95dc), CONST64(0x9fad56d8d847d88e),
245 CONST64(0x30eb70fbfbcbfb8b), CONST64(0x71c1cdeeee9fee23), CONST64(0x91f8bb7c7ced7cc7), CONST64(0xe3cc716666856617),
246 CONST64(0x8ea77bdddd53dda6), CONST64(0x4b2eaf17175c17b8), CONST64(0x468e454747014702), CONST64(0xdc211a9e9e429e84),
247 CONST64(0xc589d4caca0fca1e), CONST64(0x995a582d2db42d75), CONST64(0x79632ebfbfc6bf91), CONST64(0x1b0e3f07071c0738),
248 CONST64(0x2347acadad8ead01), CONST64(0x2fb4b05a5a755aea), CONST64(0xb51bef838336836c), CONST64(0xff66b63333cc3385),
249 CONST64(0xf2c65c636391633f), CONST64(0x0a04120202080210), CONST64(0x384993aaaa92aa39), CONST64(0xa8e2de7171d971af),
250 CONST64(0xcf8dc6c8c807c80e), CONST64(0x7d32d119196419c8), CONST64(0x70923b4949394972), CONST64(0x9aaf5fd9d943d986),
251 CONST64(0x1df931f2f2eff2c3), CONST64(0x48dba8e3e3abe34b), CONST64(0x2ab6b95b5b715be2), CONST64(0x920dbc88881a8834),
252 CONST64(0xc8293e9a9a529aa4), CONST64(0xbe4c0b262698262d), CONST64(0xfa64bf3232c8328d), CONST64(0x4a7d59b0b0fab0e9),
253 CONST64(0x6acff2e9e983e91b), CONST64(0x331e770f0f3c0f78), CONST64(0xa6b733d5d573d5e6), CONST64(0xba1df480803a8074),
254 CONST64(0x7c6127bebec2be99), CONST64(0xde87ebcdcd13cd26), CONST64(0xe468893434d034bd), CONST64(0x75903248483d487a),
255 CONST64(0x24e354ffffdbffab), CONST64(0x8ff48d7a7af57af7), CONST64(0xea3d6490907a90f4), CONST64(0x3ebe9d5f5f615fc2),
256 CONST64(0xa0403d202080201d), CONST64(0xd5d00f6868bd6867), CONST64(0x7234ca1a1a681ad0), CONST64(0x2c41b7aeae82ae19),
257 CONST64(0x5e757db4b4eab4c9), CONST64(0x19a8ce54544d549a), CONST64(0xe53b7f93937693ec), CONST64(0xaa442f222288220d),
258 CONST64(0xe9c86364648d6407), CONST64(0x12ff2af1f1e3f1db), CONST64(0xa2e6cc7373d173bf), CONST64(0x5a24821212481290),
259 CONST64(0x5d807a40401d403a), CONST64(0x2810480808200840), CONST64(0xe89b95c3c32bc356), CONST64(0x7bc5dfecec97ec33),
260 CONST64(0x90ab4ddbdb4bdb96), CONST64(0x1f5fc0a1a1bea161), CONST64(0x8307918d8d0e8d1c), CONST64(0xc97ac83d3df43df5),
261 CONST64(0xf1335b97976697cc), CONST64(0x0000000000000000), CONST64(0xd483f9cfcf1bcf36), CONST64(0x87566e2b2bac2b45),
262 CONST64(0xb3ece17676c57697), CONST64(0xb019e68282328264), CONST64(0xa9b128d6d67fd6fe), CONST64(0x7736c31b1b6c1bd8),
263 CONST64(0x5b7774b5b5eeb5c1), CONST64(0x2943beafaf86af11), CONST64(0xdfd41d6a6ab56a77), CONST64(0x0da0ea50505d50ba),
264 CONST64(0x4c8a574545094512), CONST64(0x18fb38f3f3ebf3cb), CONST64(0xf060ad3030c0309d), CONST64(0x74c3c4efef9bef2b),
265 CONST64(0xc37eda3f3ffc3fe5), CONST64(0x1caac75555495592), CONST64(0x1059dba2a2b2a279), CONST64(0x65c9e9eaea8fea03),
266 CONST64(0xecca6a656589650f), CONST64(0x686903babad2bab9), CONST64(0x935e4a2f2fbc2f65), CONST64(0xe79d8ec0c027c04e),
267 CONST64(0x81a160dede5fdebe), CONST64(0x6c38fc1c1c701ce0), CONST64(0x2ee746fdfdd3fdbb), CONST64(0x649a1f4d4d294d52),
268 CONST64(0xe0397692927292e4), CONST64(0xbceafa7575c9758f), CONST64(0x1e0c360606180630), CONST64(0x9809ae8a8a128a24),
269 CONST64(0x40794bb2b2f2b2f9), CONST64(0x59d185e6e6bfe663), CONST64(0x361c7e0e0e380e70), CONST64(0x633ee71f1f7c1ff8),
270 CONST64(0xf7c4556262956237), CONST64(0xa3b53ad4d477d4ee), CONST64(0x324d81a8a89aa829), CONST64(0xf4315296966296c4),
271 CONST64(0x3aef62f9f9c3f99b), CONST64(0xf697a3c5c533c566), CONST64(0xb14a102525942535), CONST64(0x20b2ab59597959f2),
272 CONST64(0xae15d084842a8454), CONST64(0xa7e4c57272d572b7), CONST64(0xdd72ec3939e439d5), CONST64(0x6198164c4c2d4c5a),
273 CONST64(0x3bbc945e5e655eca), CONST64(0x85f09f7878fd78e7), CONST64(0xd870e53838e038dd), CONST64(0x8605988c8c0a8c14),
274 CONST64(0xb2bf17d1d163d1c6), CONST64(0x0b57e4a5a5aea541), CONST64(0x4dd9a1e2e2afe243), CONST64(0xf8c24e616199612f),
275 CONST64(0x457b42b3b3f6b3f1), CONST64(0xa542342121842115), CONST64(0xd625089c9c4a9c94), CONST64(0x663cee1e1e781ef0),
276 CONST64(0x5286614343114322), CONST64(0xfc93b1c7c73bc776), CONST64(0x2be54ffcfcd7fcb3), CONST64(0x1408240404100420),
277 CONST64(0x08a2e351515951b2), CONST64(0xc72f2599995e99bc), CONST64(0xc4da226d6da96d4f), CONST64(0x391a650d0d340d68),
278 CONST64(0x35e979fafacffa83), CONST64(0x84a369dfdf5bdfb6), CONST64(0x9bfca97e7ee57ed7), CONST64(0xb44819242490243d),
279 CONST64(0xd776fe3b3bec3bc5), CONST64(0x3d4b9aabab96ab31), CONST64(0xd181f0cece1fce3e), CONST64(0x5522991111441188),
280 CONST64(0x8903838f8f068f0c), CONST64(0x6b9c044e4e254e4a), CONST64(0x517366b7b7e6b7d1), CONST64(0x60cbe0ebeb8beb0b),
281 CONST64(0xcc78c13c3cf03cfd), CONST64(0xbf1ffd81813e817c), CONST64(0xfe354094946a94d4), CONST64(0x0cf31cf7f7fbf7eb),
282 CONST64(0x676f18b9b9deb9a1), CONST64(0x5f268b13134c1398), CONST64(0x9c58512c2cb02c7d), CONST64(0xb8bb05d3d36bd3d6),
283 CONST64(0x5cd38ce7e7bbe76b), CONST64(0xcbdc396e6ea56e57), CONST64(0xf395aac4c437c46e), CONST64(0x0f061b03030c0318),
284 CONST64(0x13acdc565645568a), CONST64(0x49885e44440d441a), CONST64(0x9efea07f7fe17fdf), CONST64(0x374f88a9a99ea921),
285 CONST64(0x8254672a2aa82a4d), CONST64(0x6d6b0abbbbd6bbb1), CONST64(0xe29f87c1c123c146), CONST64(0x02a6f153535153a2),
286 CONST64(0x8ba572dcdc57dcae), CONST64(0x2716530b0b2c0b58), CONST64(0xd327019d9d4e9d9c), CONST64(0xc1d82b6c6cad6c47),
287 CONST64(0xf562a43131c43195), CONST64(0xb9e8f37474cd7487), CONST64(0x09f115f6f6fff6e3), CONST64(0x438c4c464605460a),
288 CONST64(0x2645a5acac8aac09), CONST64(0x970fb589891e893c), CONST64(0x4428b414145014a0), CONST64(0x42dfbae1e1a3e15b),
289 CONST64(0x4e2ca616165816b0), CONST64(0xd274f73a3ae83acd), CONST64(0xd0d2066969b9696f), CONST64(0x2d12410909240948),
290 CONST64(0xade0d77070dd70a7), CONST64(0x54716fb6b6e2b6d9), CONST64(0xb7bd1ed0d067d0ce), CONST64(0x7ec7d6eded93ed3b),
291 CONST64(0xdb85e2cccc17cc2e), CONST64(0x578468424215422a), CONST64(0xc22d2c98985a98b4), CONST64(0x0e55eda4a4aaa449),
292 CONST64(0x8850752828a0285d), CONST64(0x31b8865c5c6d5cda), CONST64(0x3fed6bf8f8c7f893), CONST64(0xa411c28686228644)
293 };
294
295 static const ulong64 sbox4[] = {
296 CONST64(0xc07830d818186018), CONST64(0x05af462623238c23), CONST64(0x7ef991b8c6c63fc6), CONST64(0x136fcdfbe8e887e8),
297 CONST64(0x4ca113cb87872687), CONST64(0xa9626d11b8b8dab8), CONST64(0x0805020901010401), CONST64(0x426e9e0d4f4f214f),
298 CONST64(0xadee6c9b3636d836), CONST64(0x590451ffa6a6a2a6), CONST64(0xdebdb90cd2d26fd2), CONST64(0xfb06f70ef5f5f3f5),
299 CONST64(0xef80f2967979f979), CONST64(0x5fcede306f6fa16f), CONST64(0xfcef3f6d91917e91), CONST64(0xaa07a4f852525552),
300 CONST64(0x27fdc04760609d60), CONST64(0x89766535bcbccabc), CONST64(0xaccd2b379b9b569b), CONST64(0x048c018a8e8e028e),
301 CONST64(0x71155bd2a3a3b6a3), CONST64(0x603c186c0c0c300c), CONST64(0xff8af6847b7bf17b), CONST64(0xb5e16a803535d435),
302 CONST64(0xe8693af51d1d741d), CONST64(0x5347ddb3e0e0a7e0), CONST64(0xf6acb321d7d77bd7), CONST64(0x5eed999cc2c22fc2),
303 CONST64(0x6d965c432e2eb82e), CONST64(0x627a96294b4b314b), CONST64(0xa321e15dfefedffe), CONST64(0x8216aed557574157),
304 CONST64(0xa8412abd15155415), CONST64(0x9fb6eee87777c177), CONST64(0xa5eb6e923737dc37), CONST64(0x7b56d79ee5e5b3e5),
305 CONST64(0x8cd923139f9f469f), CONST64(0xd317fd23f0f0e7f0), CONST64(0x6a7f94204a4a354a), CONST64(0x9e95a944dada4fda),
306 CONST64(0xfa25b0a258587d58), CONST64(0x06ca8fcfc9c903c9), CONST64(0x558d527c2929a429), CONST64(0x5022145a0a0a280a),
307 CONST64(0xe14f7f50b1b1feb1), CONST64(0x691a5dc9a0a0baa0), CONST64(0x7fdad6146b6bb16b), CONST64(0x5cab17d985852e85),
308 CONST64(0x8173673cbdbdcebd), CONST64(0xd234ba8f5d5d695d), CONST64(0x8050209010104010), CONST64(0xf303f507f4f4f7f4),
309 CONST64(0x16c08bddcbcb0bcb), CONST64(0xedc67cd33e3ef83e), CONST64(0x28110a2d05051405), CONST64(0x1fe6ce7867678167),
310 CONST64(0x7353d597e4e4b7e4), CONST64(0x25bb4e0227279c27), CONST64(0x3258827341411941), CONST64(0x2c9d0ba78b8b168b),
311 CONST64(0x510153f6a7a7a6a7), CONST64(0xcf94fab27d7de97d), CONST64(0xdcfb374995956e95), CONST64(0x8e9fad56d8d847d8),
312 CONST64(0x8b30eb70fbfbcbfb), CONST64(0x2371c1cdeeee9fee), CONST64(0xc791f8bb7c7ced7c), CONST64(0x17e3cc7166668566),
313 CONST64(0xa68ea77bdddd53dd), CONST64(0xb84b2eaf17175c17), CONST64(0x02468e4547470147), CONST64(0x84dc211a9e9e429e),
314 CONST64(0x1ec589d4caca0fca), CONST64(0x75995a582d2db42d), CONST64(0x9179632ebfbfc6bf), CONST64(0x381b0e3f07071c07),
315 CONST64(0x012347acadad8ead), CONST64(0xea2fb4b05a5a755a), CONST64(0x6cb51bef83833683), CONST64(0x85ff66b63333cc33),
316 CONST64(0x3ff2c65c63639163), CONST64(0x100a041202020802), CONST64(0x39384993aaaa92aa), CONST64(0xafa8e2de7171d971),
317 CONST64(0x0ecf8dc6c8c807c8), CONST64(0xc87d32d119196419), CONST64(0x7270923b49493949), CONST64(0x869aaf5fd9d943d9),
318 CONST64(0xc31df931f2f2eff2), CONST64(0x4b48dba8e3e3abe3), CONST64(0xe22ab6b95b5b715b), CONST64(0x34920dbc88881a88),
319 CONST64(0xa4c8293e9a9a529a), CONST64(0x2dbe4c0b26269826), CONST64(0x8dfa64bf3232c832), CONST64(0xe94a7d59b0b0fab0),
320 CONST64(0x1b6acff2e9e983e9), CONST64(0x78331e770f0f3c0f), CONST64(0xe6a6b733d5d573d5), CONST64(0x74ba1df480803a80),
321 CONST64(0x997c6127bebec2be), CONST64(0x26de87ebcdcd13cd), CONST64(0xbde468893434d034), CONST64(0x7a75903248483d48),
322 CONST64(0xab24e354ffffdbff), CONST64(0xf78ff48d7a7af57a), CONST64(0xf4ea3d6490907a90), CONST64(0xc23ebe9d5f5f615f),
323 CONST64(0x1da0403d20208020), CONST64(0x67d5d00f6868bd68), CONST64(0xd07234ca1a1a681a), CONST64(0x192c41b7aeae82ae),
324 CONST64(0xc95e757db4b4eab4), CONST64(0x9a19a8ce54544d54), CONST64(0xece53b7f93937693), CONST64(0x0daa442f22228822),
325 CONST64(0x07e9c86364648d64), CONST64(0xdb12ff2af1f1e3f1), CONST64(0xbfa2e6cc7373d173), CONST64(0x905a248212124812),
326 CONST64(0x3a5d807a40401d40), CONST64(0x4028104808082008), CONST64(0x56e89b95c3c32bc3), CONST64(0x337bc5dfecec97ec),
327 CONST64(0x9690ab4ddbdb4bdb), CONST64(0x611f5fc0a1a1bea1), CONST64(0x1c8307918d8d0e8d), CONST64(0xf5c97ac83d3df43d),
328 CONST64(0xccf1335b97976697), CONST64(0x0000000000000000), CONST64(0x36d483f9cfcf1bcf), CONST64(0x4587566e2b2bac2b),
329 CONST64(0x97b3ece17676c576), CONST64(0x64b019e682823282), CONST64(0xfea9b128d6d67fd6), CONST64(0xd87736c31b1b6c1b),
330 CONST64(0xc15b7774b5b5eeb5), CONST64(0x112943beafaf86af), CONST64(0x77dfd41d6a6ab56a), CONST64(0xba0da0ea50505d50),
331 CONST64(0x124c8a5745450945), CONST64(0xcb18fb38f3f3ebf3), CONST64(0x9df060ad3030c030), CONST64(0x2b74c3c4efef9bef),
332 CONST64(0xe5c37eda3f3ffc3f), CONST64(0x921caac755554955), CONST64(0x791059dba2a2b2a2), CONST64(0x0365c9e9eaea8fea),
333 CONST64(0x0fecca6a65658965), CONST64(0xb9686903babad2ba), CONST64(0x65935e4a2f2fbc2f), CONST64(0x4ee79d8ec0c027c0),
334 CONST64(0xbe81a160dede5fde), CONST64(0xe06c38fc1c1c701c), CONST64(0xbb2ee746fdfdd3fd), CONST64(0x52649a1f4d4d294d),
335 CONST64(0xe4e0397692927292), CONST64(0x8fbceafa7575c975), CONST64(0x301e0c3606061806), CONST64(0x249809ae8a8a128a),
336 CONST64(0xf940794bb2b2f2b2), CONST64(0x6359d185e6e6bfe6), CONST64(0x70361c7e0e0e380e), CONST64(0xf8633ee71f1f7c1f),
337 CONST64(0x37f7c45562629562), CONST64(0xeea3b53ad4d477d4), CONST64(0x29324d81a8a89aa8), CONST64(0xc4f4315296966296),
338 CONST64(0x9b3aef62f9f9c3f9), CONST64(0x66f697a3c5c533c5), CONST64(0x35b14a1025259425), CONST64(0xf220b2ab59597959),
339 CONST64(0x54ae15d084842a84), CONST64(0xb7a7e4c57272d572), CONST64(0xd5dd72ec3939e439), CONST64(0x5a6198164c4c2d4c),
340 CONST64(0xca3bbc945e5e655e), CONST64(0xe785f09f7878fd78), CONST64(0xddd870e53838e038), CONST64(0x148605988c8c0a8c),
341 CONST64(0xc6b2bf17d1d163d1), CONST64(0x410b57e4a5a5aea5), CONST64(0x434dd9a1e2e2afe2), CONST64(0x2ff8c24e61619961),
342 CONST64(0xf1457b42b3b3f6b3), CONST64(0x15a5423421218421), CONST64(0x94d625089c9c4a9c), CONST64(0xf0663cee1e1e781e),
343 CONST64(0x2252866143431143), CONST64(0x76fc93b1c7c73bc7), CONST64(0xb32be54ffcfcd7fc), CONST64(0x2014082404041004),
344 CONST64(0xb208a2e351515951), CONST64(0xbcc72f2599995e99), CONST64(0x4fc4da226d6da96d), CONST64(0x68391a650d0d340d),
345 CONST64(0x8335e979fafacffa), CONST64(0xb684a369dfdf5bdf), CONST64(0xd79bfca97e7ee57e), CONST64(0x3db4481924249024),
346 CONST64(0xc5d776fe3b3bec3b), CONST64(0x313d4b9aabab96ab), CONST64(0x3ed181f0cece1fce), CONST64(0x8855229911114411),
347 CONST64(0x0c8903838f8f068f), CONST64(0x4a6b9c044e4e254e), CONST64(0xd1517366b7b7e6b7), CONST64(0x0b60cbe0ebeb8beb),
348 CONST64(0xfdcc78c13c3cf03c), CONST64(0x7cbf1ffd81813e81), CONST64(0xd4fe354094946a94), CONST64(0xeb0cf31cf7f7fbf7),
349 CONST64(0xa1676f18b9b9deb9), CONST64(0x985f268b13134c13), CONST64(0x7d9c58512c2cb02c), CONST64(0xd6b8bb05d3d36bd3),
350 CONST64(0x6b5cd38ce7e7bbe7), CONST64(0x57cbdc396e6ea56e), CONST64(0x6ef395aac4c437c4), CONST64(0x180f061b03030c03),
351 CONST64(0x8a13acdc56564556), CONST64(0x1a49885e44440d44), CONST64(0xdf9efea07f7fe17f), CONST64(0x21374f88a9a99ea9),
352 CONST64(0x4d8254672a2aa82a), CONST64(0xb16d6b0abbbbd6bb), CONST64(0x46e29f87c1c123c1), CONST64(0xa202a6f153535153),
353 CONST64(0xae8ba572dcdc57dc), CONST64(0x582716530b0b2c0b), CONST64(0x9cd327019d9d4e9d), CONST64(0x47c1d82b6c6cad6c),
354 CONST64(0x95f562a43131c431), CONST64(0x87b9e8f37474cd74), CONST64(0xe309f115f6f6fff6), CONST64(0x0a438c4c46460546),
355 CONST64(0x092645a5acac8aac), CONST64(0x3c970fb589891e89), CONST64(0xa04428b414145014), CONST64(0x5b42dfbae1e1a3e1),
356 CONST64(0xb04e2ca616165816), CONST64(0xcdd274f73a3ae83a), CONST64(0x6fd0d2066969b969), CONST64(0x482d124109092409),
357 CONST64(0xa7ade0d77070dd70), CONST64(0xd954716fb6b6e2b6), CONST64(0xceb7bd1ed0d067d0), CONST64(0x3b7ec7d6eded93ed),
358 CONST64(0x2edb85e2cccc17cc), CONST64(0x2a57846842421542), CONST64(0xb4c22d2c98985a98), CONST64(0x490e55eda4a4aaa4),
359 CONST64(0x5d8850752828a028), CONST64(0xda31b8865c5c6d5c), CONST64(0x933fed6bf8f8c7f8), CONST64(0x44a411c286862286)
360 };
361
362 static const ulong64 sbox5[] = {
363 CONST64(0x18c07830d8181860), CONST64(0x2305af462623238c), CONST64(0xc67ef991b8c6c63f), CONST64(0xe8136fcdfbe8e887),
364 CONST64(0x874ca113cb878726), CONST64(0xb8a9626d11b8b8da), CONST64(0x0108050209010104), CONST64(0x4f426e9e0d4f4f21),
365 CONST64(0x36adee6c9b3636d8), CONST64(0xa6590451ffa6a6a2), CONST64(0xd2debdb90cd2d26f), CONST64(0xf5fb06f70ef5f5f3),
366 CONST64(0x79ef80f2967979f9), CONST64(0x6f5fcede306f6fa1), CONST64(0x91fcef3f6d91917e), CONST64(0x52aa07a4f8525255),
367 CONST64(0x6027fdc04760609d), CONST64(0xbc89766535bcbcca), CONST64(0x9baccd2b379b9b56), CONST64(0x8e048c018a8e8e02),
368 CONST64(0xa371155bd2a3a3b6), CONST64(0x0c603c186c0c0c30), CONST64(0x7bff8af6847b7bf1), CONST64(0x35b5e16a803535d4),
369 CONST64(0x1de8693af51d1d74), CONST64(0xe05347ddb3e0e0a7), CONST64(0xd7f6acb321d7d77b), CONST64(0xc25eed999cc2c22f),
370 CONST64(0x2e6d965c432e2eb8), CONST64(0x4b627a96294b4b31), CONST64(0xfea321e15dfefedf), CONST64(0x578216aed5575741),
371 CONST64(0x15a8412abd151554), CONST64(0x779fb6eee87777c1), CONST64(0x37a5eb6e923737dc), CONST64(0xe57b56d79ee5e5b3),
372 CONST64(0x9f8cd923139f9f46), CONST64(0xf0d317fd23f0f0e7), CONST64(0x4a6a7f94204a4a35), CONST64(0xda9e95a944dada4f),
373 CONST64(0x58fa25b0a258587d), CONST64(0xc906ca8fcfc9c903), CONST64(0x29558d527c2929a4), CONST64(0x0a5022145a0a0a28),
374 CONST64(0xb1e14f7f50b1b1fe), CONST64(0xa0691a5dc9a0a0ba), CONST64(0x6b7fdad6146b6bb1), CONST64(0x855cab17d985852e),
375 CONST64(0xbd8173673cbdbdce), CONST64(0x5dd234ba8f5d5d69), CONST64(0x1080502090101040), CONST64(0xf4f303f507f4f4f7),
376 CONST64(0xcb16c08bddcbcb0b), CONST64(0x3eedc67cd33e3ef8), CONST64(0x0528110a2d050514), CONST64(0x671fe6ce78676781),
377 CONST64(0xe47353d597e4e4b7), CONST64(0x2725bb4e0227279c), CONST64(0x4132588273414119), CONST64(0x8b2c9d0ba78b8b16),
378 CONST64(0xa7510153f6a7a7a6), CONST64(0x7dcf94fab27d7de9), CONST64(0x95dcfb374995956e), CONST64(0xd88e9fad56d8d847),
379 CONST64(0xfb8b30eb70fbfbcb), CONST64(0xee2371c1cdeeee9f), CONST64(0x7cc791f8bb7c7ced), CONST64(0x6617e3cc71666685),
380 CONST64(0xdda68ea77bdddd53), CONST64(0x17b84b2eaf17175c), CONST64(0x4702468e45474701), CONST64(0x9e84dc211a9e9e42),
381 CONST64(0xca1ec589d4caca0f), CONST64(0x2d75995a582d2db4), CONST64(0xbf9179632ebfbfc6), CONST64(0x07381b0e3f07071c),
382 CONST64(0xad012347acadad8e), CONST64(0x5aea2fb4b05a5a75), CONST64(0x836cb51bef838336), CONST64(0x3385ff66b63333cc),
383 CONST64(0x633ff2c65c636391), CONST64(0x02100a0412020208), CONST64(0xaa39384993aaaa92), CONST64(0x71afa8e2de7171d9),
384 CONST64(0xc80ecf8dc6c8c807), CONST64(0x19c87d32d1191964), CONST64(0x497270923b494939), CONST64(0xd9869aaf5fd9d943),
385 CONST64(0xf2c31df931f2f2ef), CONST64(0xe34b48dba8e3e3ab), CONST64(0x5be22ab6b95b5b71), CONST64(0x8834920dbc88881a),
386 CONST64(0x9aa4c8293e9a9a52), CONST64(0x262dbe4c0b262698), CONST64(0x328dfa64bf3232c8), CONST64(0xb0e94a7d59b0b0fa),
387 CONST64(0xe91b6acff2e9e983), CONST64(0x0f78331e770f0f3c), CONST64(0xd5e6a6b733d5d573), CONST64(0x8074ba1df480803a),
388 CONST64(0xbe997c6127bebec2), CONST64(0xcd26de87ebcdcd13), CONST64(0x34bde468893434d0), CONST64(0x487a75903248483d),
389 CONST64(0xffab24e354ffffdb), CONST64(0x7af78ff48d7a7af5), CONST64(0x90f4ea3d6490907a), CONST64(0x5fc23ebe9d5f5f61),
390 CONST64(0x201da0403d202080), CONST64(0x6867d5d00f6868bd), CONST64(0x1ad07234ca1a1a68), CONST64(0xae192c41b7aeae82),
391 CONST64(0xb4c95e757db4b4ea), CONST64(0x549a19a8ce54544d), CONST64(0x93ece53b7f939376), CONST64(0x220daa442f222288),
392 CONST64(0x6407e9c86364648d), CONST64(0xf1db12ff2af1f1e3), CONST64(0x73bfa2e6cc7373d1), CONST64(0x12905a2482121248),
393 CONST64(0x403a5d807a40401d), CONST64(0x0840281048080820), CONST64(0xc356e89b95c3c32b), CONST64(0xec337bc5dfecec97),
394 CONST64(0xdb9690ab4ddbdb4b), CONST64(0xa1611f5fc0a1a1be), CONST64(0x8d1c8307918d8d0e), CONST64(0x3df5c97ac83d3df4),
395 CONST64(0x97ccf1335b979766), CONST64(0x0000000000000000), CONST64(0xcf36d483f9cfcf1b), CONST64(0x2b4587566e2b2bac),
396 CONST64(0x7697b3ece17676c5), CONST64(0x8264b019e6828232), CONST64(0xd6fea9b128d6d67f), CONST64(0x1bd87736c31b1b6c),
397 CONST64(0xb5c15b7774b5b5ee), CONST64(0xaf112943beafaf86), CONST64(0x6a77dfd41d6a6ab5), CONST64(0x50ba0da0ea50505d),
398 CONST64(0x45124c8a57454509), CONST64(0xf3cb18fb38f3f3eb), CONST64(0x309df060ad3030c0), CONST64(0xef2b74c3c4efef9b),
399 CONST64(0x3fe5c37eda3f3ffc), CONST64(0x55921caac7555549), CONST64(0xa2791059dba2a2b2), CONST64(0xea0365c9e9eaea8f),
400 CONST64(0x650fecca6a656589), CONST64(0xbab9686903babad2), CONST64(0x2f65935e4a2f2fbc), CONST64(0xc04ee79d8ec0c027),
401 CONST64(0xdebe81a160dede5f), CONST64(0x1ce06c38fc1c1c70), CONST64(0xfdbb2ee746fdfdd3), CONST64(0x4d52649a1f4d4d29),
402 CONST64(0x92e4e03976929272), CONST64(0x758fbceafa7575c9), CONST64(0x06301e0c36060618), CONST64(0x8a249809ae8a8a12),
403 CONST64(0xb2f940794bb2b2f2), CONST64(0xe66359d185e6e6bf), CONST64(0x0e70361c7e0e0e38), CONST64(0x1ff8633ee71f1f7c),
404 CONST64(0x6237f7c455626295), CONST64(0xd4eea3b53ad4d477), CONST64(0xa829324d81a8a89a), CONST64(0x96c4f43152969662),
405 CONST64(0xf99b3aef62f9f9c3), CONST64(0xc566f697a3c5c533), CONST64(0x2535b14a10252594), CONST64(0x59f220b2ab595979),
406 CONST64(0x8454ae15d084842a), CONST64(0x72b7a7e4c57272d5), CONST64(0x39d5dd72ec3939e4), CONST64(0x4c5a6198164c4c2d),
407 CONST64(0x5eca3bbc945e5e65), CONST64(0x78e785f09f7878fd), CONST64(0x38ddd870e53838e0), CONST64(0x8c148605988c8c0a),
408 CONST64(0xd1c6b2bf17d1d163), CONST64(0xa5410b57e4a5a5ae), CONST64(0xe2434dd9a1e2e2af), CONST64(0x612ff8c24e616199),
409 CONST64(0xb3f1457b42b3b3f6), CONST64(0x2115a54234212184), CONST64(0x9c94d625089c9c4a), CONST64(0x1ef0663cee1e1e78),
410 CONST64(0x4322528661434311), CONST64(0xc776fc93b1c7c73b), CONST64(0xfcb32be54ffcfcd7), CONST64(0x0420140824040410),
411 CONST64(0x51b208a2e3515159), CONST64(0x99bcc72f2599995e), CONST64(0x6d4fc4da226d6da9), CONST64(0x0d68391a650d0d34),
412 CONST64(0xfa8335e979fafacf), CONST64(0xdfb684a369dfdf5b), CONST64(0x7ed79bfca97e7ee5), CONST64(0x243db44819242490),
413 CONST64(0x3bc5d776fe3b3bec), CONST64(0xab313d4b9aabab96), CONST64(0xce3ed181f0cece1f), CONST64(0x1188552299111144),
414 CONST64(0x8f0c8903838f8f06), CONST64(0x4e4a6b9c044e4e25), CONST64(0xb7d1517366b7b7e6), CONST64(0xeb0b60cbe0ebeb8b),
415 CONST64(0x3cfdcc78c13c3cf0), CONST64(0x817cbf1ffd81813e), CONST64(0x94d4fe354094946a), CONST64(0xf7eb0cf31cf7f7fb),
416 CONST64(0xb9a1676f18b9b9de), CONST64(0x13985f268b13134c), CONST64(0x2c7d9c58512c2cb0), CONST64(0xd3d6b8bb05d3d36b),
417 CONST64(0xe76b5cd38ce7e7bb), CONST64(0x6e57cbdc396e6ea5), CONST64(0xc46ef395aac4c437), CONST64(0x03180f061b03030c),
418 CONST64(0x568a13acdc565645), CONST64(0x441a49885e44440d), CONST64(0x7fdf9efea07f7fe1), CONST64(0xa921374f88a9a99e),
419 CONST64(0x2a4d8254672a2aa8), CONST64(0xbbb16d6b0abbbbd6), CONST64(0xc146e29f87c1c123), CONST64(0x53a202a6f1535351),
420 CONST64(0xdcae8ba572dcdc57), CONST64(0x0b582716530b0b2c), CONST64(0x9d9cd327019d9d4e), CONST64(0x6c47c1d82b6c6cad),
421 CONST64(0x3195f562a43131c4), CONST64(0x7487b9e8f37474cd), CONST64(0xf6e309f115f6f6ff), CONST64(0x460a438c4c464605),
422 CONST64(0xac092645a5acac8a), CONST64(0x893c970fb589891e), CONST64(0x14a04428b4141450), CONST64(0xe15b42dfbae1e1a3),
423 CONST64(0x16b04e2ca6161658), CONST64(0x3acdd274f73a3ae8), CONST64(0x696fd0d2066969b9), CONST64(0x09482d1241090924),
424 CONST64(0x70a7ade0d77070dd), CONST64(0xb6d954716fb6b6e2), CONST64(0xd0ceb7bd1ed0d067), CONST64(0xed3b7ec7d6eded93),
425 CONST64(0xcc2edb85e2cccc17), CONST64(0x422a578468424215), CONST64(0x98b4c22d2c98985a), CONST64(0xa4490e55eda4a4aa),
426 CONST64(0x285d8850752828a0), CONST64(0x5cda31b8865c5c6d), CONST64(0xf8933fed6bf8f8c7), CONST64(0x8644a411c2868622)
427 };
428
429 static const ulong64 sbox6[] = {
430 CONST64(0x6018c07830d81818), CONST64(0x8c2305af46262323), CONST64(0x3fc67ef991b8c6c6), CONST64(0x87e8136fcdfbe8e8),
431 CONST64(0x26874ca113cb8787), CONST64(0xdab8a9626d11b8b8), CONST64(0x0401080502090101), CONST64(0x214f426e9e0d4f4f),
432 CONST64(0xd836adee6c9b3636), CONST64(0xa2a6590451ffa6a6), CONST64(0x6fd2debdb90cd2d2), CONST64(0xf3f5fb06f70ef5f5),
433 CONST64(0xf979ef80f2967979), CONST64(0xa16f5fcede306f6f), CONST64(0x7e91fcef3f6d9191), CONST64(0x5552aa07a4f85252),
434 CONST64(0x9d6027fdc0476060), CONST64(0xcabc89766535bcbc), CONST64(0x569baccd2b379b9b), CONST64(0x028e048c018a8e8e),
435 CONST64(0xb6a371155bd2a3a3), CONST64(0x300c603c186c0c0c), CONST64(0xf17bff8af6847b7b), CONST64(0xd435b5e16a803535),
436 CONST64(0x741de8693af51d1d), CONST64(0xa7e05347ddb3e0e0), CONST64(0x7bd7f6acb321d7d7), CONST64(0x2fc25eed999cc2c2),
437 CONST64(0xb82e6d965c432e2e), CONST64(0x314b627a96294b4b), CONST64(0xdffea321e15dfefe), CONST64(0x41578216aed55757),
438 CONST64(0x5415a8412abd1515), CONST64(0xc1779fb6eee87777), CONST64(0xdc37a5eb6e923737), CONST64(0xb3e57b56d79ee5e5),
439 CONST64(0x469f8cd923139f9f), CONST64(0xe7f0d317fd23f0f0), CONST64(0x354a6a7f94204a4a), CONST64(0x4fda9e95a944dada),
440 CONST64(0x7d58fa25b0a25858), CONST64(0x03c906ca8fcfc9c9), CONST64(0xa429558d527c2929), CONST64(0x280a5022145a0a0a),
441 CONST64(0xfeb1e14f7f50b1b1), CONST64(0xbaa0691a5dc9a0a0), CONST64(0xb16b7fdad6146b6b), CONST64(0x2e855cab17d98585),
442 CONST64(0xcebd8173673cbdbd), CONST64(0x695dd234ba8f5d5d), CONST64(0x4010805020901010), CONST64(0xf7f4f303f507f4f4),
443 CONST64(0x0bcb16c08bddcbcb), CONST64(0xf83eedc67cd33e3e), CONST64(0x140528110a2d0505), CONST64(0x81671fe6ce786767),
444 CONST64(0xb7e47353d597e4e4), CONST64(0x9c2725bb4e022727), CONST64(0x1941325882734141), CONST64(0x168b2c9d0ba78b8b),
445 CONST64(0xa6a7510153f6a7a7), CONST64(0xe97dcf94fab27d7d), CONST64(0x6e95dcfb37499595), CONST64(0x47d88e9fad56d8d8),
446 CONST64(0xcbfb8b30eb70fbfb), CONST64(0x9fee2371c1cdeeee), CONST64(0xed7cc791f8bb7c7c), CONST64(0x856617e3cc716666),
447 CONST64(0x53dda68ea77bdddd), CONST64(0x5c17b84b2eaf1717), CONST64(0x014702468e454747), CONST64(0x429e84dc211a9e9e),
448 CONST64(0x0fca1ec589d4caca), CONST64(0xb42d75995a582d2d), CONST64(0xc6bf9179632ebfbf), CONST64(0x1c07381b0e3f0707),
449 CONST64(0x8ead012347acadad), CONST64(0x755aea2fb4b05a5a), CONST64(0x36836cb51bef8383), CONST64(0xcc3385ff66b63333),
450 CONST64(0x91633ff2c65c6363), CONST64(0x0802100a04120202), CONST64(0x92aa39384993aaaa), CONST64(0xd971afa8e2de7171),
451 CONST64(0x07c80ecf8dc6c8c8), CONST64(0x6419c87d32d11919), CONST64(0x39497270923b4949), CONST64(0x43d9869aaf5fd9d9),
452 CONST64(0xeff2c31df931f2f2), CONST64(0xabe34b48dba8e3e3), CONST64(0x715be22ab6b95b5b), CONST64(0x1a8834920dbc8888),
453 CONST64(0x529aa4c8293e9a9a), CONST64(0x98262dbe4c0b2626), CONST64(0xc8328dfa64bf3232), CONST64(0xfab0e94a7d59b0b0),
454 CONST64(0x83e91b6acff2e9e9), CONST64(0x3c0f78331e770f0f), CONST64(0x73d5e6a6b733d5d5), CONST64(0x3a8074ba1df48080),
455 CONST64(0xc2be997c6127bebe), CONST64(0x13cd26de87ebcdcd), CONST64(0xd034bde468893434), CONST64(0x3d487a7590324848),
456 CONST64(0xdbffab24e354ffff), CONST64(0xf57af78ff48d7a7a), CONST64(0x7a90f4ea3d649090), CONST64(0x615fc23ebe9d5f5f),
457 CONST64(0x80201da0403d2020), CONST64(0xbd6867d5d00f6868), CONST64(0x681ad07234ca1a1a), CONST64(0x82ae192c41b7aeae),
458 CONST64(0xeab4c95e757db4b4), CONST64(0x4d549a19a8ce5454), CONST64(0x7693ece53b7f9393), CONST64(0x88220daa442f2222),
459 CONST64(0x8d6407e9c8636464), CONST64(0xe3f1db12ff2af1f1), CONST64(0xd173bfa2e6cc7373), CONST64(0x4812905a24821212),
460 CONST64(0x1d403a5d807a4040), CONST64(0x2008402810480808), CONST64(0x2bc356e89b95c3c3), CONST64(0x97ec337bc5dfecec),
461 CONST64(0x4bdb9690ab4ddbdb), CONST64(0xbea1611f5fc0a1a1), CONST64(0x0e8d1c8307918d8d), CONST64(0xf43df5c97ac83d3d),
462 CONST64(0x6697ccf1335b9797), CONST64(0x0000000000000000), CONST64(0x1bcf36d483f9cfcf), CONST64(0xac2b4587566e2b2b),
463 CONST64(0xc57697b3ece17676), CONST64(0x328264b019e68282), CONST64(0x7fd6fea9b128d6d6), CONST64(0x6c1bd87736c31b1b),
464 CONST64(0xeeb5c15b7774b5b5), CONST64(0x86af112943beafaf), CONST64(0xb56a77dfd41d6a6a), CONST64(0x5d50ba0da0ea5050),
465 CONST64(0x0945124c8a574545), CONST64(0xebf3cb18fb38f3f3), CONST64(0xc0309df060ad3030), CONST64(0x9bef2b74c3c4efef),
466 CONST64(0xfc3fe5c37eda3f3f), CONST64(0x4955921caac75555), CONST64(0xb2a2791059dba2a2), CONST64(0x8fea0365c9e9eaea),
467 CONST64(0x89650fecca6a6565), CONST64(0xd2bab9686903baba), CONST64(0xbc2f65935e4a2f2f), CONST64(0x27c04ee79d8ec0c0),
468 CONST64(0x5fdebe81a160dede), CONST64(0x701ce06c38fc1c1c), CONST64(0xd3fdbb2ee746fdfd), CONST64(0x294d52649a1f4d4d),
469 CONST64(0x7292e4e039769292), CONST64(0xc9758fbceafa7575), CONST64(0x1806301e0c360606), CONST64(0x128a249809ae8a8a),
470 CONST64(0xf2b2f940794bb2b2), CONST64(0xbfe66359d185e6e6), CONST64(0x380e70361c7e0e0e), CONST64(0x7c1ff8633ee71f1f),
471 CONST64(0x956237f7c4556262), CONST64(0x77d4eea3b53ad4d4), CONST64(0x9aa829324d81a8a8), CONST64(0x6296c4f431529696),
472 CONST64(0xc3f99b3aef62f9f9), CONST64(0x33c566f697a3c5c5), CONST64(0x942535b14a102525), CONST64(0x7959f220b2ab5959),
473 CONST64(0x2a8454ae15d08484), CONST64(0xd572b7a7e4c57272), CONST64(0xe439d5dd72ec3939), CONST64(0x2d4c5a6198164c4c),
474 CONST64(0x655eca3bbc945e5e), CONST64(0xfd78e785f09f7878), CONST64(0xe038ddd870e53838), CONST64(0x0a8c148605988c8c),
475 CONST64(0x63d1c6b2bf17d1d1), CONST64(0xaea5410b57e4a5a5), CONST64(0xafe2434dd9a1e2e2), CONST64(0x99612ff8c24e6161),
476 CONST64(0xf6b3f1457b42b3b3), CONST64(0x842115a542342121), CONST64(0x4a9c94d625089c9c), CONST64(0x781ef0663cee1e1e),
477 CONST64(0x1143225286614343), CONST64(0x3bc776fc93b1c7c7), CONST64(0xd7fcb32be54ffcfc), CONST64(0x1004201408240404),
478 CONST64(0x5951b208a2e35151), CONST64(0x5e99bcc72f259999), CONST64(0xa96d4fc4da226d6d), CONST64(0x340d68391a650d0d),
479 CONST64(0xcffa8335e979fafa), CONST64(0x5bdfb684a369dfdf), CONST64(0xe57ed79bfca97e7e), CONST64(0x90243db448192424),
480 CONST64(0xec3bc5d776fe3b3b), CONST64(0x96ab313d4b9aabab), CONST64(0x1fce3ed181f0cece), CONST64(0x4411885522991111),
481 CONST64(0x068f0c8903838f8f), CONST64(0x254e4a6b9c044e4e), CONST64(0xe6b7d1517366b7b7), CONST64(0x8beb0b60cbe0ebeb),
482 CONST64(0xf03cfdcc78c13c3c), CONST64(0x3e817cbf1ffd8181), CONST64(0x6a94d4fe35409494), CONST64(0xfbf7eb0cf31cf7f7),
483 CONST64(0xdeb9a1676f18b9b9), CONST64(0x4c13985f268b1313), CONST64(0xb02c7d9c58512c2c), CONST64(0x6bd3d6b8bb05d3d3),
484 CONST64(0xbbe76b5cd38ce7e7), CONST64(0xa56e57cbdc396e6e), CONST64(0x37c46ef395aac4c4), CONST64(0x0c03180f061b0303),
485 CONST64(0x45568a13acdc5656), CONST64(0x0d441a49885e4444), CONST64(0xe17fdf9efea07f7f), CONST64(0x9ea921374f88a9a9),
486 CONST64(0xa82a4d8254672a2a), CONST64(0xd6bbb16d6b0abbbb), CONST64(0x23c146e29f87c1c1), CONST64(0x5153a202a6f15353),
487 CONST64(0x57dcae8ba572dcdc), CONST64(0x2c0b582716530b0b), CONST64(0x4e9d9cd327019d9d), CONST64(0xad6c47c1d82b6c6c),
488 CONST64(0xc43195f562a43131), CONST64(0xcd7487b9e8f37474), CONST64(0xfff6e309f115f6f6), CONST64(0x05460a438c4c4646),
489 CONST64(0x8aac092645a5acac), CONST64(0x1e893c970fb58989), CONST64(0x5014a04428b41414), CONST64(0xa3e15b42dfbae1e1),
490 CONST64(0x5816b04e2ca61616), CONST64(0xe83acdd274f73a3a), CONST64(0xb9696fd0d2066969), CONST64(0x2409482d12410909),
491 CONST64(0xdd70a7ade0d77070), CONST64(0xe2b6d954716fb6b6), CONST64(0x67d0ceb7bd1ed0d0), CONST64(0x93ed3b7ec7d6eded),
492 CONST64(0x17cc2edb85e2cccc), CONST64(0x15422a5784684242), CONST64(0x5a98b4c22d2c9898), CONST64(0xaaa4490e55eda4a4),
493 CONST64(0xa0285d8850752828), CONST64(0x6d5cda31b8865c5c), CONST64(0xc7f8933fed6bf8f8), CONST64(0x228644a411c28686)
494 };
495
496 static const ulong64 sbox7[] = {
497 CONST64(0x186018c07830d818), CONST64(0x238c2305af462623), CONST64(0xc63fc67ef991b8c6), CONST64(0xe887e8136fcdfbe8),
498 CONST64(0x8726874ca113cb87), CONST64(0xb8dab8a9626d11b8), CONST64(0x0104010805020901), CONST64(0x4f214f426e9e0d4f),
499 CONST64(0x36d836adee6c9b36), CONST64(0xa6a2a6590451ffa6), CONST64(0xd26fd2debdb90cd2), CONST64(0xf5f3f5fb06f70ef5),
500 CONST64(0x79f979ef80f29679), CONST64(0x6fa16f5fcede306f), CONST64(0x917e91fcef3f6d91), CONST64(0x525552aa07a4f852),
501 CONST64(0x609d6027fdc04760), CONST64(0xbccabc89766535bc), CONST64(0x9b569baccd2b379b), CONST64(0x8e028e048c018a8e),
502 CONST64(0xa3b6a371155bd2a3), CONST64(0x0c300c603c186c0c), CONST64(0x7bf17bff8af6847b), CONST64(0x35d435b5e16a8035),
503 CONST64(0x1d741de8693af51d), CONST64(0xe0a7e05347ddb3e0), CONST64(0xd77bd7f6acb321d7), CONST64(0xc22fc25eed999cc2),
504 CONST64(0x2eb82e6d965c432e), CONST64(0x4b314b627a96294b), CONST64(0xfedffea321e15dfe), CONST64(0x5741578216aed557),
505 CONST64(0x155415a8412abd15), CONST64(0x77c1779fb6eee877), CONST64(0x37dc37a5eb6e9237), CONST64(0xe5b3e57b56d79ee5),
506 CONST64(0x9f469f8cd923139f), CONST64(0xf0e7f0d317fd23f0), CONST64(0x4a354a6a7f94204a), CONST64(0xda4fda9e95a944da),
507 CONST64(0x587d58fa25b0a258), CONST64(0xc903c906ca8fcfc9), CONST64(0x29a429558d527c29), CONST64(0x0a280a5022145a0a),
508 CONST64(0xb1feb1e14f7f50b1), CONST64(0xa0baa0691a5dc9a0), CONST64(0x6bb16b7fdad6146b), CONST64(0x852e855cab17d985),
509 CONST64(0xbdcebd8173673cbd), CONST64(0x5d695dd234ba8f5d), CONST64(0x1040108050209010), CONST64(0xf4f7f4f303f507f4),
510 CONST64(0xcb0bcb16c08bddcb), CONST64(0x3ef83eedc67cd33e), CONST64(0x05140528110a2d05), CONST64(0x6781671fe6ce7867),
511 CONST64(0xe4b7e47353d597e4), CONST64(0x279c2725bb4e0227), CONST64(0x4119413258827341), CONST64(0x8b168b2c9d0ba78b),
512 CONST64(0xa7a6a7510153f6a7), CONST64(0x7de97dcf94fab27d), CONST64(0x956e95dcfb374995), CONST64(0xd847d88e9fad56d8),
513 CONST64(0xfbcbfb8b30eb70fb), CONST64(0xee9fee2371c1cdee), CONST64(0x7ced7cc791f8bb7c), CONST64(0x66856617e3cc7166),
514 CONST64(0xdd53dda68ea77bdd), CONST64(0x175c17b84b2eaf17), CONST64(0x47014702468e4547), CONST64(0x9e429e84dc211a9e),
515 CONST64(0xca0fca1ec589d4ca), CONST64(0x2db42d75995a582d), CONST64(0xbfc6bf9179632ebf), CONST64(0x071c07381b0e3f07),
516 CONST64(0xad8ead012347acad), CONST64(0x5a755aea2fb4b05a), CONST64(0x8336836cb51bef83), CONST64(0x33cc3385ff66b633),
517 CONST64(0x6391633ff2c65c63), CONST64(0x020802100a041202), CONST64(0xaa92aa39384993aa), CONST64(0x71d971afa8e2de71),
518 CONST64(0xc807c80ecf8dc6c8), CONST64(0x196419c87d32d119), CONST64(0x4939497270923b49), CONST64(0xd943d9869aaf5fd9),
519 CONST64(0xf2eff2c31df931f2), CONST64(0xe3abe34b48dba8e3), CONST64(0x5b715be22ab6b95b), CONST64(0x881a8834920dbc88),
520 CONST64(0x9a529aa4c8293e9a), CONST64(0x2698262dbe4c0b26), CONST64(0x32c8328dfa64bf32), CONST64(0xb0fab0e94a7d59b0),
521 CONST64(0xe983e91b6acff2e9), CONST64(0x0f3c0f78331e770f), CONST64(0xd573d5e6a6b733d5), CONST64(0x803a8074ba1df480),
522 CONST64(0xbec2be997c6127be), CONST64(0xcd13cd26de87ebcd), CONST64(0x34d034bde4688934), CONST64(0x483d487a75903248),
523 CONST64(0xffdbffab24e354ff), CONST64(0x7af57af78ff48d7a), CONST64(0x907a90f4ea3d6490), CONST64(0x5f615fc23ebe9d5f),
524 CONST64(0x2080201da0403d20), CONST64(0x68bd6867d5d00f68), CONST64(0x1a681ad07234ca1a), CONST64(0xae82ae192c41b7ae),
525 CONST64(0xb4eab4c95e757db4), CONST64(0x544d549a19a8ce54), CONST64(0x937693ece53b7f93), CONST64(0x2288220daa442f22),
526 CONST64(0x648d6407e9c86364), CONST64(0xf1e3f1db12ff2af1), CONST64(0x73d173bfa2e6cc73), CONST64(0x124812905a248212),
527 CONST64(0x401d403a5d807a40), CONST64(0x0820084028104808), CONST64(0xc32bc356e89b95c3), CONST64(0xec97ec337bc5dfec),
528 CONST64(0xdb4bdb9690ab4ddb), CONST64(0xa1bea1611f5fc0a1), CONST64(0x8d0e8d1c8307918d), CONST64(0x3df43df5c97ac83d),
529 CONST64(0x976697ccf1335b97), CONST64(0x0000000000000000), CONST64(0xcf1bcf36d483f9cf), CONST64(0x2bac2b4587566e2b),
530 CONST64(0x76c57697b3ece176), CONST64(0x82328264b019e682), CONST64(0xd67fd6fea9b128d6), CONST64(0x1b6c1bd87736c31b),
531 CONST64(0xb5eeb5c15b7774b5), CONST64(0xaf86af112943beaf), CONST64(0x6ab56a77dfd41d6a), CONST64(0x505d50ba0da0ea50),
532 CONST64(0x450945124c8a5745), CONST64(0xf3ebf3cb18fb38f3), CONST64(0x30c0309df060ad30), CONST64(0xef9bef2b74c3c4ef),
533 CONST64(0x3ffc3fe5c37eda3f), CONST64(0x554955921caac755), CONST64(0xa2b2a2791059dba2), CONST64(0xea8fea0365c9e9ea),
534 CONST64(0x6589650fecca6a65), CONST64(0xbad2bab9686903ba), CONST64(0x2fbc2f65935e4a2f), CONST64(0xc027c04ee79d8ec0),
535 CONST64(0xde5fdebe81a160de), CONST64(0x1c701ce06c38fc1c), CONST64(0xfdd3fdbb2ee746fd), CONST64(0x4d294d52649a1f4d),
536 CONST64(0x927292e4e0397692), CONST64(0x75c9758fbceafa75), CONST64(0x061806301e0c3606), CONST64(0x8a128a249809ae8a),
537 CONST64(0xb2f2b2f940794bb2), CONST64(0xe6bfe66359d185e6), CONST64(0x0e380e70361c7e0e), CONST64(0x1f7c1ff8633ee71f),
538 CONST64(0x62956237f7c45562), CONST64(0xd477d4eea3b53ad4), CONST64(0xa89aa829324d81a8), CONST64(0x966296c4f4315296),
539 CONST64(0xf9c3f99b3aef62f9), CONST64(0xc533c566f697a3c5), CONST64(0x25942535b14a1025), CONST64(0x597959f220b2ab59),
540 CONST64(0x842a8454ae15d084), CONST64(0x72d572b7a7e4c572), CONST64(0x39e439d5dd72ec39), CONST64(0x4c2d4c5a6198164c),
541 CONST64(0x5e655eca3bbc945e), CONST64(0x78fd78e785f09f78), CONST64(0x38e038ddd870e538), CONST64(0x8c0a8c148605988c),
542 CONST64(0xd163d1c6b2bf17d1), CONST64(0xa5aea5410b57e4a5), CONST64(0xe2afe2434dd9a1e2), CONST64(0x6199612ff8c24e61),
543 CONST64(0xb3f6b3f1457b42b3), CONST64(0x21842115a5423421), CONST64(0x9c4a9c94d625089c), CONST64(0x1e781ef0663cee1e),
544 CONST64(0x4311432252866143), CONST64(0xc73bc776fc93b1c7), CONST64(0xfcd7fcb32be54ffc), CONST64(0x0410042014082404),
545 CONST64(0x515951b208a2e351), CONST64(0x995e99bcc72f2599), CONST64(0x6da96d4fc4da226d), CONST64(0x0d340d68391a650d),
546 CONST64(0xfacffa8335e979fa), CONST64(0xdf5bdfb684a369df), CONST64(0x7ee57ed79bfca97e), CONST64(0x2490243db4481924),
547 CONST64(0x3bec3bc5d776fe3b), CONST64(0xab96ab313d4b9aab), CONST64(0xce1fce3ed181f0ce), CONST64(0x1144118855229911),
548 CONST64(0x8f068f0c8903838f), CONST64(0x4e254e4a6b9c044e), CONST64(0xb7e6b7d1517366b7), CONST64(0xeb8beb0b60cbe0eb),
549 CONST64(0x3cf03cfdcc78c13c), CONST64(0x813e817cbf1ffd81), CONST64(0x946a94d4fe354094), CONST64(0xf7fbf7eb0cf31cf7),
550 CONST64(0xb9deb9a1676f18b9), CONST64(0x134c13985f268b13), CONST64(0x2cb02c7d9c58512c), CONST64(0xd36bd3d6b8bb05d3),
551 CONST64(0xe7bbe76b5cd38ce7), CONST64(0x6ea56e57cbdc396e), CONST64(0xc437c46ef395aac4), CONST64(0x030c03180f061b03),
552 CONST64(0x5645568a13acdc56), CONST64(0x440d441a49885e44), CONST64(0x7fe17fdf9efea07f), CONST64(0xa99ea921374f88a9),
553 CONST64(0x2aa82a4d8254672a), CONST64(0xbbd6bbb16d6b0abb), CONST64(0xc123c146e29f87c1), CONST64(0x535153a202a6f153),
554 CONST64(0xdc57dcae8ba572dc), CONST64(0x0b2c0b582716530b), CONST64(0x9d4e9d9cd327019d), CONST64(0x6cad6c47c1d82b6c),
555 CONST64(0x31c43195f562a431), CONST64(0x74cd7487b9e8f374), CONST64(0xf6fff6e309f115f6), CONST64(0x4605460a438c4c46),
556 CONST64(0xac8aac092645a5ac), CONST64(0x891e893c970fb589), CONST64(0x145014a04428b414), CONST64(0xe1a3e15b42dfbae1),
557 CONST64(0x165816b04e2ca616), CONST64(0x3ae83acdd274f73a), CONST64(0x69b9696fd0d20669), CONST64(0x092409482d124109),
558 CONST64(0x70dd70a7ade0d770), CONST64(0xb6e2b6d954716fb6), CONST64(0xd067d0ceb7bd1ed0), CONST64(0xed93ed3b7ec7d6ed),
559 CONST64(0xcc17cc2edb85e2cc), CONST64(0x4215422a57846842), CONST64(0x985a98b4c22d2c98), CONST64(0xa4aaa4490e55eda4),
560 CONST64(0x28a0285d88507528), CONST64(0x5c6d5cda31b8865c), CONST64(0xf8c7f8933fed6bf8), CONST64(0x86228644a411c286)
561 };
562
563 #endif
564
565 static const ulong64 cont[] = {
566 CONST64(0x1823c6e887b8014f),
567 CONST64(0x36a6d2f5796f9152),
568 CONST64(0x60bc9b8ea30c7b35),
569 CONST64(0x1de0d7c22e4bfe57),
570 CONST64(0x157737e59ff04ada),
571 CONST64(0x58c9290ab1a06b85),
572 CONST64(0xbd5d10f4cb3e0567),
573 CONST64(0xe427418ba77d95d8),
574 CONST64(0xfbee7c66dd17479e),
575 CONST64(0xca2dbf07ad5a8333),
576 CONST64(0x6302aa71c81949d9),
577 };
578
579
580 /* $Source$ */
581 /* $Revision$ */
582 /* $Date$ */
0 #ifndef TOMCRYPT_H_
1 #define TOMCRYPT_H_
2 #include <assert.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <stddef.h>
7 #include <time.h>
8 #include <ctype.h>
9 #include <limits.h>
10
11 /* use configuration data */
12 #include <tomcrypt_custom.h>
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 /* version */
19 #define CRYPT 0x0117
20 #define SCRYPT "1.17"
21
22 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
23 #define MAXBLOCKSIZE 128
24
25 /* descriptor table size */
26 #define TAB_SIZE 32
27
28 /* error codes [will be expanded in future releases] */
29 enum {
30 CRYPT_OK=0, /* Result OK */
31 CRYPT_ERROR, /* Generic Error */
32 CRYPT_NOP, /* Not a failure but no operation was performed */
33
34 CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
35 CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */
36 CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */
37
38 CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */
39 CRYPT_INVALID_PACKET, /* Invalid input packet given */
40
41 CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
42 CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */
43
44 CRYPT_INVALID_CIPHER, /* Invalid cipher specified */
45 CRYPT_INVALID_HASH, /* Invalid hash specified */
46 CRYPT_INVALID_PRNG, /* Invalid PRNG specified */
47
48 CRYPT_MEM, /* Out of memory */
49
50 CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
51 CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */
52
53 CRYPT_INVALID_ARG, /* Generic invalid argument */
54 CRYPT_FILE_NOTFOUND, /* File Not Found */
55
56 CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */
57 CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */
58 CRYPT_PK_DUP, /* Duplicate key already in key ring */
59 CRYPT_PK_NOT_FOUND, /* Key not found in keyring */
60 CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */
61
62 CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
63 CRYPT_PK_INVALID_PADDING /* Invalid padding on input */
64 };
65
66 #include <tomcrypt_cfg.h>
67 #include <tomcrypt_macros.h>
68 #include <tomcrypt_cipher.h>
69 #include <tomcrypt_hash.h>
70 #include <tomcrypt_mac.h>
71 #include <tomcrypt_prng.h>
72 #include <tomcrypt_pk.h>
73 #include <tomcrypt_math.h>
74 #include <tomcrypt_misc.h>
75 #include <tomcrypt_argchk.h>
76 #include <tomcrypt_pkcs.h>
77 #include <tomcrypt_hkdf.h>
78
79 #ifdef __cplusplus
80 }
81 #endif
82
83 #endif /* TOMCRYPT_H_ */
84
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
0 /* Defines the LTC_ARGCHK macro used within the library */
1 /* ARGTYPE is defined in mycrypt_cfg.h */
2 #if ARGTYPE == 0
3
4 #include <signal.h>
5
6 /* this is the default LibTomCrypt macro */
7 void crypt_argchk(char *v, char *s, int d);
8 #define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); }
9 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
10
11 #elif ARGTYPE == 1
12
13 /* fatal type of error */
14 #define LTC_ARGCHK(x) assert((x))
15 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
16
17 #elif ARGTYPE == 2
18
19 #define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); }
20 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
21
22 #elif ARGTYPE == 3
23
24 #define LTC_ARGCHK(x)
25 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
26
27 #elif ARGTYPE == 4
28
29 #define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG;
30 #define LTC_ARGCHKVD(x) if (!(x)) return;
31
32 #endif
33
34
35 /* $Source$ */
36 /* $Revision$ */
37 /* $Date$ */
0 /* This is the build config file.
1 *
2 * With this you can setup what to inlcude/exclude automatically during any build. Just comment
3 * out the line that #define's the word for the thing you want to remove. phew!
4 */
5
6 #ifndef TOMCRYPT_CFG_H
7 #define TOMCRYPT_CFG_H
8
9 #if defined(_WIN32) || defined(_MSC_VER)
10 #define LTC_CALL __cdecl
11 #else
12 #ifndef LTC_CALL
13 #define LTC_CALL
14 #endif
15 #endif
16
17 #ifndef LTC_EXPORT
18 #define LTC_EXPORT
19 #endif
20
21 /* certain platforms use macros for these, making the prototypes broken */
22 #ifndef LTC_NO_PROTOTYPES
23
24 /* you can change how memory allocation works ... */
25 LTC_EXPORT void * LTC_CALL XMALLOC(size_t n);
26 LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n);
27 LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s);
28 LTC_EXPORT void LTC_CALL XFREE(void *p);
29
30 LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
31
32
33 /* change the clock function too */
34 LTC_EXPORT clock_t LTC_CALL XCLOCK(void);
35
36 /* various other functions */
37 LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n);
38 LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n);
39 LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n);
40
41 LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
42
43 #endif
44
45 /* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */
46 #ifndef ARGTYPE
47 #define ARGTYPE 0
48 #endif
49
50 /* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code
51 *
52 * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes.
53 * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST**
54 * use the portable [slower] macros.
55 */
56
57 /* detect x86-32 machines somewhat */
58 #if !defined(__STRICT_ANSI__) && !defined(_WIN64) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))))
59 #define ENDIAN_LITTLE
60 #define ENDIAN_32BITWORD
61 #define LTC_FAST
62 #define LTC_FAST_TYPE unsigned long
63 #endif
64
65 /* detects MIPS R5900 processors (PS2) */
66 #if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips))
67 #define ENDIAN_LITTLE
68 #define ENDIAN_64BITWORD
69 #endif
70
71 /* detect amd64 */
72 #ifdef _WIN64
73 #define ENDIAN_LITTLE
74 #define ENDIAN_64BITWORD
75 #define LTC_FAST
76 /* on 64bit ms windows 'unsigned long' is only 32bit we need 'long long'*/
77 #define LTC_FAST_TYPE unsigned long long
78 #else
79 #if !defined(__STRICT_ANSI__) && defined(__x86_64__)
80 #define ENDIAN_LITTLE
81 #define ENDIAN_64BITWORD
82 #define LTC_FAST
83 #define LTC_FAST_TYPE unsigned long
84 #endif
85 #endif
86
87 /* detect PPC32 */
88 #if !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
89 #define ENDIAN_BIG
90 #define ENDIAN_32BITWORD
91 #define LTC_FAST
92 #define LTC_FAST_TYPE unsigned long
93 #endif
94
95 /* detect sparc and sparc64 */
96 #if defined(__sparc__)
97 #define ENDIAN_BIG
98 #if defined(__arch64__)
99 #define ENDIAN_64BITWORD
100 #else
101 #define ENDIAN_32BITWORD
102 #endif
103 #endif
104
105
106 #ifdef LTC_NO_FAST
107 #ifdef LTC_FAST
108 #undef LTC_FAST
109 #endif
110 #endif
111
112 /* No asm is a quick way to disable anything "not portable" */
113 #ifdef LTC_NO_ASM
114 #undef ENDIAN_LITTLE
115 #undef ENDIAN_BIG
116 #undef ENDIAN_32BITWORD
117 #undef ENDIAN_64BITWORD
118 #undef LTC_FAST
119 #undef LTC_FAST_TYPE
120 #define LTC_NO_ROLC
121 #define LTC_NO_BSWAP
122 #endif
123
124 /* #define ENDIAN_LITTLE */
125 /* #define ENDIAN_BIG */
126
127 /* #define ENDIAN_32BITWORD */
128 /* #define ENDIAN_64BITWORD */
129
130 #if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
131 #error You must specify a word size as well as endianess in tomcrypt_cfg.h
132 #endif
133
134 #if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
135 #define ENDIAN_NEUTRAL
136 #endif
137
138 /* gcc 4.3 and up has a bswap builtin; detect it by gcc version.
139 * clang also supports the bswap builtin, and although clang pretends
140 * to be gcc (macro-wise, anyway), clang pretends to be a version
141 * prior to gcc 4.3, so we can't detect bswap that way. Instead,
142 * clang has a __has_builtin mechanism that can be used to check
143 * for builtins:
144 * http://clang.llvm.org/docs/LanguageExtensions.html#feature_check */
145 #ifndef __has_builtin
146 #define __has_builtin(x) 0
147 #endif
148 #if !defined(LTC_NO_BSWAP) && defined(__GNUC__) && \
149 ((__GNUC__ * 100 + __GNUC_MINOR__ >= 403) || \
150 (__has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)))
151 #define LTC_HAVE_BSWAP_BUILTIN
152 #endif
153
154 #endif
155
156
157 /* $Source$ */
158 /* $Revision$ */
159 /* $Date$ */
0 /* ---- SYMMETRIC KEY STUFF -----
1 *
2 * We put each of the ciphers scheduled keys in their own structs then we put all of
3 * the key formats in one union. This makes the function prototypes easier to use.
4 */
5 #ifdef LTC_BLOWFISH
6 struct blowfish_key {
7 ulong32 S[4][256];
8 ulong32 K[18];
9 };
10 #endif
11
12 #ifdef LTC_RC5
13 struct rc5_key {
14 int rounds;
15 ulong32 K[50];
16 };
17 #endif
18
19 #ifdef LTC_RC6
20 struct rc6_key {
21 ulong32 K[44];
22 };
23 #endif
24
25 #ifdef LTC_SAFERP
26 struct saferp_key {
27 unsigned char K[33][16];
28 long rounds;
29 };
30 #endif
31
32 #ifdef LTC_RIJNDAEL
33 struct rijndael_key {
34 ulong32 eK[60], dK[60];
35 int Nr;
36 };
37 #endif
38
39 #ifdef LTC_KSEED
40 struct kseed_key {
41 ulong32 K[32], dK[32];
42 };
43 #endif
44
45 #ifdef LTC_KASUMI
46 struct kasumi_key {
47 ulong32 KLi1[8], KLi2[8],
48 KOi1[8], KOi2[8], KOi3[8],
49 KIi1[8], KIi2[8], KIi3[8];
50 };
51 #endif
52
53 #ifdef LTC_XTEA
54 struct xtea_key {
55 unsigned long A[32], B[32];
56 };
57 #endif
58
59 #ifdef LTC_TWOFISH
60 #ifndef LTC_TWOFISH_SMALL
61 struct twofish_key {
62 ulong32 S[4][256], K[40];
63 };
64 #else
65 struct twofish_key {
66 ulong32 K[40];
67 unsigned char S[32], start;
68 };
69 #endif
70 #endif
71
72 #ifdef LTC_SAFER
73 #define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6
74 #define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10
75 #define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8
76 #define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10
77 #define LTC_SAFER_MAX_NOF_ROUNDS 13
78 #define LTC_SAFER_BLOCK_LEN 8
79 #define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS))
80 typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN];
81 typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN];
82 struct safer_key { safer_key_t key; };
83 #endif
84
85 #ifdef LTC_RC2
86 struct rc2_key { unsigned xkey[64]; };
87 #endif
88
89 #ifdef LTC_DES
90 struct des_key {
91 ulong32 ek[32], dk[32];
92 };
93
94 struct des3_key {
95 ulong32 ek[3][32], dk[3][32];
96 };
97 #endif
98
99 #ifdef LTC_CAST5
100 struct cast5_key {
101 ulong32 K[32], keylen;
102 };
103 #endif
104
105 #ifdef LTC_NOEKEON
106 struct noekeon_key {
107 ulong32 K[4], dK[4];
108 };
109 #endif
110
111 #ifdef LTC_SKIPJACK
112 struct skipjack_key {
113 unsigned char key[10];
114 };
115 #endif
116
117 #ifdef LTC_KHAZAD
118 struct khazad_key {
119 ulong64 roundKeyEnc[8 + 1];
120 ulong64 roundKeyDec[8 + 1];
121 };
122 #endif
123
124 #ifdef LTC_ANUBIS
125 struct anubis_key {
126 int keyBits;
127 int R;
128 ulong32 roundKeyEnc[18 + 1][4];
129 ulong32 roundKeyDec[18 + 1][4];
130 };
131 #endif
132
133 #ifdef LTC_MULTI2
134 struct multi2_key {
135 int N;
136 ulong32 uk[8];
137 };
138 #endif
139
140 #ifdef LTC_CAMELLIA
141 struct camellia_key {
142 int R;
143 ulong64 kw[4], k[24], kl[6];
144 };
145 #endif
146
147 typedef union Symmetric_key {
148 #ifdef LTC_DES
149 struct des_key des;
150 struct des3_key des3;
151 #endif
152 #ifdef LTC_RC2
153 struct rc2_key rc2;
154 #endif
155 #ifdef LTC_SAFER
156 struct safer_key safer;
157 #endif
158 #ifdef LTC_TWOFISH
159 struct twofish_key twofish;
160 #endif
161 #ifdef LTC_BLOWFISH
162 struct blowfish_key blowfish;
163 #endif
164 #ifdef LTC_RC5
165 struct rc5_key rc5;
166 #endif
167 #ifdef LTC_RC6
168 struct rc6_key rc6;
169 #endif
170 #ifdef LTC_SAFERP
171 struct saferp_key saferp;
172 #endif
173 #ifdef LTC_RIJNDAEL
174 struct rijndael_key rijndael;
175 #endif
176 #ifdef LTC_XTEA
177 struct xtea_key xtea;
178 #endif
179 #ifdef LTC_CAST5
180 struct cast5_key cast5;
181 #endif
182 #ifdef LTC_NOEKEON
183 struct noekeon_key noekeon;
184 #endif
185 #ifdef LTC_SKIPJACK
186 struct skipjack_key skipjack;
187 #endif
188 #ifdef LTC_KHAZAD
189 struct khazad_key khazad;
190 #endif
191 #ifdef LTC_ANUBIS
192 struct anubis_key anubis;
193 #endif
194 #ifdef LTC_KSEED
195 struct kseed_key kseed;
196 #endif
197 #ifdef LTC_KASUMI
198 struct kasumi_key kasumi;
199 #endif
200 #ifdef LTC_MULTI2
201 struct multi2_key multi2;
202 #endif
203 #ifdef LTC_CAMELLIA
204 struct camellia_key camellia;
205 #endif
206 void *data;
207 } symmetric_key;
208
209 #ifdef LTC_ECB_MODE
210 /** A block cipher ECB structure */
211 typedef struct {
212 /** The index of the cipher chosen */
213 int cipher,
214 /** The block size of the given cipher */
215 blocklen;
216 /** The scheduled key */
217 symmetric_key key;
218 } symmetric_ECB;
219 #endif
220
221 #ifdef LTC_CFB_MODE
222 /** A block cipher CFB structure */
223 typedef struct {
224 /** The index of the cipher chosen */
225 int cipher,
226 /** The block size of the given cipher */
227 blocklen,
228 /** The padding offset */
229 padlen;
230 /** The current IV */
231 unsigned char IV[MAXBLOCKSIZE],
232 /** The pad used to encrypt/decrypt */
233 pad[MAXBLOCKSIZE];
234 /** The scheduled key */
235 symmetric_key key;
236 } symmetric_CFB;
237 #endif
238
239 #ifdef LTC_OFB_MODE
240 /** A block cipher OFB structure */
241 typedef struct {
242 /** The index of the cipher chosen */
243 int cipher,
244 /** The block size of the given cipher */
245 blocklen,
246 /** The padding offset */
247 padlen;
248 /** The current IV */
249 unsigned char IV[MAXBLOCKSIZE];
250 /** The scheduled key */
251 symmetric_key key;
252 } symmetric_OFB;
253 #endif
254
255 #ifdef LTC_CBC_MODE
256 /** A block cipher CBC structure */
257 typedef struct {
258 /** The index of the cipher chosen */
259 int cipher,
260 /** The block size of the given cipher */
261 blocklen;
262 /** The current IV */
263 unsigned char IV[MAXBLOCKSIZE];
264 /** The scheduled key */
265 symmetric_key key;
266 } symmetric_CBC;
267 #endif
268
269
270 #ifdef LTC_CTR_MODE
271 /** A block cipher CTR structure */
272 typedef struct {
273 /** The index of the cipher chosen */
274 int cipher,
275 /** The block size of the given cipher */
276 blocklen,
277 /** The padding offset */
278 padlen,
279 /** The mode (endianess) of the CTR, 0==little, 1==big */
280 mode,
281 /** counter width */
282 ctrlen;
283
284 /** The counter */
285 unsigned char ctr[MAXBLOCKSIZE],
286 /** The pad used to encrypt/decrypt */
287 pad[MAXBLOCKSIZE];
288 /** The scheduled key */
289 symmetric_key key;
290 } symmetric_CTR;
291 #endif
292
293
294 #ifdef LTC_LRW_MODE
295 /** A LRW structure */
296 typedef struct {
297 /** The index of the cipher chosen (must be a 128-bit block cipher) */
298 int cipher;
299
300 /** The current IV */
301 unsigned char IV[16],
302
303 /** the tweak key */
304 tweak[16],
305
306 /** The current pad, it's the product of the first 15 bytes against the tweak key */
307 pad[16];
308
309 /** The scheduled symmetric key */
310 symmetric_key key;
311
312 #ifdef LRW_TABLES
313 /** The pre-computed multiplication table */
314 unsigned char PC[16][256][16];
315 #endif
316 } symmetric_LRW;
317 #endif
318
319 #ifdef LTC_F8_MODE
320 /** A block cipher F8 structure */
321 typedef struct {
322 /** The index of the cipher chosen */
323 int cipher,
324 /** The block size of the given cipher */
325 blocklen,
326 /** The padding offset */
327 padlen;
328 /** The current IV */
329 unsigned char IV[MAXBLOCKSIZE],
330 MIV[MAXBLOCKSIZE];
331 /** Current block count */
332 ulong32 blockcnt;
333 /** The scheduled key */
334 symmetric_key key;
335 } symmetric_F8;
336 #endif
337
338
339 /** cipher descriptor table, last entry has "name == NULL" to mark the end of table */
340 extern struct ltc_cipher_descriptor {
341 /** name of cipher */
342 char *name;
343 /** internal ID */
344 unsigned char ID;
345 /** min keysize (octets) */
346 int min_key_length,
347 /** max keysize (octets) */
348 max_key_length,
349 /** block size (octets) */
350 block_length,
351 /** default number of rounds */
352 default_rounds;
353 /** Setup the cipher
354 @param key The input symmetric key
355 @param keylen The length of the input key (octets)
356 @param num_rounds The requested number of rounds (0==default)
357 @param skey [out] The destination of the scheduled key
358 @return CRYPT_OK if successful
359 */
360 int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
361 /** Encrypt a block
362 @param pt The plaintext
363 @param ct [out] The ciphertext
364 @param skey The scheduled key
365 @return CRYPT_OK if successful
366 */
367 int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
368 /** Decrypt a block
369 @param ct The ciphertext
370 @param pt [out] The plaintext
371 @param skey The scheduled key
372 @return CRYPT_OK if successful
373 */
374 int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
375 /** Test the block cipher
376 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
377 */
378 int (*test)(void);
379
380 /** Terminate the context
381 @param skey The scheduled key
382 */
383 void (*done)(symmetric_key *skey);
384
385 /** Determine a key size
386 @param keysize [in/out] The size of the key desired and the suggested size
387 @return CRYPT_OK if successful
388 */
389 int (*keysize)(int *keysize);
390
391 /** Accelerators **/
392 /** Accelerated ECB encryption
393 @param pt Plaintext
394 @param ct Ciphertext
395 @param blocks The number of complete blocks to process
396 @param skey The scheduled key context
397 @return CRYPT_OK if successful
398 */
399 int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
400
401 /** Accelerated ECB decryption
402 @param pt Plaintext
403 @param ct Ciphertext
404 @param blocks The number of complete blocks to process
405 @param skey The scheduled key context
406 @return CRYPT_OK if successful
407 */
408 int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
409
410 /** Accelerated CBC encryption
411 @param pt Plaintext
412 @param ct Ciphertext
413 @param blocks The number of complete blocks to process
414 @param IV The initial value (input/output)
415 @param skey The scheduled key context
416 @return CRYPT_OK if successful
417 */
418 int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
419
420 /** Accelerated CBC decryption
421 @param pt Plaintext
422 @param ct Ciphertext
423 @param blocks The number of complete blocks to process
424 @param IV The initial value (input/output)
425 @param skey The scheduled key context
426 @return CRYPT_OK if successful
427 */
428 int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
429
430 /** Accelerated CTR encryption
431 @param pt Plaintext
432 @param ct Ciphertext
433 @param blocks The number of complete blocks to process
434 @param IV The initial value (input/output)
435 @param mode little or big endian counter (mode=0 or mode=1)
436 @param skey The scheduled key context
437 @return CRYPT_OK if successful
438 */
439 int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
440
441 /** Accelerated LRW
442 @param pt Plaintext
443 @param ct Ciphertext
444 @param blocks The number of complete blocks to process
445 @param IV The initial value (input/output)
446 @param tweak The LRW tweak
447 @param skey The scheduled key context
448 @return CRYPT_OK if successful
449 */
450 int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
451
452 /** Accelerated LRW
453 @param ct Ciphertext
454 @param pt Plaintext
455 @param blocks The number of complete blocks to process
456 @param IV The initial value (input/output)
457 @param tweak The LRW tweak
458 @param skey The scheduled key context
459 @return CRYPT_OK if successful
460 */
461 int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
462
463 /** Accelerated CCM packet (one-shot)
464 @param key The secret key to use
465 @param keylen The length of the secret key (octets)
466 @param uskey A previously scheduled key [optional can be NULL]
467 @param nonce The session nonce [use once]
468 @param noncelen The length of the nonce
469 @param header The header for the session
470 @param headerlen The length of the header (octets)
471 @param pt [out] The plaintext
472 @param ptlen The length of the plaintext (octets)
473 @param ct [out] The ciphertext
474 @param tag [out] The destination tag
475 @param taglen [in/out] The max size and resulting size of the authentication tag
476 @param direction Encrypt or Decrypt direction (0 or 1)
477 @return CRYPT_OK if successful
478 */
479 int (*accel_ccm_memory)(
480 const unsigned char *key, unsigned long keylen,
481 symmetric_key *uskey,
482 const unsigned char *nonce, unsigned long noncelen,
483 const unsigned char *header, unsigned long headerlen,
484 unsigned char *pt, unsigned long ptlen,
485 unsigned char *ct,
486 unsigned char *tag, unsigned long *taglen,
487 int direction);
488
489 /** Accelerated GCM packet (one shot)
490 @param key The secret key
491 @param keylen The length of the secret key
492 @param IV The initial vector
493 @param IVlen The length of the initial vector
494 @param adata The additional authentication data (header)
495 @param adatalen The length of the adata
496 @param pt The plaintext
497 @param ptlen The length of the plaintext (ciphertext length is the same)
498 @param ct The ciphertext
499 @param tag [out] The MAC tag
500 @param taglen [in/out] The MAC tag length
501 @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
502 @return CRYPT_OK on success
503 */
504 int (*accel_gcm_memory)(
505 const unsigned char *key, unsigned long keylen,
506 const unsigned char *IV, unsigned long IVlen,
507 const unsigned char *adata, unsigned long adatalen,
508 unsigned char *pt, unsigned long ptlen,
509 unsigned char *ct,
510 unsigned char *tag, unsigned long *taglen,
511 int direction);
512
513 /** Accelerated one shot LTC_OMAC
514 @param key The secret key
515 @param keylen The key length (octets)
516 @param in The message
517 @param inlen Length of message (octets)
518 @param out [out] Destination for tag
519 @param outlen [in/out] Initial and final size of out
520 @return CRYPT_OK on success
521 */
522 int (*omac_memory)(
523 const unsigned char *key, unsigned long keylen,
524 const unsigned char *in, unsigned long inlen,
525 unsigned char *out, unsigned long *outlen);
526
527 /** Accelerated one shot XCBC
528 @param key The secret key
529 @param keylen The key length (octets)
530 @param in The message
531 @param inlen Length of message (octets)
532 @param out [out] Destination for tag
533 @param outlen [in/out] Initial and final size of out
534 @return CRYPT_OK on success
535 */
536 int (*xcbc_memory)(
537 const unsigned char *key, unsigned long keylen,
538 const unsigned char *in, unsigned long inlen,
539 unsigned char *out, unsigned long *outlen);
540
541 /** Accelerated one shot F9
542 @param key The secret key
543 @param keylen The key length (octets)
544 @param in The message
545 @param inlen Length of message (octets)
546 @param out [out] Destination for tag
547 @param outlen [in/out] Initial and final size of out
548 @return CRYPT_OK on success
549 @remark Requires manual padding
550 */
551 int (*f9_memory)(
552 const unsigned char *key, unsigned long keylen,
553 const unsigned char *in, unsigned long inlen,
554 unsigned char *out, unsigned long *outlen);
555 } cipher_descriptor[];
556
557 #ifdef LTC_BLOWFISH
558 int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
559 int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
560 int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
561 int blowfish_test(void);
562 void blowfish_done(symmetric_key *skey);
563 int blowfish_keysize(int *keysize);
564 extern const struct ltc_cipher_descriptor blowfish_desc;
565 #endif
566
567 #ifdef LTC_RC5
568 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
569 int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
570 int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
571 int rc5_test(void);
572 void rc5_done(symmetric_key *skey);
573 int rc5_keysize(int *keysize);
574 extern const struct ltc_cipher_descriptor rc5_desc;
575 #endif
576
577 #ifdef LTC_RC6
578 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
579 int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
580 int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
581 int rc6_test(void);
582 void rc6_done(symmetric_key *skey);
583 int rc6_keysize(int *keysize);
584 extern const struct ltc_cipher_descriptor rc6_desc;
585 #endif
586
587 #ifdef LTC_RC2
588 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
589 int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
590 int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
591 int rc2_test(void);
592 void rc2_done(symmetric_key *skey);
593 int rc2_keysize(int *keysize);
594 extern const struct ltc_cipher_descriptor rc2_desc;
595 #endif
596
597 #ifdef LTC_SAFERP
598 int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
599 int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
600 int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
601 int saferp_test(void);
602 void saferp_done(symmetric_key *skey);
603 int saferp_keysize(int *keysize);
604 extern const struct ltc_cipher_descriptor saferp_desc;
605 #endif
606
607 #ifdef LTC_SAFER
608 int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
609 int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
610 int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
611 int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
612 int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
613 int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
614 int safer_k64_test(void);
615 int safer_sk64_test(void);
616 int safer_sk128_test(void);
617 void safer_done(symmetric_key *skey);
618 int safer_64_keysize(int *keysize);
619 int safer_128_keysize(int *keysize);
620 extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc;
621 #endif
622
623 #ifdef LTC_RIJNDAEL
624
625 /* make aes an alias */
626 #define aes_setup rijndael_setup
627 #define aes_ecb_encrypt rijndael_ecb_encrypt
628 #define aes_ecb_decrypt rijndael_ecb_decrypt
629 #define aes_test rijndael_test
630 #define aes_done rijndael_done
631 #define aes_keysize rijndael_keysize
632
633 #define aes_enc_setup rijndael_enc_setup
634 #define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt
635 #define aes_enc_keysize rijndael_enc_keysize
636
637 int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
638 int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
639 int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
640 int rijndael_test(void);
641 void rijndael_done(symmetric_key *skey);
642 int rijndael_keysize(int *keysize);
643 int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
644 int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
645 void rijndael_enc_done(symmetric_key *skey);
646 int rijndael_enc_keysize(int *keysize);
647 extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
648 extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
649 #endif
650
651 #ifdef LTC_XTEA
652 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
653 int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
654 int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
655 int xtea_test(void);
656 void xtea_done(symmetric_key *skey);
657 int xtea_keysize(int *keysize);
658 extern const struct ltc_cipher_descriptor xtea_desc;
659 #endif
660
661 #ifdef LTC_TWOFISH
662 int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
663 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
664 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
665 int twofish_test(void);
666 void twofish_done(symmetric_key *skey);
667 int twofish_keysize(int *keysize);
668 extern const struct ltc_cipher_descriptor twofish_desc;
669 #endif
670
671 #ifdef LTC_DES
672 int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
673 int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
674 int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
675 int des_test(void);
676 void des_done(symmetric_key *skey);
677 int des_keysize(int *keysize);
678 int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
679 int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
680 int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
681 int des3_test(void);
682 void des3_done(symmetric_key *skey);
683 int des3_keysize(int *keysize);
684 extern const struct ltc_cipher_descriptor des_desc, des3_desc;
685 #endif
686
687 #ifdef LTC_CAST5
688 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
689 int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
690 int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
691 int cast5_test(void);
692 void cast5_done(symmetric_key *skey);
693 int cast5_keysize(int *keysize);
694 extern const struct ltc_cipher_descriptor cast5_desc;
695 #endif
696
697 #ifdef LTC_NOEKEON
698 int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
699 int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
700 int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
701 int noekeon_test(void);
702 void noekeon_done(symmetric_key *skey);
703 int noekeon_keysize(int *keysize);
704 extern const struct ltc_cipher_descriptor noekeon_desc;
705 #endif
706
707 #ifdef LTC_SKIPJACK
708 int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
709 int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
710 int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
711 int skipjack_test(void);
712 void skipjack_done(symmetric_key *skey);
713 int skipjack_keysize(int *keysize);
714 extern const struct ltc_cipher_descriptor skipjack_desc;
715 #endif
716
717 #ifdef LTC_KHAZAD
718 int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
719 int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
720 int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
721 int khazad_test(void);
722 void khazad_done(symmetric_key *skey);
723 int khazad_keysize(int *keysize);
724 extern const struct ltc_cipher_descriptor khazad_desc;
725 #endif
726
727 #ifdef LTC_ANUBIS
728 int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
729 int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
730 int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
731 int anubis_test(void);
732 void anubis_done(symmetric_key *skey);
733 int anubis_keysize(int *keysize);
734 extern const struct ltc_cipher_descriptor anubis_desc;
735 #endif
736
737 #ifdef LTC_KSEED
738 int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
739 int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
740 int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
741 int kseed_test(void);
742 void kseed_done(symmetric_key *skey);
743 int kseed_keysize(int *keysize);
744 extern const struct ltc_cipher_descriptor kseed_desc;
745 #endif
746
747 #ifdef LTC_KASUMI
748 int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
749 int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
750 int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
751 int kasumi_test(void);
752 void kasumi_done(symmetric_key *skey);
753 int kasumi_keysize(int *keysize);
754 extern const struct ltc_cipher_descriptor kasumi_desc;
755 #endif
756
757
758 #ifdef LTC_MULTI2
759 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
760 int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
761 int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
762 int multi2_test(void);
763 void multi2_done(symmetric_key *skey);
764 int multi2_keysize(int *keysize);
765 extern const struct ltc_cipher_descriptor multi2_desc;
766 #endif
767
768 #ifdef LTC_CAMELLIA
769 int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
770 int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
771 int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
772 int camellia_test(void);
773 void camellia_done(symmetric_key *skey);
774 int camellia_keysize(int *keysize);
775 extern const struct ltc_cipher_descriptor camellia_desc;
776 #endif
777
778 #ifdef LTC_ECB_MODE
779 int ecb_start(int cipher, const unsigned char *key,
780 int keylen, int num_rounds, symmetric_ECB *ecb);
781 int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb);
782 int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb);
783 int ecb_done(symmetric_ECB *ecb);
784 #endif
785
786 #ifdef LTC_CFB_MODE
787 int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
788 int keylen, int num_rounds, symmetric_CFB *cfb);
789 int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb);
790 int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
791 int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb);
792 int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb);
793 int cfb_done(symmetric_CFB *cfb);
794 #endif
795
796 #ifdef LTC_OFB_MODE
797 int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
798 int keylen, int num_rounds, symmetric_OFB *ofb);
799 int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb);
800 int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb);
801 int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb);
802 int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb);
803 int ofb_done(symmetric_OFB *ofb);
804 #endif
805
806 #ifdef LTC_CBC_MODE
807 int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
808 int keylen, int num_rounds, symmetric_CBC *cbc);
809 int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc);
810 int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc);
811 int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc);
812 int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc);
813 int cbc_done(symmetric_CBC *cbc);
814 #endif
815
816 #ifdef LTC_CTR_MODE
817
818 #define CTR_COUNTER_LITTLE_ENDIAN 0x0000
819 #define CTR_COUNTER_BIG_ENDIAN 0x1000
820 #define LTC_CTR_RFC3686 0x2000
821
822 int ctr_start( int cipher,
823 const unsigned char *IV,
824 const unsigned char *key, int keylen,
825 int num_rounds, int ctr_mode,
826 symmetric_CTR *ctr);
827 int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
828 int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
829 int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
830 int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
831 int ctr_done(symmetric_CTR *ctr);
832 int ctr_test(void);
833 #endif
834
835 #ifdef LTC_LRW_MODE
836
837 #define LRW_ENCRYPT 0
838 #define LRW_DECRYPT 1
839
840 int lrw_start( int cipher,
841 const unsigned char *IV,
842 const unsigned char *key, int keylen,
843 const unsigned char *tweak,
844 int num_rounds,
845 symmetric_LRW *lrw);
846 int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw);
847 int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw);
848 int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw);
849 int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw);
850 int lrw_done(symmetric_LRW *lrw);
851 int lrw_test(void);
852
853 /* don't call */
854 int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw);
855 #endif
856
857 #ifdef LTC_F8_MODE
858 int f8_start( int cipher, const unsigned char *IV,
859 const unsigned char *key, int keylen,
860 const unsigned char *salt_key, int skeylen,
861 int num_rounds, symmetric_F8 *f8);
862 int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8);
863 int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8);
864 int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8);
865 int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8);
866 int f8_done(symmetric_F8 *f8);
867 int f8_test_mode(void);
868 #endif
869
870 #ifdef LTC_XTS_MODE
871 typedef struct {
872 symmetric_key key1, key2;
873 int cipher;
874 } symmetric_xts;
875
876 int xts_start( int cipher,
877 const unsigned char *key1,
878 const unsigned char *key2,
879 unsigned long keylen,
880 int num_rounds,
881 symmetric_xts *xts);
882
883 int xts_encrypt(
884 const unsigned char *pt, unsigned long ptlen,
885 unsigned char *ct,
886 const unsigned char *tweak,
887 symmetric_xts *xts);
888 int xts_decrypt(
889 const unsigned char *ct, unsigned long ptlen,
890 unsigned char *pt,
891 const unsigned char *tweak,
892 symmetric_xts *xts);
893
894 void xts_done(symmetric_xts *xts);
895 int xts_test(void);
896 void xts_mult_x(unsigned char *I);
897 #endif
898
899 int find_cipher(const char *name);
900 int find_cipher_any(const char *name, int blocklen, int keylen);
901 int find_cipher_id(unsigned char ID);
902 int register_cipher(const struct ltc_cipher_descriptor *cipher);
903 int unregister_cipher(const struct ltc_cipher_descriptor *cipher);
904 int cipher_is_valid(int idx);
905
906 LTC_MUTEX_PROTO(ltc_cipher_mutex)
907
908 /* $Source$ */
909 /* $Revision$ */
910 /* $Date$ */
0 #ifndef TOMCRYPT_CUSTOM_H_
1 #define TOMCRYPT_CUSTOM_H_
2
3 /* macros for various libc functions you can change for embedded targets */
4 #ifndef XMALLOC
5 #ifdef malloc
6 /* #define LTC_NO_PROTOTYPES */
7 #endif
8 #define XMALLOC malloc
9 #endif
10 #ifndef XREALLOC
11 #ifdef realloc
12 /* #define LTC_NO_PROTOTYPES */
13 #endif
14 #define XREALLOC realloc
15 #endif
16 #ifndef XCALLOC
17 #ifdef calloc
18 /* #define LTC_NO_PROTOTYPES */
19 #endif
20 #define XCALLOC calloc
21 #endif
22 #ifndef XFREE
23 #ifdef free
24 /* #define LTC_NO_PROTOTYPES */
25 #endif
26 #define XFREE free
27 #endif
28
29 #ifndef XMEMSET
30 #ifdef memset
31 /* #define LTC_NO_PROTOTYPES */
32 #endif
33 #define XMEMSET memset
34 #endif
35 #ifndef XMEMCPY
36 #ifdef memcpy
37 /* #define LTC_NO_PROTOTYPES */
38 #endif
39 #define XMEMCPY memcpy
40 #endif
41 #ifndef XMEMCMP
42 #ifdef memcmp
43 /* #define LTC_NO_PROTOTYPES */
44 #endif
45 #define XMEMCMP memcmp
46 #endif
47 #ifndef XSTRCMP
48 #ifdef strcmp
49 /* #define LTC_NO_PROTOTYPES */
50 #endif
51 #define XSTRCMP strcmp
52 #endif
53
54 #ifndef XCLOCK
55 #define XCLOCK clock
56 #endif
57 #ifndef XCLOCKS_PER_SEC
58 #define XCLOCKS_PER_SEC CLOCKS_PER_SEC
59 #endif
60
61 #ifndef XQSORT
62 #ifdef qsort
63 /* #define LTC_NO_PROTOTYPES */
64 #endif
65 #define XQSORT qsort
66 #endif
67
68 /* Easy button? */
69 #ifdef LTC_EASY
70 #define LTC_NO_CIPHERS
71 #define LTC_RIJNDAEL
72 #define LTC_BLOWFISH
73 #define LTC_DES
74 #define LTC_CAST5
75
76 #define LTC_NO_MODES
77 #define LTC_ECB_MODE
78 #define LTC_CBC_MODE
79 #define LTC_CTR_MODE
80
81 #define LTC_NO_HASHES
82 #define LTC_SHA1
83 #define LTC_SHA512
84 #define LTC_SHA384
85 #define LTC_SHA256
86 #define LTC_SHA224
87
88 #define LTC_NO_MACS
89 #define LTC_HMAC
90 #define LTC_OMAC
91 #define LTC_CCM_MODE
92
93 #define LTC_NO_PRNGS
94 #define LTC_SPRNG
95 #define LTC_YARROW
96 #define LTC_DEVRANDOM
97 #define TRY_URANDOM_FIRST
98
99 #define LTC_NO_PK
100 #define LTC_MRSA
101 #define LTC_MECC
102 #endif
103
104 /* Use small code where possible */
105 /* #define LTC_SMALL_CODE */
106
107 /* Enable self-test test vector checking */
108 #ifndef LTC_NO_TEST
109 #define LTC_TEST
110 #endif
111
112 /* clean the stack of functions which put private information on stack */
113 /* #define LTC_CLEAN_STACK */
114
115 /* disable all file related functions */
116 /* #define LTC_NO_FILE */
117
118 /* disable all forms of ASM */
119 /* #define LTC_NO_ASM */
120
121 /* disable FAST mode */
122 /* #define LTC_NO_FAST */
123
124 /* disable BSWAP on x86 */
125 /* #define LTC_NO_BSWAP */
126
127 /* ---> Symmetric Block Ciphers <--- */
128 #ifndef LTC_NO_CIPHERS
129
130 #define LTC_BLOWFISH
131 #define LTC_RC2
132 #define LTC_RC5
133 #define LTC_RC6
134 #define LTC_SAFERP
135 #define LTC_RIJNDAEL
136 #define LTC_XTEA
137 /* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format
138 * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */
139 #define LTC_TWOFISH
140 #ifndef LTC_NO_TABLES
141 #define LTC_TWOFISH_TABLES
142 /* #define LTC_TWOFISH_ALL_TABLES */
143 #else
144 #define LTC_TWOFISH_SMALL
145 #endif
146 /* #define LTC_TWOFISH_SMALL */
147 /* LTC_DES includes EDE triple-LTC_DES */
148 #define LTC_DES
149 #define LTC_CAST5
150 #define LTC_NOEKEON
151 #define LTC_SKIPJACK
152 #define LTC_SAFER
153 #define LTC_KHAZAD
154 #define LTC_ANUBIS
155 #define LTC_ANUBIS_TWEAK
156 #define LTC_KSEED
157 #define LTC_KASUMI
158 #define LTC_MULTI2
159 #define LTC_CAMELLIA
160
161 #endif /* LTC_NO_CIPHERS */
162
163
164 /* ---> Block Cipher Modes of Operation <--- */
165 #ifndef LTC_NO_MODES
166
167 #define LTC_CFB_MODE
168 #define LTC_OFB_MODE
169 #define LTC_ECB_MODE
170 #define LTC_CBC_MODE
171 #define LTC_CTR_MODE
172
173 /* F8 chaining mode */
174 #define LTC_F8_MODE
175
176 /* LRW mode */
177 #define LTC_LRW_MODE
178 #ifndef LTC_NO_TABLES
179 /* like GCM mode this will enable 16 8x128 tables [64KB] that make
180 * seeking very fast.
181 */
182 #define LRW_TABLES
183 #endif
184
185 /* XTS mode */
186 #define LTC_XTS_MODE
187
188 #endif /* LTC_NO_MODES */
189
190 /* ---> One-Way Hash Functions <--- */
191 #ifndef LTC_NO_HASHES
192
193 #define LTC_CHC_HASH
194 #define LTC_WHIRLPOOL
195 #define LTC_SHA512
196 #define LTC_SHA384
197 #define LTC_SHA256
198 #define LTC_SHA224
199 #define LTC_TIGER
200 #define LTC_SHA1
201 #define LTC_MD5
202 #define LTC_MD4
203 #define LTC_MD2
204 #define LTC_RIPEMD128
205 #define LTC_RIPEMD160
206 #define LTC_RIPEMD256
207 #define LTC_RIPEMD320
208
209 #endif /* LTC_NO_HASHES */
210
211 /* ---> MAC functions <--- */
212 #ifndef LTC_NO_MACS
213
214 #define LTC_HMAC
215 #define LTC_OMAC
216 #define LTC_PMAC
217 #define LTC_XCBC
218 #define LTC_F9_MODE
219 #define LTC_PELICAN
220
221 #if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL)
222 #error Pelican-MAC requires LTC_RIJNDAEL
223 #endif
224
225 /* ---> Encrypt + Authenticate Modes <--- */
226
227 #define LTC_EAX_MODE
228 #if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC))
229 #error LTC_EAX_MODE requires CTR and LTC_OMAC mode
230 #endif
231
232 #define LTC_OCB_MODE
233 #define LTC_OCB3_MODE
234 #define LTC_CCM_MODE
235 #define LTC_GCM_MODE
236
237 /* Use 64KiB tables */
238 #ifndef LTC_NO_TABLES
239 #define LTC_GCM_TABLES
240 #endif
241
242 /* USE SSE2? requires GCC works on x86_32 and x86_64*/
243 #ifdef LTC_GCM_TABLES
244 /* #define LTC_GCM_TABLES_SSE2 */
245 #endif
246
247 #endif /* LTC_NO_MACS */
248
249 /* Various tidbits of modern neatoness */
250 #define LTC_BASE64
251
252 /* --> Pseudo Random Number Generators <--- */
253 #ifndef LTC_NO_PRNGS
254
255 /* Yarrow */
256 #define LTC_YARROW
257 /* which descriptor of AES to use? */
258 /* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */
259 #ifdef ENCRYPT_ONLY
260 #define LTC_YARROW_AES 3
261 #else
262 #define LTC_YARROW_AES 3
263 #endif
264
265 #if defined(LTC_YARROW) && !defined(LTC_CTR_MODE)
266 #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined!
267 #endif
268
269 /* a PRNG that simply reads from an available system source */
270 #define LTC_SPRNG
271
272 /* The LTC_RC4 stream cipher */
273 #define LTC_RC4
274
275 /* Fortuna PRNG */
276 #define LTC_FORTUNA
277 /* reseed every N calls to the read function */
278 #define LTC_FORTUNA_WD 10
279 /* number of pools (4..32) can save a bit of ram by lowering the count */
280 #define LTC_FORTUNA_POOLS 32
281
282 /* Greg's LTC_SOBER128 PRNG ;-0 */
283 #define LTC_SOBER128
284
285 /* the *nix style /dev/random device */
286 #define LTC_DEVRANDOM
287 /* try /dev/urandom before trying /dev/random */
288 #define TRY_URANDOM_FIRST
289
290 #endif /* LTC_NO_PRNGS */
291
292 /* ---> math provider? <--- */
293 #ifndef LTC_NO_MATH
294
295 /* LibTomMath */
296 /* #define LTM_DESC */
297
298 /* TomsFastMath */
299 /* #define TFM_DESC */
300
301 #endif /* LTC_NO_MATH */
302
303 /* ---> Public Key Crypto <--- */
304 #ifndef LTC_NO_PK
305
306 /* Include RSA support */
307 #define LTC_MRSA
308
309 /* Enable RSA blinding when doing private key operations? */
310 /* #define LTC_RSA_BLINDING */
311
312 /* Include Diffie-Hellman support */
313 #ifndef GMP_DESC
314 /* is_prime fails for GMP */
315 #define MDH
316 /* Supported Key Sizes */
317 #define DH768
318 #define DH1024
319 #define DH1280
320 #define DH1536
321 #define DH1792
322 #define DH2048
323
324 #ifndef TFM_DESC
325 /* tfm has a problem in fp_isprime for larger key sizes */
326 #define DH2560
327 #define DH3072
328 #define DH4096
329 #endif
330 #endif
331
332 /* Include Katja (a Rabin variant like RSA) */
333 /* #define MKAT */
334
335 /* Digital Signature Algorithm */
336 #define LTC_MDSA
337
338 /* ECC */
339 #define LTC_MECC
340
341 /* use Shamir's trick for point mul (speeds up signature verification) */
342 #define LTC_ECC_SHAMIR
343
344 #if defined(TFM_LTC_DESC) && defined(LTC_MECC)
345 #define LTC_MECC_ACCEL
346 #endif
347
348 /* do we want fixed point ECC */
349 /* #define LTC_MECC_FP */
350
351 /* Timing Resistant? */
352 /* #define LTC_ECC_TIMING_RESISTANT */
353
354 #endif /* LTC_NO_PK */
355
356 /* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */
357 #ifndef LTC_NO_PKCS
358
359 #define LTC_PKCS_1
360 #define LTC_PKCS_5
361
362 /* Include ASN.1 DER (required by DSA/RSA) */
363 #define LTC_DER
364
365 #endif /* LTC_NO_PKCS */
366
367 /* LTC_HKDF Key Derivation/Expansion stuff */
368 #ifndef LTC_NO_HKDF
369
370 #define LTC_HKDF
371
372 #endif /* LTC_NO_HKDF */
373
374 /* cleanup */
375
376 #ifdef LTC_MECC
377 /* Supported ECC Key Sizes */
378 #ifndef LTC_NO_CURVES
379 #define ECC112
380 #define ECC128
381 #define ECC160
382 #define ECC192
383 #define ECC224
384 #define ECC256
385 #define ECC384
386 #define ECC521
387 #endif
388 #endif
389
390 #if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA)
391 /* Include the MPI functionality? (required by the PK algorithms) */
392 #define MPI
393 #endif
394
395 #ifdef LTC_MRSA
396 #define LTC_PKCS_1
397 #endif
398
399 #if defined(TFM_DESC) && defined(LTC_RSA_BLINDING)
400 #warning RSA blinding currently not supported in combination with TFM
401 #undef LTC_RSA_BLINDING
402 #endif
403
404 #if defined(LTC_DER) && !defined(MPI)
405 #error ASN.1 DER requires MPI functionality
406 #endif
407
408 #if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER)
409 #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled
410 #endif
411
412 /* THREAD management */
413 #ifdef LTC_PTHREAD
414
415 #include <pthread.h>
416
417 #define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
418 #define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
419 #define LTC_MUTEX_TYPE(x) pthread_mutex_t x;
420 #define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL);
421 #define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x);
422 #define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x);
423
424 #else
425
426 /* default no functions */
427 #define LTC_MUTEX_GLOBAL(x)
428 #define LTC_MUTEX_PROTO(x)
429 #define LTC_MUTEX_TYPE(x)
430 #define LTC_MUTEX_INIT(x)
431 #define LTC_MUTEX_LOCK(x)
432 #define LTC_MUTEX_UNLOCK(x)
433
434 #endif
435
436 /* Debuggers */
437
438 /* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */
439 /* #define LTC_VALGRIND */
440
441 #endif
442
443
444
445 /* $Source$ */
446 /* $Revision$ */
447 /* $Date$ */
0 /* ---- HASH FUNCTIONS ---- */
1 #ifdef LTC_SHA512
2 struct sha512_state {
3 ulong64 length, state[8];
4 unsigned long curlen;
5 unsigned char buf[128];
6 };
7 #endif
8
9 #ifdef LTC_SHA256
10 struct sha256_state {
11 ulong64 length;
12 ulong32 state[8], curlen;
13 unsigned char buf[64];
14 };
15 #endif
16
17 #ifdef LTC_SHA1
18 struct sha1_state {
19 ulong64 length;
20 ulong32 state[5], curlen;
21 unsigned char buf[64];
22 };
23 #endif
24
25 #ifdef LTC_MD5
26 struct md5_state {
27 ulong64 length;
28 ulong32 state[4], curlen;
29 unsigned char buf[64];
30 };
31 #endif
32
33 #ifdef LTC_MD4
34 struct md4_state {
35 ulong64 length;
36 ulong32 state[4], curlen;
37 unsigned char buf[64];
38 };
39 #endif
40
41 #ifdef LTC_TIGER
42 struct tiger_state {
43 ulong64 state[3], length;
44 unsigned long curlen;
45 unsigned char buf[64];
46 };
47 #endif
48
49 #ifdef LTC_MD2
50 struct md2_state {
51 unsigned char chksum[16], X[48], buf[16];
52 unsigned long curlen;
53 };
54 #endif
55
56 #ifdef LTC_RIPEMD128
57 struct rmd128_state {
58 ulong64 length;
59 unsigned char buf[64];
60 ulong32 curlen, state[4];
61 };
62 #endif
63
64 #ifdef LTC_RIPEMD160
65 struct rmd160_state {
66 ulong64 length;
67 unsigned char buf[64];
68 ulong32 curlen, state[5];
69 };
70 #endif
71
72 #ifdef LTC_RIPEMD256
73 struct rmd256_state {
74 ulong64 length;
75 unsigned char buf[64];
76 ulong32 curlen, state[8];
77 };
78 #endif
79
80 #ifdef LTC_RIPEMD320
81 struct rmd320_state {
82 ulong64 length;
83 unsigned char buf[64];
84 ulong32 curlen, state[10];
85 };
86 #endif
87
88 #ifdef LTC_WHIRLPOOL
89 struct whirlpool_state {
90 ulong64 length, state[8];
91 unsigned char buf[64];
92 ulong32 curlen;
93 };
94 #endif
95
96 #ifdef LTC_CHC_HASH
97 struct chc_state {
98 ulong64 length;
99 unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE];
100 ulong32 curlen;
101 };
102 #endif
103
104 typedef union Hash_state {
105 char dummy[1];
106 #ifdef LTC_CHC_HASH
107 struct chc_state chc;
108 #endif
109 #ifdef LTC_WHIRLPOOL
110 struct whirlpool_state whirlpool;
111 #endif
112 #ifdef LTC_SHA512
113 struct sha512_state sha512;
114 #endif
115 #ifdef LTC_SHA256
116 struct sha256_state sha256;
117 #endif
118 #ifdef LTC_SHA1
119 struct sha1_state sha1;
120 #endif
121 #ifdef LTC_MD5
122 struct md5_state md5;
123 #endif
124 #ifdef LTC_MD4
125 struct md4_state md4;
126 #endif
127 #ifdef LTC_MD2
128 struct md2_state md2;
129 #endif
130 #ifdef LTC_TIGER
131 struct tiger_state tiger;
132 #endif
133 #ifdef LTC_RIPEMD128
134 struct rmd128_state rmd128;
135 #endif
136 #ifdef LTC_RIPEMD160
137 struct rmd160_state rmd160;
138 #endif
139 #ifdef LTC_RIPEMD256
140 struct rmd256_state rmd256;
141 #endif
142 #ifdef LTC_RIPEMD320
143 struct rmd320_state rmd320;
144 #endif
145 void *data;
146 } hash_state;
147
148 /** hash descriptor */
149 extern struct ltc_hash_descriptor {
150 /** name of hash */
151 char *name;
152 /** internal ID */
153 unsigned char ID;
154 /** Size of digest in octets */
155 unsigned long hashsize;
156 /** Input block size in octets */
157 unsigned long blocksize;
158 /** ASN.1 OID */
159 unsigned long OID[16];
160 /** Length of DER encoding */
161 unsigned long OIDlen;
162
163 /** Init a hash state
164 @param hash The hash to initialize
165 @return CRYPT_OK if successful
166 */
167 int (*init)(hash_state *hash);
168 /** Process a block of data
169 @param hash The hash state
170 @param in The data to hash
171 @param inlen The length of the data (octets)
172 @return CRYPT_OK if successful
173 */
174 int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen);
175 /** Produce the digest and store it
176 @param hash The hash state
177 @param out [out] The destination of the digest
178 @return CRYPT_OK if successful
179 */
180 int (*done)(hash_state *hash, unsigned char *out);
181 /** Self-test
182 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
183 */
184 int (*test)(void);
185
186 /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */
187 int (*hmac_block)(const unsigned char *key, unsigned long keylen,
188 const unsigned char *in, unsigned long inlen,
189 unsigned char *out, unsigned long *outlen);
190
191 } hash_descriptor[];
192
193 #ifdef LTC_CHC_HASH
194 int chc_register(int cipher);
195 int chc_init(hash_state * md);
196 int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen);
197 int chc_done(hash_state * md, unsigned char *hash);
198 int chc_test(void);
199 extern const struct ltc_hash_descriptor chc_desc;
200 #endif
201
202 #ifdef LTC_WHIRLPOOL
203 int whirlpool_init(hash_state * md);
204 int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen);
205 int whirlpool_done(hash_state * md, unsigned char *hash);
206 int whirlpool_test(void);
207 extern const struct ltc_hash_descriptor whirlpool_desc;
208 #endif
209
210 #ifdef LTC_SHA512
211 int sha512_init(hash_state * md);
212 int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen);
213 int sha512_done(hash_state * md, unsigned char *hash);
214 int sha512_test(void);
215 extern const struct ltc_hash_descriptor sha512_desc;
216 #endif
217
218 #ifdef LTC_SHA384
219 #ifndef LTC_SHA512
220 #error LTC_SHA512 is required for LTC_SHA384
221 #endif
222 int sha384_init(hash_state * md);
223 #define sha384_process sha512_process
224 int sha384_done(hash_state * md, unsigned char *hash);
225 int sha384_test(void);
226 extern const struct ltc_hash_descriptor sha384_desc;
227 #endif
228
229 #ifdef LTC_SHA256
230 int sha256_init(hash_state * md);
231 int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
232 int sha256_done(hash_state * md, unsigned char *hash);
233 int sha256_test(void);
234 extern const struct ltc_hash_descriptor sha256_desc;
235
236 #ifdef LTC_SHA224
237 #ifndef LTC_SHA256
238 #error LTC_SHA256 is required for LTC_SHA224
239 #endif
240 int sha224_init(hash_state * md);
241 #define sha224_process sha256_process
242 int sha224_done(hash_state * md, unsigned char *hash);
243 int sha224_test(void);
244 extern const struct ltc_hash_descriptor sha224_desc;
245 #endif
246 #endif
247
248 #ifdef LTC_SHA1
249 int sha1_init(hash_state * md);
250 int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen);
251 int sha1_done(hash_state * md, unsigned char *hash);
252 int sha1_test(void);
253 extern const struct ltc_hash_descriptor sha1_desc;
254 #endif
255
256 #ifdef LTC_MD5
257 int md5_init(hash_state * md);
258 int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen);
259 int md5_done(hash_state * md, unsigned char *hash);
260 int md5_test(void);
261 extern const struct ltc_hash_descriptor md5_desc;
262 #endif
263
264 #ifdef LTC_MD4
265 int md4_init(hash_state * md);
266 int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen);
267 int md4_done(hash_state * md, unsigned char *hash);
268 int md4_test(void);
269 extern const struct ltc_hash_descriptor md4_desc;
270 #endif
271
272 #ifdef LTC_MD2
273 int md2_init(hash_state * md);
274 int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen);
275 int md2_done(hash_state * md, unsigned char *hash);
276 int md2_test(void);
277 extern const struct ltc_hash_descriptor md2_desc;
278 #endif
279
280 #ifdef LTC_TIGER
281 int tiger_init(hash_state * md);
282 int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen);
283 int tiger_done(hash_state * md, unsigned char *hash);
284 int tiger_test(void);
285 extern const struct ltc_hash_descriptor tiger_desc;
286 #endif
287
288 #ifdef LTC_RIPEMD128
289 int rmd128_init(hash_state * md);
290 int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen);
291 int rmd128_done(hash_state * md, unsigned char *hash);
292 int rmd128_test(void);
293 extern const struct ltc_hash_descriptor rmd128_desc;
294 #endif
295
296 #ifdef LTC_RIPEMD160
297 int rmd160_init(hash_state * md);
298 int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen);
299 int rmd160_done(hash_state * md, unsigned char *hash);
300 int rmd160_test(void);
301 extern const struct ltc_hash_descriptor rmd160_desc;
302 #endif
303
304 #ifdef LTC_RIPEMD256
305 int rmd256_init(hash_state * md);
306 int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
307 int rmd256_done(hash_state * md, unsigned char *hash);
308 int rmd256_test(void);
309 extern const struct ltc_hash_descriptor rmd256_desc;
310 #endif
311
312 #ifdef LTC_RIPEMD320
313 int rmd320_init(hash_state * md);
314 int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen);
315 int rmd320_done(hash_state * md, unsigned char *hash);
316 int rmd320_test(void);
317 extern const struct ltc_hash_descriptor rmd320_desc;
318 #endif
319
320
321 int find_hash(const char *name);
322 int find_hash_id(unsigned char ID);
323 int find_hash_oid(const unsigned long *ID, unsigned long IDlen);
324 int find_hash_any(const char *name, int digestlen);
325 int register_hash(const struct ltc_hash_descriptor *hash);
326 int unregister_hash(const struct ltc_hash_descriptor *hash);
327 int hash_is_valid(int idx);
328
329 LTC_MUTEX_PROTO(ltc_hash_mutex)
330
331 int hash_memory(int hash,
332 const unsigned char *in, unsigned long inlen,
333 unsigned char *out, unsigned long *outlen);
334 int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
335 const unsigned char *in, unsigned long inlen, ...);
336
337 #ifndef LTC_NO_FILE
338 int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen);
339 int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen);
340 #endif
341
342 /* a simple macro for making hash "process" functions */
343 #define HASH_PROCESS(func_name, compress_name, state_var, block_size) \
344 int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \
345 { \
346 unsigned long n; \
347 int err; \
348 LTC_ARGCHK(md != NULL); \
349 LTC_ARGCHK(in != NULL); \
350 if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \
351 return CRYPT_INVALID_ARG; \
352 } \
353 while (inlen > 0) { \
354 if (md-> state_var .curlen == 0 && inlen >= block_size) { \
355 if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \
356 return err; \
357 } \
358 md-> state_var .length += block_size * 8; \
359 in += block_size; \
360 inlen -= block_size; \
361 } else { \
362 n = MIN(inlen, (block_size - md-> state_var .curlen)); \
363 memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \
364 md-> state_var .curlen += n; \
365 in += n; \
366 inlen -= n; \
367 if (md-> state_var .curlen == block_size) { \
368 if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \
369 return err; \
370 } \
371 md-> state_var .length += 8*block_size; \
372 md-> state_var .curlen = 0; \
373 } \
374 } \
375 } \
376 return CRYPT_OK; \
377 }
378
379 /* $Source$ */
380 /* $Revision$ */
381 /* $Date$ */
0 /* LTC_HKDF Header Info */
1
2 /* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */
3 #ifdef LTC_HKDF
4
5 int hkdf_test(void);
6
7 int hkdf_extract(int hash_idx,
8 const unsigned char *salt, unsigned long saltlen,
9 const unsigned char *in, unsigned long inlen,
10 unsigned char *out, unsigned long *outlen);
11
12 int hkdf_expand(int hash_idx,
13 const unsigned char *info, unsigned long infolen,
14 const unsigned char *in, unsigned long inlen,
15 unsigned char *out, unsigned long outlen);
16
17 int hkdf(int hash_idx,
18 const unsigned char *salt, unsigned long saltlen,
19 const unsigned char *info, unsigned long infolen,
20 const unsigned char *in, unsigned long inlen,
21 unsigned char *out, unsigned long outlen);
22
23 #endif /* LTC_HKDF */
24
25 /* $Source$ */
26 /* $Revision$ */
27 /* $Date$ */
0 #ifdef LTC_HMAC
1 typedef struct Hmac_state {
2 hash_state md;
3 int hash;
4 hash_state hashstate;
5 unsigned char *key;
6 } hmac_state;
7
8 int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
9 int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen);
10 int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen);
11 int hmac_test(void);
12 int hmac_memory(int hash,
13 const unsigned char *key, unsigned long keylen,
14 const unsigned char *in, unsigned long inlen,
15 unsigned char *out, unsigned long *outlen);
16 int hmac_memory_multi(int hash,
17 const unsigned char *key, unsigned long keylen,
18 unsigned char *out, unsigned long *outlen,
19 const unsigned char *in, unsigned long inlen, ...);
20 int hmac_file(int hash, const char *fname, const unsigned char *key,
21 unsigned long keylen,
22 unsigned char *dst, unsigned long *dstlen);
23 #endif
24
25 #ifdef LTC_OMAC
26
27 typedef struct {
28 int cipher_idx,
29 buflen,
30 blklen;
31 unsigned char block[MAXBLOCKSIZE],
32 prev[MAXBLOCKSIZE],
33 Lu[2][MAXBLOCKSIZE];
34 symmetric_key key;
35 } omac_state;
36
37 int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen);
38 int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen);
39 int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen);
40 int omac_memory(int cipher,
41 const unsigned char *key, unsigned long keylen,
42 const unsigned char *in, unsigned long inlen,
43 unsigned char *out, unsigned long *outlen);
44 int omac_memory_multi(int cipher,
45 const unsigned char *key, unsigned long keylen,
46 unsigned char *out, unsigned long *outlen,
47 const unsigned char *in, unsigned long inlen, ...);
48 int omac_file(int cipher,
49 const unsigned char *key, unsigned long keylen,
50 const char *filename,
51 unsigned char *out, unsigned long *outlen);
52 int omac_test(void);
53 #endif /* LTC_OMAC */
54
55 #ifdef LTC_PMAC
56
57 typedef struct {
58 unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
59 Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
60 Lr[MAXBLOCKSIZE], /* L * x^-1 */
61 block[MAXBLOCKSIZE], /* currently accumulated block */
62 checksum[MAXBLOCKSIZE]; /* current checksum */
63
64 symmetric_key key; /* scheduled key for cipher */
65 unsigned long block_index; /* index # for current block */
66 int cipher_idx, /* cipher idx */
67 block_len, /* length of block */
68 buflen; /* number of bytes in the buffer */
69 } pmac_state;
70
71 int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen);
72 int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen);
73 int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen);
74
75 int pmac_memory(int cipher,
76 const unsigned char *key, unsigned long keylen,
77 const unsigned char *msg, unsigned long msglen,
78 unsigned char *out, unsigned long *outlen);
79
80 int pmac_memory_multi(int cipher,
81 const unsigned char *key, unsigned long keylen,
82 unsigned char *out, unsigned long *outlen,
83 const unsigned char *in, unsigned long inlen, ...);
84
85 int pmac_file(int cipher,
86 const unsigned char *key, unsigned long keylen,
87 const char *filename,
88 unsigned char *out, unsigned long *outlen);
89
90 int pmac_test(void);
91
92 /* internal functions */
93 int pmac_ntz(unsigned long x);
94 void pmac_shift_xor(pmac_state *pmac);
95
96 #endif /* PMAC */
97
98 #ifdef LTC_EAX_MODE
99
100 #if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE))
101 #error LTC_EAX_MODE requires LTC_OMAC and CTR
102 #endif
103
104 typedef struct {
105 unsigned char N[MAXBLOCKSIZE];
106 symmetric_CTR ctr;
107 omac_state headeromac, ctomac;
108 } eax_state;
109
110 int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
111 const unsigned char *nonce, unsigned long noncelen,
112 const unsigned char *header, unsigned long headerlen);
113
114 int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);
115 int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);
116 int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);
117 int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);
118
119 int eax_encrypt_authenticate_memory(int cipher,
120 const unsigned char *key, unsigned long keylen,
121 const unsigned char *nonce, unsigned long noncelen,
122 const unsigned char *header, unsigned long headerlen,
123 const unsigned char *pt, unsigned long ptlen,
124 unsigned char *ct,
125 unsigned char *tag, unsigned long *taglen);
126
127 int eax_decrypt_verify_memory(int cipher,
128 const unsigned char *key, unsigned long keylen,
129 const unsigned char *nonce, unsigned long noncelen,
130 const unsigned char *header, unsigned long headerlen,
131 const unsigned char *ct, unsigned long ctlen,
132 unsigned char *pt,
133 unsigned char *tag, unsigned long taglen,
134 int *stat);
135
136 int eax_test(void);
137 #endif /* EAX MODE */
138
139 #ifdef LTC_OCB_MODE
140 typedef struct {
141 unsigned char L[MAXBLOCKSIZE], /* L value */
142 Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
143 Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
144 Lr[MAXBLOCKSIZE], /* L * x^-1 */
145 R[MAXBLOCKSIZE], /* R value */
146 checksum[MAXBLOCKSIZE]; /* current checksum */
147
148 symmetric_key key; /* scheduled key for cipher */
149 unsigned long block_index; /* index # for current block */
150 int cipher, /* cipher idx */
151 block_len; /* length of block */
152 } ocb_state;
153
154 int ocb_init(ocb_state *ocb, int cipher,
155 const unsigned char *key, unsigned long keylen, const unsigned char *nonce);
156
157 int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
158 int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
159
160 int ocb_done_encrypt(ocb_state *ocb,
161 const unsigned char *pt, unsigned long ptlen,
162 unsigned char *ct,
163 unsigned char *tag, unsigned long *taglen);
164
165 int ocb_done_decrypt(ocb_state *ocb,
166 const unsigned char *ct, unsigned long ctlen,
167 unsigned char *pt,
168 const unsigned char *tag, unsigned long taglen, int *stat);
169
170 int ocb_encrypt_authenticate_memory(int cipher,
171 const unsigned char *key, unsigned long keylen,
172 const unsigned char *nonce,
173 const unsigned char *pt, unsigned long ptlen,
174 unsigned char *ct,
175 unsigned char *tag, unsigned long *taglen);
176
177 int ocb_decrypt_verify_memory(int cipher,
178 const unsigned char *key, unsigned long keylen,
179 const unsigned char *nonce,
180 const unsigned char *ct, unsigned long ctlen,
181 unsigned char *pt,
182 const unsigned char *tag, unsigned long taglen,
183 int *stat);
184
185 int ocb_test(void);
186
187 /* internal functions */
188 void ocb_shift_xor(ocb_state *ocb, unsigned char *Z);
189 int ocb_ntz(unsigned long x);
190 int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
191 unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode);
192
193 #endif /* LTC_OCB_MODE */
194
195 #ifdef LTC_OCB3_MODE
196 typedef struct {
197 unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */
198 Offset_current[MAXBLOCKSIZE], /* Offset_{current_block_index} value */
199 L_dollar[MAXBLOCKSIZE], /* L_$ value */
200 L_star[MAXBLOCKSIZE], /* L_* value */
201 L_[32][MAXBLOCKSIZE], /* L_{i} values */
202 tag_part[MAXBLOCKSIZE], /* intermediate result of tag calculation */
203 checksum[MAXBLOCKSIZE]; /* current checksum */
204
205 /* AAD related members */
206 unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */
207 aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */
208 adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */
209 int adata_buffer_bytes; /* bytes in AAD buffer */
210 unsigned long ablock_index; /* index # for current adata (AAD) block */
211
212 symmetric_key key; /* scheduled key for cipher */
213 unsigned long block_index; /* index # for current data block */
214 int cipher, /* cipher idx */
215 block_len; /* length of block */
216 } ocb3_state;
217
218 int ocb3_init(ocb3_state *ocb, int cipher,
219 const unsigned char *key, unsigned long keylen,
220 const unsigned char *nonce, unsigned long noncelen);
221
222 int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
223 int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
224 int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
225 int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
226 int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen);
227 int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen);
228
229 int ocb3_encrypt_authenticate_memory(int cipher,
230 const unsigned char *key, unsigned long keylen,
231 const unsigned char *nonce, unsigned long noncelen,
232 const unsigned char *adata, unsigned long adatalen,
233 const unsigned char *pt, unsigned long ptlen,
234 unsigned char *ct,
235 unsigned char *tag, unsigned long *taglen);
236
237 int ocb3_decrypt_verify_memory(int cipher,
238 const unsigned char *key, unsigned long keylen,
239 const unsigned char *nonce, unsigned long noncelen,
240 const unsigned char *adata, unsigned long adatalen,
241 const unsigned char *ct, unsigned long ctlen,
242 unsigned char *pt,
243 const unsigned char *tag, unsigned long taglen,
244 int *stat);
245
246 int ocb3_test(void);
247
248 /* internal helper functions */
249 int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block);
250 void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen);
251 int ocb3_int_ntz(unsigned long x);
252 void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len);
253
254 #endif /* LTC_OCB3_MODE */
255
256 #ifdef LTC_CCM_MODE
257
258 #define CCM_ENCRYPT 0
259 #define CCM_DECRYPT 1
260
261 int ccm_memory(int cipher,
262 const unsigned char *key, unsigned long keylen,
263 symmetric_key *uskey,
264 const unsigned char *nonce, unsigned long noncelen,
265 const unsigned char *header, unsigned long headerlen,
266 unsigned char *pt, unsigned long ptlen,
267 unsigned char *ct,
268 unsigned char *tag, unsigned long *taglen,
269 int direction);
270
271 int ccm_memory_ex(int cipher,
272 const unsigned char *key, unsigned long keylen,
273 symmetric_key *uskey,
274 const unsigned char *nonce, unsigned long noncelen,
275 const unsigned char *header, unsigned long headerlen,
276 unsigned char *pt, unsigned long ptlen,
277 unsigned char *ct,
278 unsigned char *tag, unsigned long *taglen,
279 int direction,
280 const unsigned char *B_0,
281 const unsigned char *CTR,
282 int ctrwidth);
283
284 int ccm_test(void);
285
286 #endif /* LTC_CCM_MODE */
287
288 #if defined(LRW_MODE) || defined(LTC_GCM_MODE)
289 void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c);
290 #endif
291
292
293 /* table shared between GCM and LRW */
294 #if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
295 extern const unsigned char gcm_shift_table[];
296 #endif
297
298 #ifdef LTC_GCM_MODE
299
300 #define GCM_ENCRYPT 0
301 #define GCM_DECRYPT 1
302
303 #define LTC_GCM_MODE_IV 0
304 #define LTC_GCM_MODE_AAD 1
305 #define LTC_GCM_MODE_TEXT 2
306
307 typedef struct {
308 symmetric_key K;
309 unsigned char H[16], /* multiplier */
310 X[16], /* accumulator */
311 Y[16], /* counter */
312 Y_0[16], /* initial counter */
313 buf[16]; /* buffer for stuff */
314
315 int cipher, /* which cipher */
316 ivmode, /* Which mode is the IV in? */
317 mode, /* mode the GCM code is in */
318 buflen; /* length of data in buf */
319
320 ulong64 totlen, /* 64-bit counter used for IV and AAD */
321 pttotlen; /* 64-bit counter for the PT */
322
323 #ifdef LTC_GCM_TABLES
324 unsigned char PC[16][256][16] /* 16 tables of 8x128 */
325 #ifdef LTC_GCM_TABLES_SSE2
326 __attribute__ ((aligned (16)))
327 #endif
328 ;
329 #endif
330 } gcm_state;
331
332 void gcm_mult_h(gcm_state *gcm, unsigned char *I);
333
334 int gcm_init(gcm_state *gcm, int cipher,
335 const unsigned char *key, int keylen);
336
337 int gcm_reset(gcm_state *gcm);
338
339 int gcm_add_iv(gcm_state *gcm,
340 const unsigned char *IV, unsigned long IVlen);
341
342 int gcm_add_aad(gcm_state *gcm,
343 const unsigned char *adata, unsigned long adatalen);
344
345 int gcm_process(gcm_state *gcm,
346 unsigned char *pt, unsigned long ptlen,
347 unsigned char *ct,
348 int direction);
349
350 int gcm_done(gcm_state *gcm,
351 unsigned char *tag, unsigned long *taglen);
352
353 int gcm_memory( int cipher,
354 const unsigned char *key, unsigned long keylen,
355 const unsigned char *IV, unsigned long IVlen,
356 const unsigned char *adata, unsigned long adatalen,
357 unsigned char *pt, unsigned long ptlen,
358 unsigned char *ct,
359 unsigned char *tag, unsigned long *taglen,
360 int direction);
361 int gcm_test(void);
362
363 #endif /* LTC_GCM_MODE */
364
365 #ifdef LTC_PELICAN
366
367 typedef struct pelican_state
368 {
369 symmetric_key K;
370 unsigned char state[16];
371 int buflen;
372 } pelican_state;
373
374 int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen);
375 int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen);
376 int pelican_done(pelican_state *pelmac, unsigned char *out);
377 int pelican_test(void);
378
379 int pelican_memory(const unsigned char *key, unsigned long keylen,
380 const unsigned char *in, unsigned long inlen,
381 unsigned char *out);
382
383 #endif
384
385 #ifdef LTC_XCBC
386
387 /* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */
388 #define LTC_XCBC_PURE 0x8000UL
389
390 typedef struct {
391 unsigned char K[3][MAXBLOCKSIZE],
392 IV[MAXBLOCKSIZE];
393
394 symmetric_key key;
395
396 int cipher,
397 buflen,
398 blocksize;
399 } xcbc_state;
400
401 int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen);
402 int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen);
403 int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen);
404 int xcbc_memory(int cipher,
405 const unsigned char *key, unsigned long keylen,
406 const unsigned char *in, unsigned long inlen,
407 unsigned char *out, unsigned long *outlen);
408 int xcbc_memory_multi(int cipher,
409 const unsigned char *key, unsigned long keylen,
410 unsigned char *out, unsigned long *outlen,
411 const unsigned char *in, unsigned long inlen, ...);
412 int xcbc_file(int cipher,
413 const unsigned char *key, unsigned long keylen,
414 const char *filename,
415 unsigned char *out, unsigned long *outlen);
416 int xcbc_test(void);
417
418 #endif
419
420 #ifdef LTC_F9_MODE
421
422 typedef struct {
423 unsigned char akey[MAXBLOCKSIZE],
424 ACC[MAXBLOCKSIZE],
425 IV[MAXBLOCKSIZE];
426
427 symmetric_key key;
428
429 int cipher,
430 buflen,
431 keylen,
432 blocksize;
433 } f9_state;
434
435 int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen);
436 int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen);
437 int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
438 int f9_memory(int cipher,
439 const unsigned char *key, unsigned long keylen,
440 const unsigned char *in, unsigned long inlen,
441 unsigned char *out, unsigned long *outlen);
442 int f9_memory_multi(int cipher,
443 const unsigned char *key, unsigned long keylen,
444 unsigned char *out, unsigned long *outlen,
445 const unsigned char *in, unsigned long inlen, ...);
446 int f9_file(int cipher,
447 const unsigned char *key, unsigned long keylen,
448 const char *filename,
449 unsigned char *out, unsigned long *outlen);
450 int f9_test(void);
451
452 #endif
453
454
455 /* $Source$ */
456 /* $Revision$ */
457 /* $Date$ */
0 /* fix for MSVC ...evil! */
1 #ifdef _MSC_VER
2 #define CONST64(n) n ## ui64
3 typedef unsigned __int64 ulong64;
4 #else
5 #define CONST64(n) n ## ULL
6 typedef unsigned long long ulong64;
7 #endif
8
9 /* this is the "32-bit at least" data type
10 * Re-define it to suit your platform but it must be at least 32-bits
11 */
12 #if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__))
13 typedef unsigned ulong32;
14 #else
15 typedef unsigned long ulong32;
16 #endif
17
18 /* ---- HELPER MACROS ---- */
19 #ifdef ENDIAN_NEUTRAL
20
21 #define STORE32L(x, y) \
22 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
23 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
24
25 #define LOAD32L(x, y) \
26 { x = ((unsigned long)((y)[3] & 255)<<24) | \
27 ((unsigned long)((y)[2] & 255)<<16) | \
28 ((unsigned long)((y)[1] & 255)<<8) | \
29 ((unsigned long)((y)[0] & 255)); }
30
31 #define STORE64L(x, y) \
32 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
33 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
34 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
35 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
36
37 #define LOAD64L(x, y) \
38 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
39 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
40 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
41 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
42
43 #define STORE32H(x, y) \
44 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
45 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
46
47 #define LOAD32H(x, y) \
48 { x = ((unsigned long)((y)[0] & 255)<<24) | \
49 ((unsigned long)((y)[1] & 255)<<16) | \
50 ((unsigned long)((y)[2] & 255)<<8) | \
51 ((unsigned long)((y)[3] & 255)); }
52
53 #define STORE64H(x, y) \
54 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
55 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
56 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
57 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
58
59 #define LOAD64H(x, y) \
60 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
61 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
62 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
63 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
64
65 #endif /* ENDIAN_NEUTRAL */
66
67 #ifdef ENDIAN_LITTLE
68
69 #ifdef LTC_HAVE_BSWAP_BUILTIN
70
71 #define STORE32H(x, y) \
72 { ulong32 __t = __builtin_bswap32 ((x)); \
73 XMEMCPY ((y), &__t, 4); }
74
75 #define LOAD32H(x, y) \
76 { XMEMCPY (&(x), (y), 4); \
77 (x) = __builtin_bswap32 ((x)); }
78
79 #elif !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))
80
81 #define STORE32H(x, y) \
82 asm __volatile__ ( \
83 "bswapl %0 \n\t" \
84 "movl %0,(%1)\n\t" \
85 "bswapl %0 \n\t" \
86 ::"r"(x), "r"(y));
87
88 #define LOAD32H(x, y) \
89 asm __volatile__ ( \
90 "movl (%1),%0\n\t" \
91 "bswapl %0\n\t" \
92 :"=r"(x): "r"(y));
93
94 #else
95
96 #define STORE32H(x, y) \
97 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
98 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
99
100 #define LOAD32H(x, y) \
101 { x = ((unsigned long)((y)[0] & 255)<<24) | \
102 ((unsigned long)((y)[1] & 255)<<16) | \
103 ((unsigned long)((y)[2] & 255)<<8) | \
104 ((unsigned long)((y)[3] & 255)); }
105
106 #endif
107
108 #ifdef LTC_HAVE_BSWAP_BUILTIN
109
110 #define STORE64H(x, y) \
111 { ulong64 __t = __builtin_bswap64 ((x)); \
112 XMEMCPY ((y), &__t, 8); }
113
114 #define LOAD64H(x, y) \
115 { XMEMCPY (&(x), (y), 8); \
116 (x) = __builtin_bswap64 ((x)); }
117
118 /* x86_64 processor */
119 #elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
120
121 #define STORE64H(x, y) \
122 asm __volatile__ ( \
123 "bswapq %0 \n\t" \
124 "movq %0,(%1)\n\t" \
125 "bswapq %0 \n\t" \
126 ::"r"(x), "r"(y): "memory");
127
128 #define LOAD64H(x, y) \
129 asm __volatile__ ( \
130 "movq (%1),%0\n\t" \
131 "bswapq %0\n\t" \
132 :"=r"(x): "r"(y): "memory");
133
134 #else
135
136 #define STORE64H(x, y) \
137 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
138 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
139 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
140 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
141
142 #define LOAD64H(x, y) \
143 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
144 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
145 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
146 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
147
148 #endif
149
150 #ifdef ENDIAN_32BITWORD
151
152 #define STORE32L(x, y) \
153 { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
154
155 #define LOAD32L(x, y) \
156 XMEMCPY(&(x), y, 4);
157
158 #define STORE64L(x, y) \
159 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
160 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
161 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
162 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
163
164 #define LOAD64L(x, y) \
165 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
166 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
167 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
168 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
169
170 #else /* 64-bit words then */
171
172 #define STORE32L(x, y) \
173 { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
174
175 #define LOAD32L(x, y) \
176 { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
177
178 #define STORE64L(x, y) \
179 { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
180
181 #define LOAD64L(x, y) \
182 { XMEMCPY(&(x), y, 8); }
183
184 #endif /* ENDIAN_64BITWORD */
185
186 #endif /* ENDIAN_LITTLE */
187
188 #ifdef ENDIAN_BIG
189 #define STORE32L(x, y) \
190 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
191 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
192
193 #define LOAD32L(x, y) \
194 { x = ((unsigned long)((y)[3] & 255)<<24) | \
195 ((unsigned long)((y)[2] & 255)<<16) | \
196 ((unsigned long)((y)[1] & 255)<<8) | \
197 ((unsigned long)((y)[0] & 255)); }
198
199 #define STORE64L(x, y) \
200 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
201 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
202 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
203 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
204
205 #define LOAD64L(x, y) \
206 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
207 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
208 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
209 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
210
211 #ifdef ENDIAN_32BITWORD
212
213 #define STORE32H(x, y) \
214 { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
215
216 #define LOAD32H(x, y) \
217 XMEMCPY(&(x), y, 4);
218
219 #define STORE64H(x, y) \
220 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
221 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
222 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
223 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
224
225 #define LOAD64H(x, y) \
226 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
227 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
228 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
229 (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
230
231 #else /* 64-bit words then */
232
233 #define STORE32H(x, y) \
234 { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
235
236 #define LOAD32H(x, y) \
237 { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
238
239 #define STORE64H(x, y) \
240 { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
241
242 #define LOAD64H(x, y) \
243 { XMEMCPY(&(x), y, 8); }
244
245 #endif /* ENDIAN_64BITWORD */
246 #endif /* ENDIAN_BIG */
247
248 #define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
249 ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
250
251
252 /* 32-bit Rotates */
253 #if defined(_MSC_VER)
254
255 /* instrinsic rotate */
256 #include <stdlib.h>
257 #pragma intrinsic(_lrotr,_lrotl)
258 #define ROR(x,n) _lrotr(x,n)
259 #define ROL(x,n) _lrotl(x,n)
260 #define RORc(x,n) _lrotr(x,n)
261 #define ROLc(x,n) _lrotl(x,n)
262
263 #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
264
265 static inline unsigned ROL(unsigned word, int i)
266 {
267 asm ("roll %%cl,%0"
268 :"=r" (word)
269 :"0" (word),"c" (i));
270 return word;
271 }
272
273 static inline unsigned ROR(unsigned word, int i)
274 {
275 asm ("rorl %%cl,%0"
276 :"=r" (word)
277 :"0" (word),"c" (i));
278 return word;
279 }
280
281 #ifndef LTC_NO_ROLC
282
283 static inline unsigned ROLc(unsigned word, const int i)
284 {
285 asm ("roll %2,%0"
286 :"=r" (word)
287 :"0" (word),"I" (i));
288 return word;
289 }
290
291 static inline unsigned RORc(unsigned word, const int i)
292 {
293 asm ("rorl %2,%0"
294 :"=r" (word)
295 :"0" (word),"I" (i));
296 return word;
297 }
298
299 #else
300
301 #define ROLc ROL
302 #define RORc ROR
303
304 #endif
305
306 #elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
307
308 static inline unsigned ROL(unsigned word, int i)
309 {
310 asm ("rotlw %0,%0,%2"
311 :"=r" (word)
312 :"0" (word),"r" (i));
313 return word;
314 }
315
316 static inline unsigned ROR(unsigned word, int i)
317 {
318 asm ("rotlw %0,%0,%2"
319 :"=r" (word)
320 :"0" (word),"r" (32-i));
321 return word;
322 }
323
324 #ifndef LTC_NO_ROLC
325
326 static inline unsigned ROLc(unsigned word, const int i)
327 {
328 asm ("rotlwi %0,%0,%2"
329 :"=r" (word)
330 :"0" (word),"I" (i));
331 return word;
332 }
333
334 static inline unsigned RORc(unsigned word, const int i)
335 {
336 asm ("rotrwi %0,%0,%2"
337 :"=r" (word)
338 :"0" (word),"I" (i));
339 return word;
340 }
341
342 #else
343
344 #define ROLc ROL
345 #define RORc ROR
346
347 #endif
348
349
350 #else
351
352 /* rotates the hard way */
353 #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
354 #define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
355 #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
356 #define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
357
358 #endif
359
360
361 /* 64-bit Rotates */
362 #if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM)
363
364 static inline unsigned long ROL64(unsigned long word, int i)
365 {
366 asm("rolq %%cl,%0"
367 :"=r" (word)
368 :"0" (word),"c" (i));
369 return word;
370 }
371
372 static inline unsigned long ROR64(unsigned long word, int i)
373 {
374 asm("rorq %%cl,%0"
375 :"=r" (word)
376 :"0" (word),"c" (i));
377 return word;
378 }
379
380 #ifndef LTC_NO_ROLC
381
382 static inline unsigned long ROL64c(unsigned long word, const int i)
383 {
384 asm("rolq %2,%0"
385 :"=r" (word)
386 :"0" (word),"J" (i));
387 return word;
388 }
389
390 static inline unsigned long ROR64c(unsigned long word, const int i)
391 {
392 asm("rorq %2,%0"
393 :"=r" (word)
394 :"0" (word),"J" (i));
395 return word;
396 }
397
398 #else /* LTC_NO_ROLC */
399
400 #define ROL64c ROL64
401 #define ROR64c ROR64
402
403 #endif
404
405 #else /* Not x86_64 */
406
407 #define ROL64(x, y) \
408 ( (((x)<<((ulong64)(y)&63)) | \
409 (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
410
411 #define ROR64(x, y) \
412 ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
413 ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
414
415 #define ROL64c(x, y) \
416 ( (((x)<<((ulong64)(y)&63)) | \
417 (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
418
419 #define ROR64c(x, y) \
420 ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
421 ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
422
423 #endif
424
425 #ifndef MAX
426 #define MAX(x, y) ( ((x)>(y))?(x):(y) )
427 #endif
428
429 #ifndef MIN
430 #define MIN(x, y) ( ((x)<(y))?(x):(y) )
431 #endif
432
433 /* extract a byte portably */
434 #ifdef _MSC_VER
435 #define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
436 #else
437 #define byte(x, n) (((x) >> (8 * (n))) & 255)
438 #endif
439
440 /* $Source$ */
441 /* $Revision$ */
442 /* $Date$ */
0 /** math functions **/
1
2 #define LTC_MP_LT -1
3 #define LTC_MP_EQ 0
4 #define LTC_MP_GT 1
5
6 #define LTC_MP_NO 0
7 #define LTC_MP_YES 1
8
9 #ifndef LTC_MECC
10 typedef void ecc_point;
11 #endif
12
13 #ifndef LTC_MRSA
14 typedef void rsa_key;
15 #endif
16
17 /** math descriptor */
18 typedef struct {
19 /** Name of the math provider */
20 char *name;
21
22 /** Bits per digit, amount of bits must fit in an unsigned long */
23 int bits_per_digit;
24
25 /* ---- init/deinit functions ---- */
26
27 /** initialize a bignum
28 @param a The number to initialize
29 @return CRYPT_OK on success
30 */
31 int (*init)(void **a);
32
33 /** init copy
34 @param dst The number to initialize and write to
35 @param src The number to copy from
36 @return CRYPT_OK on success
37 */
38 int (*init_copy)(void **dst, void *src);
39
40 /** deinit
41 @param a The number to free
42 @return CRYPT_OK on success
43 */
44 void (*deinit)(void *a);
45
46 /* ---- data movement ---- */
47
48 /** negate
49 @param src The number to negate
50 @param dst The destination
51 @return CRYPT_OK on success
52 */
53 int (*neg)(void *src, void *dst);
54
55 /** copy
56 @param src The number to copy from
57 @param dst The number to write to
58 @return CRYPT_OK on success
59 */
60 int (*copy)(void *src, void *dst);
61
62 /* ---- trivial low level functions ---- */
63
64 /** set small constant
65 @param a Number to write to
66 @param n Source upto bits_per_digit (actually meant for very small constants)
67 @return CRYPT_OK on succcess
68 */
69 int (*set_int)(void *a, unsigned long n);
70
71 /** get small constant
72 @param a Number to read, only fetches upto bits_per_digit from the number
73 @return The lower bits_per_digit of the integer (unsigned)
74 */
75 unsigned long (*get_int)(void *a);
76
77 /** get digit n
78 @param a The number to read from
79 @param n The number of the digit to fetch
80 @return The bits_per_digit sized n'th digit of a
81 */
82 unsigned long (*get_digit)(void *a, int n);
83
84 /** Get the number of digits that represent the number
85 @param a The number to count
86 @return The number of digits used to represent the number
87 */
88 int (*get_digit_count)(void *a);
89
90 /** compare two integers
91 @param a The left side integer
92 @param b The right side integer
93 @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison)
94 */
95 int (*compare)(void *a, void *b);
96
97 /** compare against int
98 @param a The left side integer
99 @param b The right side integer (upto bits_per_digit)
100 @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison)
101 */
102 int (*compare_d)(void *a, unsigned long n);
103
104 /** Count the number of bits used to represent the integer
105 @param a The integer to count
106 @return The number of bits required to represent the integer
107 */
108 int (*count_bits)(void * a);
109
110 /** Count the number of LSB bits which are zero
111 @param a The integer to count
112 @return The number of contiguous zero LSB bits
113 */
114 int (*count_lsb_bits)(void *a);
115
116 /** Compute a power of two
117 @param a The integer to store the power in
118 @param n The power of two you want to store (a = 2^n)
119 @return CRYPT_OK on success
120 */
121 int (*twoexpt)(void *a , int n);
122
123 /* ---- radix conversions ---- */
124
125 /** read ascii string
126 @param a The integer to store into
127 @param str The string to read
128 @param radix The radix the integer has been represented in (2-64)
129 @return CRYPT_OK on success
130 */
131 int (*read_radix)(void *a, const char *str, int radix);
132
133 /** write number to string
134 @param a The integer to store
135 @param str The destination for the string
136 @param radix The radix the integer is to be represented in (2-64)
137 @return CRYPT_OK on success
138 */
139 int (*write_radix)(void *a, char *str, int radix);
140
141 /** get size as unsigned char string
142 @param a The integer to get the size (when stored in array of octets)
143 @return The length of the integer
144 */
145 unsigned long (*unsigned_size)(void *a);
146
147 /** store an integer as an array of octets
148 @param src The integer to store
149 @param dst The buffer to store the integer in
150 @return CRYPT_OK on success
151 */
152 int (*unsigned_write)(void *src, unsigned char *dst);
153
154 /** read an array of octets and store as integer
155 @param dst The integer to load
156 @param src The array of octets
157 @param len The number of octets
158 @return CRYPT_OK on success
159 */
160 int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len);
161
162 /* ---- basic math ---- */
163
164 /** add two integers
165 @param a The first source integer
166 @param b The second source integer
167 @param c The destination of "a + b"
168 @return CRYPT_OK on success
169 */
170 int (*add)(void *a, void *b, void *c);
171
172
173 /** add two integers
174 @param a The first source integer
175 @param b The second source integer (single digit of upto bits_per_digit in length)
176 @param c The destination of "a + b"
177 @return CRYPT_OK on success
178 */
179 int (*addi)(void *a, unsigned long b, void *c);
180
181 /** subtract two integers
182 @param a The first source integer
183 @param b The second source integer
184 @param c The destination of "a - b"
185 @return CRYPT_OK on success
186 */
187 int (*sub)(void *a, void *b, void *c);
188
189 /** subtract two integers
190 @param a The first source integer
191 @param b The second source integer (single digit of upto bits_per_digit in length)
192 @param c The destination of "a - b"
193 @return CRYPT_OK on success
194 */
195 int (*subi)(void *a, unsigned long b, void *c);
196
197 /** multiply two integers
198 @param a The first source integer
199 @param b The second source integer (single digit of upto bits_per_digit in length)
200 @param c The destination of "a * b"
201 @return CRYPT_OK on success
202 */
203 int (*mul)(void *a, void *b, void *c);
204
205 /** multiply two integers
206 @param a The first source integer
207 @param b The second source integer (single digit of upto bits_per_digit in length)
208 @param c The destination of "a * b"
209 @return CRYPT_OK on success
210 */
211 int (*muli)(void *a, unsigned long b, void *c);
212
213 /** Square an integer
214 @param a The integer to square
215 @param b The destination
216 @return CRYPT_OK on success
217 */
218 int (*sqr)(void *a, void *b);
219
220 /** Divide an integer
221 @param a The dividend
222 @param b The divisor
223 @param c The quotient (can be NULL to signify don't care)
224 @param d The remainder (can be NULL to signify don't care)
225 @return CRYPT_OK on success
226 */
227 int (*mpdiv)(void *a, void *b, void *c, void *d);
228
229 /** divide by two
230 @param a The integer to divide (shift right)
231 @param b The destination
232 @return CRYPT_OK on success
233 */
234 int (*div_2)(void *a, void *b);
235
236 /** Get remainder (small value)
237 @param a The integer to reduce
238 @param b The modulus (upto bits_per_digit in length)
239 @param c The destination for the residue
240 @return CRYPT_OK on success
241 */
242 int (*modi)(void *a, unsigned long b, unsigned long *c);
243
244 /** gcd
245 @param a The first integer
246 @param b The second integer
247 @param c The destination for (a, b)
248 @return CRYPT_OK on success
249 */
250 int (*gcd)(void *a, void *b, void *c);
251
252 /** lcm
253 @param a The first integer
254 @param b The second integer
255 @param c The destination for [a, b]
256 @return CRYPT_OK on success
257 */
258 int (*lcm)(void *a, void *b, void *c);
259
260 /** Modular multiplication
261 @param a The first source
262 @param b The second source
263 @param c The modulus
264 @param d The destination (a*b mod c)
265 @return CRYPT_OK on success
266 */
267 int (*mulmod)(void *a, void *b, void *c, void *d);
268
269 /** Modular squaring
270 @param a The first source
271 @param b The modulus
272 @param c The destination (a*a mod b)
273 @return CRYPT_OK on success
274 */
275 int (*sqrmod)(void *a, void *b, void *c);
276
277 /** Modular inversion
278 @param a The value to invert
279 @param b The modulus
280 @param c The destination (1/a mod b)
281 @return CRYPT_OK on success
282 */
283 int (*invmod)(void *, void *, void *);
284
285 /* ---- reduction ---- */
286
287 /** setup montgomery
288 @param a The modulus
289 @param b The destination for the reduction digit
290 @return CRYPT_OK on success
291 */
292 int (*montgomery_setup)(void *a, void **b);
293
294 /** get normalization value
295 @param a The destination for the normalization value
296 @param b The modulus
297 @return CRYPT_OK on success
298 */
299 int (*montgomery_normalization)(void *a, void *b);
300
301 /** reduce a number
302 @param a The number [and dest] to reduce
303 @param b The modulus
304 @param c The value "b" from montgomery_setup()
305 @return CRYPT_OK on success
306 */
307 int (*montgomery_reduce)(void *a, void *b, void *c);
308
309 /** clean up (frees memory)
310 @param a The value "b" from montgomery_setup()
311 @return CRYPT_OK on success
312 */
313 void (*montgomery_deinit)(void *a);
314
315 /* ---- exponentiation ---- */
316
317 /** Modular exponentiation
318 @param a The base integer
319 @param b The power (can be negative) integer
320 @param c The modulus integer
321 @param d The destination
322 @return CRYPT_OK on success
323 */
324 int (*exptmod)(void *a, void *b, void *c, void *d);
325
326 /** Primality testing
327 @param a The integer to test
328 @param b The destination of the result (FP_YES if prime)
329 @return CRYPT_OK on success
330 */
331 int (*isprime)(void *a, int *b);
332
333 /* ---- (optional) ecc point math ---- */
334
335 /** ECC GF(p) point multiplication (from the NIST curves)
336 @param k The integer to multiply the point by
337 @param G The point to multiply
338 @param R The destination for kG
339 @param modulus The modulus for the field
340 @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only)
341 @return CRYPT_OK on success
342 */
343 int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
344
345 /** ECC GF(p) point addition
346 @param P The first point
347 @param Q The second point
348 @param R The destination of P + Q
349 @param modulus The modulus
350 @param mp The "b" value from montgomery_setup()
351 @return CRYPT_OK on success
352 */
353 int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
354
355 /** ECC GF(p) point double
356 @param P The first point
357 @param R The destination of 2P
358 @param modulus The modulus
359 @param mp The "b" value from montgomery_setup()
360 @return CRYPT_OK on success
361 */
362 int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp);
363
364 /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1)
365 @param P The point to map
366 @param modulus The modulus
367 @param mp The "b" value from montgomery_setup()
368 @return CRYPT_OK on success
369 @remark The mapping can be different but keep in mind a ecc_point only has three
370 integers (x,y,z) so if you use a different mapping you have to make it fit.
371 */
372 int (*ecc_map)(ecc_point *P, void *modulus, void *mp);
373
374 /** Computes kA*A + kB*B = C using Shamir's Trick
375 @param A First point to multiply
376 @param kA What to multiple A by
377 @param B Second point to multiply
378 @param kB What to multiple B by
379 @param C [out] Destination point (can overlap with A or B
380 @param modulus Modulus for curve
381 @return CRYPT_OK on success
382 */
383 int (*ecc_mul2add)(ecc_point *A, void *kA,
384 ecc_point *B, void *kB,
385 ecc_point *C,
386 void *modulus);
387
388 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
389
390 /** RSA Key Generation
391 @param prng An active PRNG state
392 @param wprng The index of the PRNG desired
393 @param size The size of the modulus (key size) desired (octets)
394 @param e The "e" value (public key). e==65537 is a good choice
395 @param key [out] Destination of a newly created private key pair
396 @return CRYPT_OK if successful, upon error all allocated ram is freed
397 */
398 int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
399
400
401 /** RSA exponentiation
402 @param in The octet array representing the base
403 @param inlen The length of the input
404 @param out The destination (to be stored in an octet array format)
405 @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus)
406 @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
407 @param key The RSA key to use
408 @return CRYPT_OK on success
409 */
410 int (*rsa_me)(const unsigned char *in, unsigned long inlen,
411 unsigned char *out, unsigned long *outlen, int which,
412 rsa_key *key);
413
414 /* ---- basic math continued ---- */
415
416 /** Modular addition
417 @param a The first source
418 @param b The second source
419 @param c The modulus
420 @param d The destination (a + b mod c)
421 @return CRYPT_OK on success
422 */
423 int (*addmod)(void *a, void *b, void *c, void *d);
424
425 /** Modular substraction
426 @param a The first source
427 @param b The second source
428 @param c The modulus
429 @param d The destination (a - b mod c)
430 @return CRYPT_OK on success
431 */
432 int (*submod)(void *a, void *b, void *c, void *d);
433
434 /* ---- misc stuff ---- */
435 /** Make a pseudo-random mpi
436 @param a The mpi to make random
437 @param size The desired length
438 @return CRYPT_OK on success
439 */
440 int (*rand)(void *a, int size);
441
442 } ltc_math_descriptor;
443
444 extern ltc_math_descriptor ltc_mp;
445
446 int ltc_init_multi(void **a, ...);
447 void ltc_deinit_multi(void *a, ...);
448
449 #ifdef LTM_DESC
450 extern const ltc_math_descriptor ltm_desc;
451 #endif
452
453 #ifdef TFM_DESC
454 extern const ltc_math_descriptor tfm_desc;
455 #endif
456
457 #ifdef GMP_DESC
458 extern const ltc_math_descriptor gmp_desc;
459 #endif
460
461 #if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE)
462
463 #define MP_DIGIT_BIT ltc_mp.bits_per_digit
464
465 /* some handy macros */
466 #define mp_init(a) ltc_mp.init(a)
467 #define mp_init_multi ltc_init_multi
468 #define mp_clear(a) ltc_mp.deinit(a)
469 #define mp_clear_multi ltc_deinit_multi
470 #define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
471
472 #define mp_neg(a, b) ltc_mp.neg(a, b)
473 #define mp_copy(a, b) ltc_mp.copy(a, b)
474
475 #define mp_set(a, b) ltc_mp.set_int(a, b)
476 #define mp_set_int(a, b) ltc_mp.set_int(a, b)
477 #define mp_get_int(a) ltc_mp.get_int(a)
478 #define mp_get_digit(a, n) ltc_mp.get_digit(a, n)
479 #define mp_get_digit_count(a) ltc_mp.get_digit_count(a)
480 #define mp_cmp(a, b) ltc_mp.compare(a, b)
481 #define mp_cmp_d(a, b) ltc_mp.compare_d(a, b)
482 #define mp_count_bits(a) ltc_mp.count_bits(a)
483 #define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a)
484 #define mp_2expt(a, b) ltc_mp.twoexpt(a, b)
485
486 #define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c)
487 #define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c)
488 #define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
489 #define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
490 #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
491
492 #define mp_add(a, b, c) ltc_mp.add(a, b, c)
493 #define mp_add_d(a, b, c) ltc_mp.addi(a, b, c)
494 #define mp_sub(a, b, c) ltc_mp.sub(a, b, c)
495 #define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c)
496 #define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
497 #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
498 #define mp_sqr(a, b) ltc_mp.sqr(a, b)
499 #define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
500 #define mp_div_2(a, b) ltc_mp.div_2(a, b)
501 #define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
502 #define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c)
503 #define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c)
504 #define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c)
505
506 #define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d)
507 #define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d)
508 #define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d)
509 #define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c)
510 #define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c)
511
512 #define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b)
513 #define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)
514 #define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c)
515 #define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a)
516
517 #define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
518 #define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, c)
519
520 #define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)
521 #define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO)
522 #define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0);
523
524 #define mp_tohex(a, b) mp_toradix(a, b, 16)
525
526 #define mp_rand(a, b) ltc_mp.rand(a, b)
527
528 #endif
529
530 /* $Source$ */
531 /* $Revision$ */
532 /* $Date$ */
0 /* ---- LTC_BASE64 Routines ---- */
1 #ifdef LTC_BASE64
2 int base64_encode(const unsigned char *in, unsigned long len,
3 unsigned char *out, unsigned long *outlen);
4
5 int base64_decode(const unsigned char *in, unsigned long len,
6 unsigned char *out, unsigned long *outlen);
7
8 int base64url_encode(const unsigned char *in, unsigned long len,
9 unsigned char *out, unsigned long *outlen);
10
11 int base64url_decode(const unsigned char *in, unsigned long len,
12 unsigned char *out, unsigned long *outlen);
13 #endif
14
15 /* ---- MEM routines ---- */
16 void zeromem(volatile void *dst, size_t len);
17 void burn_stack(unsigned long len);
18
19 const char *error_to_string(int err);
20
21 extern const char *crypt_build_settings;
22
23 /* ---- HMM ---- */
24 int crypt_fsa(void *mp, ...);
25
26 /* $Source$ */
27 /* $Revision$ */
28 /* $Date$ */
0 /* ---- NUMBER THEORY ---- */
1
2 enum {
3 PK_PUBLIC=0,
4 PK_PRIVATE=1
5 };
6
7 int rand_prime(void *N, long len, prng_state *prng, int wprng);
8
9 enum {
10 PKA_RSA,
11 PKA_DSA
12 };
13
14 typedef struct Oid {
15 unsigned long OID[16];
16 /** Length of DER encoding */
17 unsigned long OIDlen;
18 } oid_st;
19
20 int pk_get_oid(int pk, oid_st *st);
21
22 /* ---- RSA ---- */
23 #ifdef LTC_MRSA
24
25 /* Min and Max RSA key sizes (in bits) */
26 #define MIN_RSA_SIZE 1024
27 #define MAX_RSA_SIZE 4096
28
29 /** RSA LTC_PKCS style key */
30 typedef struct Rsa_key {
31 /** Type of key, PK_PRIVATE or PK_PUBLIC */
32 int type;
33 /** The public exponent */
34 void *e;
35 /** The private exponent */
36 void *d;
37 /** The modulus */
38 void *N;
39 /** The p factor of N */
40 void *p;
41 /** The q factor of N */
42 void *q;
43 /** The 1/q mod p CRT param */
44 void *qP;
45 /** The d mod (p - 1) CRT param */
46 void *dP;
47 /** The d mod (q - 1) CRT param */
48 void *dQ;
49 } rsa_key;
50
51 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
52
53 int rsa_exptmod(const unsigned char *in, unsigned long inlen,
54 unsigned char *out, unsigned long *outlen, int which,
55 rsa_key *key);
56
57 void rsa_free(rsa_key *key);
58
59 /* These use LTC_PKCS #1 v2.0 padding */
60 #define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \
61 rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_PKCS_1_OAEP, _key)
62
63 #define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \
64 rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_PKCS_1_OAEP, _stat, _key)
65
66 #define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \
67 rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key)
68
69 #define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \
70 rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key)
71
72 /* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */
73 int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
74 unsigned char *out, unsigned long *outlen,
75 const unsigned char *lparam, unsigned long lparamlen,
76 prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key);
77
78 int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
79 unsigned char *out, unsigned long *outlen,
80 const unsigned char *lparam, unsigned long lparamlen,
81 int hash_idx, int padding,
82 int *stat, rsa_key *key);
83
84 int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
85 unsigned char *out, unsigned long *outlen,
86 int padding,
87 prng_state *prng, int prng_idx,
88 int hash_idx, unsigned long saltlen,
89 rsa_key *key);
90
91 int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
92 const unsigned char *hash, unsigned long hashlen,
93 int padding,
94 int hash_idx, unsigned long saltlen,
95 int *stat, rsa_key *key);
96
97 /* LTC_PKCS #1 import/export */
98 int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
99 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
100
101 #endif
102
103 /* ---- Katja ---- */
104 #ifdef MKAT
105
106 /* Min and Max KAT key sizes (in bits) */
107 #define MIN_KAT_SIZE 1024
108 #define MAX_KAT_SIZE 4096
109
110 /** Katja LTC_PKCS style key */
111 typedef struct KAT_key {
112 /** Type of key, PK_PRIVATE or PK_PUBLIC */
113 int type;
114 /** The private exponent */
115 void *d;
116 /** The modulus */
117 void *N;
118 /** The p factor of N */
119 void *p;
120 /** The q factor of N */
121 void *q;
122 /** The 1/q mod p CRT param */
123 void *qP;
124 /** The d mod (p - 1) CRT param */
125 void *dP;
126 /** The d mod (q - 1) CRT param */
127 void *dQ;
128 /** The pq param */
129 void *pq;
130 } katja_key;
131
132 int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key);
133
134 int katja_exptmod(const unsigned char *in, unsigned long inlen,
135 unsigned char *out, unsigned long *outlen, int which,
136 katja_key *key);
137
138 void katja_free(katja_key *key);
139
140 /* These use LTC_PKCS #1 v2.0 padding */
141 int katja_encrypt_key(const unsigned char *in, unsigned long inlen,
142 unsigned char *out, unsigned long *outlen,
143 const unsigned char *lparam, unsigned long lparamlen,
144 prng_state *prng, int prng_idx, int hash_idx, katja_key *key);
145
146 int katja_decrypt_key(const unsigned char *in, unsigned long inlen,
147 unsigned char *out, unsigned long *outlen,
148 const unsigned char *lparam, unsigned long lparamlen,
149 int hash_idx, int *stat,
150 katja_key *key);
151
152 /* LTC_PKCS #1 import/export */
153 int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key);
154 int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key);
155
156 #endif
157
158 /* ---- DH Routines ---- */
159 #ifdef MDH
160
161 typedef struct Dh_key {
162 int idx, type;
163 void *x;
164 void *y;
165 } dh_key;
166
167 int dh_compat_test(void);
168 void dh_sizes(int *low, int *high);
169 int dh_get_size(dh_key *key);
170
171 int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key);
172 void dh_free(dh_key *key);
173
174 int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key);
175 int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key);
176
177 int dh_shared_secret(dh_key *private_key, dh_key *public_key,
178 unsigned char *out, unsigned long *outlen);
179
180 int dh_encrypt_key(const unsigned char *in, unsigned long keylen,
181 unsigned char *out, unsigned long *outlen,
182 prng_state *prng, int wprng, int hash,
183 dh_key *key);
184
185 int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
186 unsigned char *out, unsigned long *outlen,
187 dh_key *key);
188
189 int dh_sign_hash(const unsigned char *in, unsigned long inlen,
190 unsigned char *out, unsigned long *outlen,
191 prng_state *prng, int wprng, dh_key *key);
192
193 int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
194 const unsigned char *hash, unsigned long hashlen,
195 int *stat, dh_key *key);
196
197
198 #endif
199
200
201 /* ---- ECC Routines ---- */
202 #ifdef LTC_MECC
203
204 /* size of our temp buffers for exported keys */
205 #define ECC_BUF_SIZE 256
206
207 /* max private key size */
208 #define ECC_MAXSIZE 66
209
210 /** Structure defines a NIST GF(p) curve */
211 typedef struct {
212 /** The size of the curve in octets */
213 int size;
214
215 /** name of curve */
216 char *name;
217
218 /** The prime that defines the field the curve is in (encoded in hex) */
219 char *prime;
220
221 /** The fields B param (hex) */
222 char *B;
223
224 /** The order of the curve (hex) */
225 char *order;
226
227 /** The x co-ordinate of the base point on the curve (hex) */
228 char *Gx;
229
230 /** The y co-ordinate of the base point on the curve (hex) */
231 char *Gy;
232 } ltc_ecc_set_type;
233
234 /** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */
235 typedef struct {
236 /** The x co-ordinate */
237 void *x;
238
239 /** The y co-ordinate */
240 void *y;
241
242 /** The z co-ordinate */
243 void *z;
244 } ecc_point;
245
246 /** An ECC key */
247 typedef struct {
248 /** Type of key, PK_PRIVATE or PK_PUBLIC */
249 int type;
250
251 /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */
252 int idx;
253
254 /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */
255 const ltc_ecc_set_type *dp;
256
257 /** The public key */
258 ecc_point pubkey;
259
260 /** The private key */
261 void *k;
262 } ecc_key;
263
264 /** the ECC params provided */
265 extern const ltc_ecc_set_type ltc_ecc_sets[];
266
267 int ecc_test(void);
268 void ecc_sizes(int *low, int *high);
269 int ecc_get_size(ecc_key *key);
270
271 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
272 int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
273 void ecc_free(ecc_key *key);
274
275 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
276 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
277 int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp);
278
279 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
280 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
281 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
282
283 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
284 unsigned char *out, unsigned long *outlen);
285
286 int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
287 unsigned char *out, unsigned long *outlen,
288 prng_state *prng, int wprng, int hash,
289 ecc_key *key);
290
291 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
292 unsigned char *out, unsigned long *outlen,
293 ecc_key *key);
294
295 int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
296 unsigned char *out, unsigned long *outlen,
297 prng_state *prng, int wprng, ecc_key *key);
298
299 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
300 const unsigned char *hash, unsigned long hashlen,
301 int *stat, ecc_key *key);
302
303 /* low level functions */
304 ecc_point *ltc_ecc_new_point(void);
305 void ltc_ecc_del_point(ecc_point *p);
306 int ltc_ecc_is_valid_idx(int n);
307
308 /* point ops (mp == montgomery digit) */
309 #if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC)
310 /* R = 2P */
311 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
312
313 /* R = P + Q */
314 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
315 #endif
316
317 #if defined(LTC_MECC_FP)
318 /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
319 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
320
321 /* functions for saving/loading/freeing/adding to fixed point cache */
322 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
323 int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen);
324 void ltc_ecc_fp_free(void);
325 int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock);
326
327 /* lock/unlock all points currently in fixed point cache */
328 void ltc_ecc_fp_tablelock(int lock);
329 #endif
330
331 /* R = kG */
332 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
333
334 #ifdef LTC_ECC_SHAMIR
335 /* kA*A + kB*B = C */
336 int ltc_ecc_mul2add(ecc_point *A, void *kA,
337 ecc_point *B, void *kB,
338 ecc_point *C,
339 void *modulus);
340
341 #ifdef LTC_MECC_FP
342 /* Shamir's trick with optimized point multiplication using fixed point cache */
343 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
344 ecc_point *B, void *kB,
345 ecc_point *C, void *modulus);
346 #endif
347
348 #endif
349
350
351 /* map P to affine from projective */
352 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
353
354 #endif
355
356 #ifdef LTC_MDSA
357
358 /* Max diff between group and modulus size in bytes */
359 #define LTC_MDSA_DELTA 512
360
361 /* Max DSA group size in bytes (default allows 4k-bit groups) */
362 #define LTC_MDSA_MAX_GROUP 512
363
364 /** DSA key structure */
365 typedef struct {
366 /** The key type, PK_PRIVATE or PK_PUBLIC */
367 int type;
368
369 /** The order of the sub-group used in octets */
370 int qord;
371
372 /** The generator */
373 void *g;
374
375 /** The prime used to generate the sub-group */
376 void *q;
377
378 /** The large prime that generats the field the contains the sub-group */
379 void *p;
380
381 /** The private key */
382 void *x;
383
384 /** The public key */
385 void *y;
386 } dsa_key;
387
388 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
389 void dsa_free(dsa_key *key);
390
391 int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
392 void *r, void *s,
393 prng_state *prng, int wprng, dsa_key *key);
394
395 int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
396 unsigned char *out, unsigned long *outlen,
397 prng_state *prng, int wprng, dsa_key *key);
398
399 int dsa_verify_hash_raw( void *r, void *s,
400 const unsigned char *hash, unsigned long hashlen,
401 int *stat, dsa_key *key);
402
403 int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
404 const unsigned char *hash, unsigned long hashlen,
405 int *stat, dsa_key *key);
406
407 int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
408 unsigned char *out, unsigned long *outlen,
409 prng_state *prng, int wprng, int hash,
410 dsa_key *key);
411
412 int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
413 unsigned char *out, unsigned long *outlen,
414 dsa_key *key);
415
416 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
417 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
418 int dsa_verify_key(dsa_key *key, int *stat);
419
420 int dsa_shared_secret(void *private_key, void *base,
421 dsa_key *public_key,
422 unsigned char *out, unsigned long *outlen);
423 #endif
424
425 #ifdef LTC_DER
426 /* DER handling */
427
428 enum {
429 LTC_ASN1_EOL,
430 LTC_ASN1_BOOLEAN,
431 LTC_ASN1_INTEGER,
432 LTC_ASN1_SHORT_INTEGER,
433 LTC_ASN1_BIT_STRING,
434 LTC_ASN1_OCTET_STRING,
435 LTC_ASN1_NULL,
436 LTC_ASN1_OBJECT_IDENTIFIER,
437 LTC_ASN1_IA5_STRING,
438 LTC_ASN1_PRINTABLE_STRING,
439 LTC_ASN1_UTF8_STRING,
440 LTC_ASN1_UTCTIME,
441 LTC_ASN1_CHOICE,
442 LTC_ASN1_SEQUENCE,
443 LTC_ASN1_SET,
444 LTC_ASN1_SETOF,
445 LTC_ASN1_RAW_BIT_STRING,
446 LTC_ASN1_TELETEX_STRING,
447 LTC_ASN1_CONSTRUCTED,
448 };
449
450 /** A LTC ASN.1 list type */
451 typedef struct ltc_asn1_list_ {
452 /** The LTC ASN.1 enumerated type identifier */
453 int type;
454 /** The data to encode or place for decoding */
455 void *data;
456 /** The size of the input or resulting output */
457 unsigned long size;
458 /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
459 int used;
460 /** prev/next entry in the list */
461 struct ltc_asn1_list_ *prev, *next, *child, *parent;
462 } ltc_asn1_list;
463
464 #define LTC_SET_ASN1(list, index, Type, Data, Size) \
465 do { \
466 int LTC_MACRO_temp = (index); \
467 ltc_asn1_list *LTC_MACRO_list = (list); \
468 LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
469 LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
470 LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
471 LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
472 } while (0);
473
474 /* SEQUENCE */
475 int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
476 unsigned char *out, unsigned long *outlen, int type_of);
477
478 #define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE)
479
480 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
481 ltc_asn1_list *list, unsigned long outlen, int ordered);
482
483 #define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
484
485 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
486 unsigned long *outlen);
487
488 /* SUBJECT PUBLIC KEY INFO */
489 int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
490 unsigned int algorithm, void* public_key, unsigned long public_key_len,
491 unsigned long parameters_type, void* parameters, unsigned long parameters_len);
492
493 int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
494 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
495 unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len);
496
497 /* SET */
498 #define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
499 #define der_length_set der_length_sequence
500 int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
501 unsigned char *out, unsigned long *outlen);
502
503 int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
504 unsigned char *out, unsigned long *outlen);
505
506 /* VA list handy helpers with triplets of <type, size, data> */
507 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
508 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
509
510 /* FLEXI DECODER handle unknown list decoder */
511 int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
512 void der_free_sequence_flexi(ltc_asn1_list *list);
513 void der_sequence_free(ltc_asn1_list *in);
514
515 /* BOOLEAN */
516 int der_length_boolean(unsigned long *outlen);
517 int der_encode_boolean(int in,
518 unsigned char *out, unsigned long *outlen);
519 int der_decode_boolean(const unsigned char *in, unsigned long inlen,
520 int *out);
521 /* INTEGER */
522 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
523 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);
524 int der_length_integer(void *num, unsigned long *len);
525
526 /* INTEGER -- handy for 0..2^32-1 values */
527 int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num);
528 int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen);
529 int der_length_short_integer(unsigned long num, unsigned long *outlen);
530
531 /* BIT STRING */
532 int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
533 unsigned char *out, unsigned long *outlen);
534 int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
535 unsigned char *out, unsigned long *outlen);
536 int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
537 unsigned char *out, unsigned long *outlen);
538 int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
539 unsigned char *out, unsigned long *outlen);
540 int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
541
542 /* OCTET STRING */
543 int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
544 unsigned char *out, unsigned long *outlen);
545 int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
546 unsigned char *out, unsigned long *outlen);
547 int der_length_octet_string(unsigned long noctets, unsigned long *outlen);
548
549 /* OBJECT IDENTIFIER */
550 int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
551 unsigned char *out, unsigned long *outlen);
552 int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
553 unsigned long *words, unsigned long *outlen);
554 int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen);
555 unsigned long der_object_identifier_bits(unsigned long x);
556
557 /* IA5 STRING */
558 int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
559 unsigned char *out, unsigned long *outlen);
560 int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
561 unsigned char *out, unsigned long *outlen);
562 int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
563
564 int der_ia5_char_encode(int c);
565 int der_ia5_value_decode(int v);
566
567 /* TELETEX STRING */
568 int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
569 unsigned char *out, unsigned long *outlen);
570 int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
571
572 int der_teletex_char_encode(int c);
573 int der_teletex_value_decode(int v);
574
575 /* PRINTABLE STRING */
576 int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
577 unsigned char *out, unsigned long *outlen);
578 int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
579 unsigned char *out, unsigned long *outlen);
580 int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
581
582 int der_printable_char_encode(int c);
583 int der_printable_value_decode(int v);
584
585 /* UTF-8 */
586 #if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR)
587 #include <wchar.h>
588 #else
589 typedef ulong32 wchar_t;
590 #endif
591
592 int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,
593 unsigned char *out, unsigned long *outlen);
594
595 int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
596 wchar_t *out, unsigned long *outlen);
597 unsigned long der_utf8_charsize(const wchar_t c);
598 int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen);
599
600
601 /* CHOICE */
602 int der_decode_choice(const unsigned char *in, unsigned long *inlen,
603 ltc_asn1_list *list, unsigned long outlen);
604
605 /* UTCTime */
606 typedef struct {
607 unsigned YY, /* year */
608 MM, /* month */
609 DD, /* day */
610 hh, /* hour */
611 mm, /* minute */
612 ss, /* second */
613 off_dir, /* timezone offset direction 0 == +, 1 == - */
614 off_hh, /* timezone offset hours */
615 off_mm; /* timezone offset minutes */
616 } ltc_utctime;
617
618 int der_encode_utctime(ltc_utctime *utctime,
619 unsigned char *out, unsigned long *outlen);
620
621 int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
622 ltc_utctime *out);
623
624 int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
625
626
627 #endif
628
629 /* $Source$ */
630 /* $Revision$ */
631 /* $Date$ */
0 /* LTC_PKCS Header Info */
1
2 /* ===> LTC_PKCS #1 -- RSA Cryptography <=== */
3 #ifdef LTC_PKCS_1
4
5 enum ltc_pkcs_1_v1_5_blocks
6 {
7 LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */
8 LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */
9 };
10
11 enum ltc_pkcs_1_paddings
12 {
13 LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */
14 LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */
15 LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */
16 };
17
18 int pkcs_1_mgf1( int hash_idx,
19 const unsigned char *seed, unsigned long seedlen,
20 unsigned char *mask, unsigned long masklen);
21
22 int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
23 int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen);
24
25 /* *** v1.5 padding */
26 int pkcs_1_v1_5_encode(const unsigned char *msg,
27 unsigned long msglen,
28 int block_type,
29 unsigned long modulus_bitlen,
30 prng_state *prng,
31 int prng_idx,
32 unsigned char *out,
33 unsigned long *outlen);
34
35 int pkcs_1_v1_5_decode(const unsigned char *msg,
36 unsigned long msglen,
37 int block_type,
38 unsigned long modulus_bitlen,
39 unsigned char *out,
40 unsigned long *outlen,
41 int *is_valid);
42
43 /* *** v2.1 padding */
44 int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
45 const unsigned char *lparam, unsigned long lparamlen,
46 unsigned long modulus_bitlen, prng_state *prng,
47 int prng_idx, int hash_idx,
48 unsigned char *out, unsigned long *outlen);
49
50 int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
51 const unsigned char *lparam, unsigned long lparamlen,
52 unsigned long modulus_bitlen, int hash_idx,
53 unsigned char *out, unsigned long *outlen,
54 int *res);
55
56 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
57 unsigned long saltlen, prng_state *prng,
58 int prng_idx, int hash_idx,
59 unsigned long modulus_bitlen,
60 unsigned char *out, unsigned long *outlen);
61
62 int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
63 const unsigned char *sig, unsigned long siglen,
64 unsigned long saltlen, int hash_idx,
65 unsigned long modulus_bitlen, int *res);
66
67 #endif /* LTC_PKCS_1 */
68
69 /* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */
70 #ifdef LTC_PKCS_5
71
72 /* Algorithm #1 (old) */
73 int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
74 const unsigned char *salt,
75 int iteration_count, int hash_idx,
76 unsigned char *out, unsigned long *outlen);
77
78 /* Algorithm #2 (new) */
79 int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
80 const unsigned char *salt, unsigned long salt_len,
81 int iteration_count, int hash_idx,
82 unsigned char *out, unsigned long *outlen);
83
84 #endif /* LTC_PKCS_5 */
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
0 /* ---- PRNG Stuff ---- */
1 #ifdef LTC_YARROW
2 struct yarrow_prng {
3 int cipher, hash;
4 unsigned char pool[MAXBLOCKSIZE];
5 symmetric_CTR ctr;
6 LTC_MUTEX_TYPE(prng_lock)
7 };
8 #endif
9
10 #ifdef LTC_RC4
11 struct rc4_prng {
12 int x, y;
13 unsigned char buf[256];
14 };
15 #endif
16
17 #ifdef LTC_FORTUNA
18 struct fortuna_prng {
19 hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */
20
21 symmetric_key skey;
22
23 unsigned char K[32], /* the current key */
24 IV[16]; /* IV for CTR mode */
25
26 unsigned long pool_idx, /* current pool we will add to */
27 pool0_len, /* length of 0'th pool */
28 wd;
29
30 ulong64 reset_cnt; /* number of times we have reset */
31 LTC_MUTEX_TYPE(prng_lock)
32 };
33 #endif
34
35 #ifdef LTC_SOBER128
36 struct sober128_prng {
37 ulong32 R[17], /* Working storage for the shift register */
38 initR[17], /* saved register contents */
39 konst, /* key dependent constant */
40 sbuf; /* partial word encryption buffer */
41
42 int nbuf, /* number of part-word stream bits buffered */
43 flag, /* first add_entropy call or not? */
44 set; /* did we call add_entropy to set key? */
45
46 };
47 #endif
48
49 typedef union Prng_state {
50 char dummy[1];
51 #ifdef LTC_YARROW
52 struct yarrow_prng yarrow;
53 #endif
54 #ifdef LTC_RC4
55 struct rc4_prng rc4;
56 #endif
57 #ifdef LTC_FORTUNA
58 struct fortuna_prng fortuna;
59 #endif
60 #ifdef LTC_SOBER128
61 struct sober128_prng sober128;
62 #endif
63 } prng_state;
64
65 /** PRNG descriptor */
66 extern struct ltc_prng_descriptor {
67 /** Name of the PRNG */
68 char *name;
69 /** size in bytes of exported state */
70 int export_size;
71 /** Start a PRNG state
72 @param prng [out] The state to initialize
73 @return CRYPT_OK if successful
74 */
75 int (*start)(prng_state *prng);
76 /** Add entropy to the PRNG
77 @param in The entropy
78 @param inlen Length of the entropy (octets)\
79 @param prng The PRNG state
80 @return CRYPT_OK if successful
81 */
82 int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng);
83 /** Ready a PRNG state to read from
84 @param prng The PRNG state to ready
85 @return CRYPT_OK if successful
86 */
87 int (*ready)(prng_state *prng);
88 /** Read from the PRNG
89 @param out [out] Where to store the data
90 @param outlen Length of data desired (octets)
91 @param prng The PRNG state to read from
92 @return Number of octets read
93 */
94 unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng);
95 /** Terminate a PRNG state
96 @param prng The PRNG state to terminate
97 @return CRYPT_OK if successful
98 */
99 int (*done)(prng_state *prng);
100 /** Export a PRNG state
101 @param out [out] The destination for the state
102 @param outlen [in/out] The max size and resulting size of the PRNG state
103 @param prng The PRNG to export
104 @return CRYPT_OK if successful
105 */
106 int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng);
107 /** Import a PRNG state
108 @param in The data to import
109 @param inlen The length of the data to import (octets)
110 @param prng The PRNG to initialize/import
111 @return CRYPT_OK if successful
112 */
113 int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng);
114 /** Self-test the PRNG
115 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
116 */
117 int (*test)(void);
118 } prng_descriptor[];
119
120 #ifdef LTC_YARROW
121 int yarrow_start(prng_state *prng);
122 int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
123 int yarrow_ready(prng_state *prng);
124 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng);
125 int yarrow_done(prng_state *prng);
126 int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
127 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
128 int yarrow_test(void);
129 extern const struct ltc_prng_descriptor yarrow_desc;
130 #endif
131
132 #ifdef LTC_FORTUNA
133 int fortuna_start(prng_state *prng);
134 int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
135 int fortuna_ready(prng_state *prng);
136 unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng);
137 int fortuna_done(prng_state *prng);
138 int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
139 int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
140 int fortuna_test(void);
141 extern const struct ltc_prng_descriptor fortuna_desc;
142 #endif
143
144 #ifdef LTC_RC4
145 int rc4_start(prng_state *prng);
146 int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
147 int rc4_ready(prng_state *prng);
148 unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng);
149 int rc4_done(prng_state *prng);
150 int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
151 int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
152 int rc4_test(void);
153 extern const struct ltc_prng_descriptor rc4_desc;
154 #endif
155
156 #ifdef LTC_SPRNG
157 int sprng_start(prng_state *prng);
158 int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
159 int sprng_ready(prng_state *prng);
160 unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng);
161 int sprng_done(prng_state *prng);
162 int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
163 int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
164 int sprng_test(void);
165 extern const struct ltc_prng_descriptor sprng_desc;
166 #endif
167
168 #ifdef LTC_SOBER128
169 int sober128_start(prng_state *prng);
170 int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
171 int sober128_ready(prng_state *prng);
172 unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng);
173 int sober128_done(prng_state *prng);
174 int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
175 int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
176 int sober128_test(void);
177 extern const struct ltc_prng_descriptor sober128_desc;
178 #endif
179
180 int find_prng(const char *name);
181 int register_prng(const struct ltc_prng_descriptor *prng);
182 int unregister_prng(const struct ltc_prng_descriptor *prng);
183 int prng_is_valid(int idx);
184 LTC_MUTEX_PROTO(ltc_prng_mutex)
185
186 /* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this
187 * might not work on all platforms as planned
188 */
189 unsigned long rng_get_bytes(unsigned char *out,
190 unsigned long outlen,
191 void (*callback)(void));
192
193 int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
194
195
196 /* $Source$ */
197 /* $Revision$ */
198 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_done.c
14 f9 Support, terminate the state
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /** Terminate the f9-MAC state
20 @param f9 f9 state to terminate
21 @param out [out] Destination for the MAC tag
22 @param outlen [in/out] Destination size and final tag size
23 Return CRYPT_OK on success
24 */
25 int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen)
26 {
27 int err, x;
28 LTC_ARGCHK(f9 != NULL);
29 LTC_ARGCHK(out != NULL);
30
31 /* check structure */
32 if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) {
33 return err;
34 }
35
36 if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) ||
37 (f9->buflen > f9->blocksize) || (f9->buflen < 0)) {
38 return CRYPT_INVALID_ARG;
39 }
40
41 if (f9->buflen != 0) {
42 /* encrypt */
43 cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key);
44 f9->buflen = 0;
45 for (x = 0; x < f9->blocksize; x++) {
46 f9->ACC[x] ^= f9->IV[x];
47 }
48 }
49
50 /* schedule modified key */
51 if ((err = cipher_descriptor[f9->cipher].setup(f9->akey, f9->keylen, 0, &f9->key)) != CRYPT_OK) {
52 return err;
53 }
54
55 /* encrypt the ACC */
56 cipher_descriptor[f9->cipher].ecb_encrypt(f9->ACC, f9->ACC, &f9->key);
57 cipher_descriptor[f9->cipher].done(&f9->key);
58
59 /* extract tag */
60 for (x = 0; x < f9->blocksize && (unsigned long)x < *outlen; x++) {
61 out[x] = f9->ACC[x];
62 }
63 *outlen = x;
64
65 #ifdef LTC_CLEAN_STACK
66 zeromem(f9, sizeof(*f9));
67 #endif
68 return CRYPT_OK;
69 }
70
71 #endif
72
73 /* $Source$ */
74 /* $Revision$ */
75 /* $Date$ */
76
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_file.c
14 f9 support, process a file, Tom St Denis
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /**
20 f9 a file
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param filename The name of the file you wish to f9
25 @param out [out] Where the authentication tag is to be stored
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int f9_file(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const char *filename,
32 unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35 return CRYPT_NOP;
36 #else
37 int err, x;
38 f9_state f9;
39 FILE *in;
40 unsigned char buf[512];
41
42 LTC_ARGCHK(key != NULL);
43 LTC_ARGCHK(filename != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 in = fopen(filename, "rb");
48 if (in == NULL) {
49 return CRYPT_FILE_NOTFOUND;
50 }
51
52 if ((err = f9_init(&f9, cipher, key, keylen)) != CRYPT_OK) {
53 fclose(in);
54 return err;
55 }
56
57 do {
58 x = fread(buf, 1, sizeof(buf), in);
59 if ((err = f9_process(&f9, buf, x)) != CRYPT_OK) {
60 fclose(in);
61 return err;
62 }
63 } while (x == sizeof(buf));
64 fclose(in);
65
66 if ((err = f9_done(&f9, out, outlen)) != CRYPT_OK) {
67 return err;
68 }
69
70 #ifdef LTC_CLEAN_STACK
71 zeromem(buf, sizeof(buf));
72 #endif
73
74 return CRYPT_OK;
75 #endif
76 }
77
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_init.c
14 F9 Support, start an F9 state
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /** Initialize F9-MAC state
20 @param f9 [out] f9 state to initialize
21 @param cipher Index of cipher to use
22 @param key [in] Secret key
23 @param keylen Length of secret key in octets
24 Return CRYPT_OK on success
25 */
26 int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen)
27 {
28 int x, err;
29
30 LTC_ARGCHK(f9 != NULL);
31 LTC_ARGCHK(key != NULL);
32
33 /* schedule the key */
34 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
35 return err;
36 }
37
38 #ifdef LTC_FAST
39 if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
40 return CRYPT_INVALID_ARG;
41 }
42 #endif
43
44 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &f9->key)) != CRYPT_OK) {
45 goto done;
46 }
47
48 /* make the second key */
49 for (x = 0; (unsigned)x < keylen; x++) {
50 f9->akey[x] = key[x] ^ 0xAA;
51 }
52
53 /* setup struct */
54 zeromem(f9->IV, cipher_descriptor[cipher].block_length);
55 zeromem(f9->ACC, cipher_descriptor[cipher].block_length);
56 f9->blocksize = cipher_descriptor[cipher].block_length;
57 f9->cipher = cipher;
58 f9->buflen = 0;
59 f9->keylen = keylen;
60 done:
61 return err;
62 }
63
64 #endif
65
66 /* $Source$ */
67 /* $Revision$ */
68 /* $Date$ */
69
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_process.c
14 f9 Support, Process a block through F9-MAC
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /** f9-MAC a block of memory
20 @param cipher Index of cipher to use
21 @param key [in] Secret key
22 @param keylen Length of key in octets
23 @param in [in] Message to MAC
24 @param inlen Length of input in octets
25 @param out [out] Destination for the MAC tag
26 @param outlen [in/out] Output size and final tag size
27 Return CRYPT_OK on success.
28 */
29 int f9_memory(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long *outlen)
33 {
34 f9_state *f9;
35 int err;
36
37 /* is the cipher valid? */
38 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* Use accelerator if found */
43 if (cipher_descriptor[cipher].f9_memory != NULL) {
44 return cipher_descriptor[cipher].f9_memory(key, keylen, in, inlen, out, outlen);
45 }
46
47 f9 = XCALLOC(1, sizeof(*f9));
48 if (f9 == NULL) {
49 return CRYPT_MEM;
50 }
51
52 if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) {
53 goto done;
54 }
55
56 if ((err = f9_process(f9, in, inlen)) != CRYPT_OK) {
57 goto done;
58 }
59
60 err = f9_done(f9, out, outlen);
61 done:
62 XFREE(f9);
63 return err;
64 }
65
66 #endif
67
68 /* $Source$ */
69 /* $Revision$ */
70 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file f9_memory_multi.c
15 f9 support, process multiple blocks of memory, Tom St Denis
16 */
17
18 #ifdef LTC_F9_MODE
19
20 /**
21 f9 multiple blocks of memory
22 @param cipher The index of the desired cipher
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] The destination of the authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag (octets)
27 @param in The data to send through f9
28 @param inlen The length of the data to send through f9 (octets)
29 @param ... tuples of (data,len) pairs to f9, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int f9_memory_multi(int cipher,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36 {
37 int err;
38 f9_state *f9;
39 va_list args;
40 const unsigned char *curptr;
41 unsigned long curlen;
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 /* allocate ram for f9 state */
49 f9 = XMALLOC(sizeof(f9_state));
50 if (f9 == NULL) {
51 return CRYPT_MEM;
52 }
53
54 /* f9 process the message */
55 if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58 va_start(args, inlen);
59 curptr = in;
60 curlen = inlen;
61 for (;;) {
62 /* process buf */
63 if ((err = f9_process(f9, curptr, curlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 /* step to next */
67 curptr = va_arg(args, const unsigned char*);
68 if (curptr == NULL) {
69 break;
70 }
71 curlen = va_arg(args, unsigned long);
72 }
73 if ((err = f9_done(f9, out, outlen)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76 LBL_ERR:
77 #ifdef LTC_CLEAN_STACK
78 zeromem(f9, sizeof(f9_state));
79 #endif
80 XFREE(f9);
81 va_end(args);
82 return err;
83 }
84
85 #endif
86
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file f9_process.c
14 f9 Support, process blocks with f9
15 */
16
17 #ifdef LTC_F9_MODE
18
19 /** Process data through f9-MAC
20 @param f9 The f9-MAC state
21 @param in Input data to process
22 @param inlen Length of input in octets
23 Return CRYPT_OK on success
24 */
25 int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen)
26 {
27 int err, x;
28
29 LTC_ARGCHK(f9 != NULL);
30 LTC_ARGCHK(in != NULL);
31
32 /* check structure */
33 if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) {
34 return err;
35 }
36
37 if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) ||
38 (f9->buflen > f9->blocksize) || (f9->buflen < 0)) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 #ifdef LTC_FAST
43 if (f9->buflen == 0) {
44 while (inlen >= (unsigned long)f9->blocksize) {
45 for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) {
46 *((LTC_FAST_TYPE*)&(f9->IV[x])) ^= *((LTC_FAST_TYPE*)&(in[x]));
47 }
48 cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key);
49 for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) {
50 *((LTC_FAST_TYPE*)&(f9->ACC[x])) ^= *((LTC_FAST_TYPE*)&(f9->IV[x]));
51 }
52 in += f9->blocksize;
53 inlen -= f9->blocksize;
54 }
55 }
56 #endif
57
58 while (inlen) {
59 if (f9->buflen == f9->blocksize) {
60 cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key);
61 for (x = 0; x < f9->blocksize; x++) {
62 f9->ACC[x] ^= f9->IV[x];
63 }
64 f9->buflen = 0;
65 }
66 f9->IV[f9->buflen++] ^= *in++;
67 --inlen;
68 }
69 return CRYPT_OK;
70 }
71
72 #endif
73
74 /* $Source$ */
75 /* $Revision$ */
76 /* $Date$ */
77
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_done.c
14 LTC_HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
20
21 /**
22 Terminate an LTC_HMAC session
23 @param hmac The LTC_HMAC state
24 @param out [out] The destination of the LTC_HMAC authentication tag
25 @param outlen [in/out] The max size and resulting size of the LTC_HMAC authentication tag
26 @return CRYPT_OK if successful
27 */
28 int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
29 {
30 unsigned char *buf, *isha;
31 unsigned long hashsize, i;
32 int hash, err;
33
34 LTC_ARGCHK(hmac != NULL);
35 LTC_ARGCHK(out != NULL);
36
37 /* test hash */
38 hash = hmac->hash;
39 if((err = hash_is_valid(hash)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* get the hash message digest size */
44 hashsize = hash_descriptor[hash].hashsize;
45
46 /* allocate buffers */
47 buf = XMALLOC(LTC_HMAC_BLOCKSIZE);
48 isha = XMALLOC(hashsize);
49 if (buf == NULL || isha == NULL) {
50 if (buf != NULL) {
51 XFREE(buf);
52 }
53 if (isha != NULL) {
54 XFREE(isha);
55 }
56 return CRYPT_MEM;
57 }
58
59 /* Get the hash of the first LTC_HMAC vector plus the data */
60 if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
61 goto LBL_ERR;
62 }
63
64 /* Create the second LTC_HMAC vector vector for step (3) */
65 for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) {
66 buf[i] = hmac->key[i] ^ 0x5C;
67 }
68
69 /* Now calculate the "outer" hash for step (5), (6), and (7) */
70 if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
71 goto LBL_ERR;
72 }
73 if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76 if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79 if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) {
80 goto LBL_ERR;
81 }
82
83 /* copy to output */
84 for (i = 0; i < hashsize && i < *outlen; i++) {
85 out[i] = buf[i];
86 }
87 *outlen = i;
88
89 err = CRYPT_OK;
90 LBL_ERR:
91 XFREE(hmac->key);
92 #ifdef LTC_CLEAN_STACK
93 zeromem(isha, hashsize);
94 zeromem(buf, hashsize);
95 zeromem(hmac, sizeof(*hmac));
96 #endif
97
98 XFREE(isha);
99 XFREE(buf);
100
101 return err;
102 }
103
104 #endif
105
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_file.c
14 LTC_HMAC support, process a file, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 /**
20 LTC_HMAC a file
21 @param hash The index of the hash you wish to use
22 @param fname The name of the file you wish to LTC_HMAC
23 @param key The secret key
24 @param keylen The length of the secret key
25 @param out [out] The LTC_HMAC authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int hmac_file(int hash, const char *fname,
30 const unsigned char *key, unsigned long keylen,
31 unsigned char *out, unsigned long *outlen)
32 {
33 #ifdef LTC_NO_FILE
34 return CRYPT_NOP;
35 #else
36 hmac_state hmac;
37 FILE *in;
38 unsigned char buf[512];
39 size_t x;
40 int err;
41
42 LTC_ARGCHK(fname != NULL);
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 if((err = hash_is_valid(hash)) != CRYPT_OK) {
48 return err;
49 }
50
51 if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
52 return err;
53 }
54
55 in = fopen(fname, "rb");
56 if (in == NULL) {
57 return CRYPT_FILE_NOTFOUND;
58 }
59
60 /* process the file contents */
61 do {
62 x = fread(buf, 1, sizeof(buf), in);
63 if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) {
64 /* we don't trap this error since we're already returning an error! */
65 fclose(in);
66 return err;
67 }
68 } while (x == sizeof(buf));
69
70 if (fclose(in) != 0) {
71 return CRYPT_ERROR;
72 }
73
74 /* get final hmac */
75 if ((err = hmac_done(&hmac, out, outlen)) != CRYPT_OK) {
76 return err;
77 }
78
79 #ifdef LTC_CLEAN_STACK
80 /* clear memory */
81 zeromem(buf, sizeof(buf));
82 #endif
83 return CRYPT_OK;
84 #endif
85 }
86
87 #endif
88
89
90 /* $Source$ */
91 /* $Revision$ */
92 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_init.c
14 LTC_HMAC support, initialize state, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
20
21 /**
22 Initialize an LTC_HMAC context.
23 @param hmac The LTC_HMAC state
24 @param hash The index of the hash you want to use
25 @param key The secret key
26 @param keylen The length of the secret key (octets)
27 @return CRYPT_OK if successful
28 */
29 int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen)
30 {
31 unsigned char *buf;
32 unsigned long hashsize;
33 unsigned long i, z;
34 int err;
35
36 LTC_ARGCHK(hmac != NULL);
37 LTC_ARGCHK(key != NULL);
38
39 /* valid hash? */
40 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
41 return err;
42 }
43 hmac->hash = hash;
44 hashsize = hash_descriptor[hash].hashsize;
45
46 /* valid key length? */
47 if (keylen == 0) {
48 return CRYPT_INVALID_KEYSIZE;
49 }
50
51 /* allocate ram for buf */
52 buf = XMALLOC(LTC_HMAC_BLOCKSIZE);
53 if (buf == NULL) {
54 return CRYPT_MEM;
55 }
56
57 /* allocate memory for key */
58 hmac->key = XMALLOC(LTC_HMAC_BLOCKSIZE);
59 if (hmac->key == NULL) {
60 XFREE(buf);
61 return CRYPT_MEM;
62 }
63
64 /* (1) make sure we have a large enough key */
65 if(keylen > LTC_HMAC_BLOCKSIZE) {
66 z = LTC_HMAC_BLOCKSIZE;
67 if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) {
68 goto LBL_ERR;
69 }
70 if(hashsize < LTC_HMAC_BLOCKSIZE) {
71 zeromem((hmac->key) + hashsize, (size_t)(LTC_HMAC_BLOCKSIZE - hashsize));
72 }
73 keylen = hashsize;
74 } else {
75 XMEMCPY(hmac->key, key, (size_t)keylen);
76 if(keylen < LTC_HMAC_BLOCKSIZE) {
77 zeromem((hmac->key) + keylen, (size_t)(LTC_HMAC_BLOCKSIZE - keylen));
78 }
79 }
80
81 /* Create the initial vector for step (3) */
82 for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) {
83 buf[i] = hmac->key[i] ^ 0x36;
84 }
85
86 /* Pre-pend that to the hash data */
87 if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
88 goto LBL_ERR;
89 }
90
91 if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) {
92 goto LBL_ERR;
93 }
94 goto done;
95 LBL_ERR:
96 /* free the key since we failed */
97 XFREE(hmac->key);
98 done:
99 #ifdef LTC_CLEAN_STACK
100 zeromem(buf, LTC_HMAC_BLOCKSIZE);
101 #endif
102
103 XFREE(buf);
104 return err;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_memory.c
14 LTC_HMAC support, process a block of memory, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 /**
20 LTC_HMAC a block of memory to produce the authentication tag
21 @param hash The index of the hash to use
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param in The data to LTC_HMAC
25 @param inlen The length of the data to LTC_HMAC (octets)
26 @param out [out] Destination of the authentication tag
27 @param outlen [in/out] Max size and resulting size of authentication tag
28 @return CRYPT_OK if successful
29 */
30 int hmac_memory(int hash,
31 const unsigned char *key, unsigned long keylen,
32 const unsigned char *in, unsigned long inlen,
33 unsigned char *out, unsigned long *outlen)
34 {
35 hmac_state *hmac;
36 int err;
37
38 LTC_ARGCHK(key != NULL);
39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL);
42
43 /* make sure hash descriptor is valid */
44 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* is there a descriptor? */
49 if (hash_descriptor[hash].hmac_block != NULL) {
50 return hash_descriptor[hash].hmac_block(key, keylen, in, inlen, out, outlen);
51 }
52
53 /* nope, so call the hmac functions */
54 /* allocate ram for hmac state */
55 hmac = XMALLOC(sizeof(hmac_state));
56 if (hmac == NULL) {
57 return CRYPT_MEM;
58 }
59
60 if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) {
61 goto LBL_ERR;
62 }
63
64 if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) {
65 goto LBL_ERR;
66 }
67
68 if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) {
69 goto LBL_ERR;
70 }
71
72 err = CRYPT_OK;
73 LBL_ERR:
74 #ifdef LTC_CLEAN_STACK
75 zeromem(hmac, sizeof(hmac_state));
76 #endif
77
78 XFREE(hmac);
79 return err;
80 }
81
82 #endif
83
84
85 /* $Source$ */
86 /* $Revision$ */
87 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file hmac_memory_multi.c
15 LTC_HMAC support, process multiple blocks of memory, Tom St Denis/Dobes Vandermeer
16 */
17
18 #ifdef LTC_HMAC
19
20 /**
21 LTC_HMAC multiple blocks of memory to produce the authentication tag
22 @param hash The index of the hash to use
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] Destination of the authentication tag
26 @param outlen [in/out] Max size and resulting size of authentication tag
27 @param in The data to LTC_HMAC
28 @param inlen The length of the data to LTC_HMAC (octets)
29 @param ... tuples of (data,len) pairs to LTC_HMAC, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int hmac_memory_multi(int hash,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36
37 {
38 hmac_state *hmac;
39 int err;
40 va_list args;
41 const unsigned char *curptr;
42 unsigned long curlen;
43
44 LTC_ARGCHK(key != NULL);
45 LTC_ARGCHK(in != NULL);
46 LTC_ARGCHK(out != NULL);
47 LTC_ARGCHK(outlen != NULL);
48
49 /* allocate ram for hmac state */
50 hmac = XMALLOC(sizeof(hmac_state));
51 if (hmac == NULL) {
52 return CRYPT_MEM;
53 }
54
55 if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58
59 va_start(args, inlen);
60 curptr = in;
61 curlen = inlen;
62 for (;;) {
63 /* process buf */
64 if ((err = hmac_process(hmac, curptr, curlen)) != CRYPT_OK) {
65 goto LBL_ERR;
66 }
67 /* step to next */
68 curptr = va_arg(args, const unsigned char*);
69 if (curptr == NULL) {
70 break;
71 }
72 curlen = va_arg(args, unsigned long);
73 }
74 if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77 LBL_ERR:
78 #ifdef LTC_CLEAN_STACK
79 zeromem(hmac, sizeof(hmac_state));
80 #endif
81 XFREE(hmac);
82 va_end(args);
83 return err;
84 }
85
86 #endif
87
88
89 /* $Source$ */
90 /* $Revision$ */
91 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file hmac_process.c
14 LTC_HMAC support, process data, Tom St Denis/Dobes Vandermeer
15 */
16
17 #ifdef LTC_HMAC
18
19 /**
20 Process data through LTC_HMAC
21 @param hmac The hmac state
22 @param in The data to send through LTC_HMAC
23 @param inlen The length of the data to LTC_HMAC (octets)
24 @return CRYPT_OK if successful
25 */
26 int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen)
27 {
28 int err;
29 LTC_ARGCHK(hmac != NULL);
30 LTC_ARGCHK(in != NULL);
31 if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) {
32 return err;
33 }
34 return hash_descriptor[hmac->hash].process(&hmac->md, in, inlen);
35 }
36
37 #endif
38
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_done.c
14 LTC_OMAC1 support, terminate a stream, Tom St Denis
15 */
16
17 #ifdef LTC_OMAC
18
19 /**
20 Terminate an LTC_OMAC stream
21 @param omac The LTC_OMAC state
22 @param out [out] Destination for the authentication tag
23 @param outlen [in/out] The max size and resulting size of the authentication tag
24 @return CRYPT_OK if successful
25 */
26 int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen)
27 {
28 int err, mode;
29 unsigned x;
30
31 LTC_ARGCHK(omac != NULL);
32 LTC_ARGCHK(out != NULL);
33 LTC_ARGCHK(outlen != NULL);
34 if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) {
35 return err;
36 }
37
38 if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) ||
39 (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 /* figure out mode */
44 if (omac->buflen != omac->blklen) {
45 /* add the 0x80 byte */
46 omac->block[omac->buflen++] = 0x80;
47
48 /* pad with 0x00 */
49 while (omac->buflen < omac->blklen) {
50 omac->block[omac->buflen++] = 0x00;
51 }
52 mode = 1;
53 } else {
54 mode = 0;
55 }
56
57 /* now xor prev + Lu[mode] */
58 for (x = 0; x < (unsigned)omac->blklen; x++) {
59 omac->block[x] ^= omac->prev[x] ^ omac->Lu[mode][x];
60 }
61
62 /* encrypt it */
63 if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) {
64 return err;
65 }
66 cipher_descriptor[omac->cipher_idx].done(&omac->key);
67
68 /* output it */
69 for (x = 0; x < (unsigned)omac->blklen && x < *outlen; x++) {
70 out[x] = omac->block[x];
71 }
72 *outlen = x;
73
74 #ifdef LTC_CLEAN_STACK
75 zeromem(omac, sizeof(*omac));
76 #endif
77 return CRYPT_OK;
78 }
79
80 #endif
81
82
83 /* $Source$ */
84 /* $Revision$ */
85 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_file.c
14 LTC_OMAC1 support, process a file, Tom St Denis
15 */
16
17 #ifdef LTC_OMAC
18
19 /**
20 LTC_OMAC a file
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param filename The name of the file you wish to LTC_OMAC
25 @param out [out] Where the authentication tag is to be stored
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int omac_file(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const char *filename,
32 unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35 return CRYPT_NOP;
36 #else
37 int err, x;
38 omac_state omac;
39 FILE *in;
40 unsigned char buf[512];
41
42 LTC_ARGCHK(key != NULL);
43 LTC_ARGCHK(filename != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 in = fopen(filename, "rb");
48 if (in == NULL) {
49 return CRYPT_FILE_NOTFOUND;
50 }
51
52 if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) {
53 fclose(in);
54 return err;
55 }
56
57 do {
58 x = fread(buf, 1, sizeof(buf), in);
59 if ((err = omac_process(&omac, buf, x)) != CRYPT_OK) {
60 fclose(in);
61 return err;
62 }
63 } while (x == sizeof(buf));
64 fclose(in);
65
66 if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) {
67 return err;
68 }
69
70 #ifdef LTC_CLEAN_STACK
71 zeromem(buf, sizeof(buf));
72 #endif
73
74 return CRYPT_OK;
75 #endif
76 }
77
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_init.c
14 LTC_OMAC1 support, initialize state, by Tom St Denis
15 */
16
17
18 #ifdef LTC_OMAC
19
20 /**
21 Initialize an LTC_OMAC state
22 @param omac The LTC_OMAC state to initialize
23 @param cipher The index of the desired cipher
24 @param key The secret key
25 @param keylen The length of the secret key (octets)
26 @return CRYPT_OK if successful
27 */
28 int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen)
29 {
30 int err, x, y, mask, msb, len;
31
32 LTC_ARGCHK(omac != NULL);
33 LTC_ARGCHK(key != NULL);
34
35 /* schedule the key */
36 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 #ifdef LTC_FAST
41 if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
42 return CRYPT_INVALID_ARG;
43 }
44 #endif
45
46 /* now setup the system */
47 switch (cipher_descriptor[cipher].block_length) {
48 case 8: mask = 0x1B;
49 len = 8;
50 break;
51 case 16: mask = 0x87;
52 len = 16;
53 break;
54 default: return CRYPT_INVALID_ARG;
55 }
56
57 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) {
58 return err;
59 }
60
61 /* ok now we need Lu and Lu^2 [calc one from the other] */
62
63 /* first calc L which is Ek(0) */
64 zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
65 if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) {
66 return err;
67 }
68
69 /* now do the mults, whoopy! */
70 for (x = 0; x < 2; x++) {
71 /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */
72 msb = omac->Lu[x][0] >> 7;
73
74 /* shift left */
75 for (y = 0; y < (len - 1); y++) {
76 omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255;
77 }
78 omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255;
79
80 /* copy up as require */
81 if (x == 0) {
82 XMEMCPY(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0]));
83 }
84 }
85
86 /* setup state */
87 omac->cipher_idx = cipher;
88 omac->buflen = 0;
89 omac->blklen = len;
90 zeromem(omac->prev, sizeof(omac->prev));
91 zeromem(omac->block, sizeof(omac->block));
92
93 return CRYPT_OK;
94 }
95
96 #endif
97
98 /* $Source$ */
99 /* $Revision$ */
100 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_memory.c
14 LTC_OMAC1 support, process a block of memory, Tom St Denis
15 */
16
17 #ifdef LTC_OMAC
18
19 /**
20 LTC_OMAC a block of memory
21 @param cipher The index of the desired cipher
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param in The data to send through LTC_OMAC
25 @param inlen The length of the data to send through LTC_OMAC (octets)
26 @param out [out] The destination of the authentication tag
27 @param outlen [in/out] The max size and resulting size of the authentication tag (octets)
28 @return CRYPT_OK if successful
29 */
30 int omac_memory(int cipher,
31 const unsigned char *key, unsigned long keylen,
32 const unsigned char *in, unsigned long inlen,
33 unsigned char *out, unsigned long *outlen)
34 {
35 int err;
36 omac_state *omac;
37
38 LTC_ARGCHK(key != NULL);
39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL);
42
43 /* is the cipher valid? */
44 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* Use accelerator if found */
49 if (cipher_descriptor[cipher].omac_memory != NULL) {
50 return cipher_descriptor[cipher].omac_memory(key, keylen, in, inlen, out, outlen);
51 }
52
53 /* allocate ram for omac state */
54 omac = XMALLOC(sizeof(omac_state));
55 if (omac == NULL) {
56 return CRYPT_MEM;
57 }
58
59 /* omac process the message */
60 if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
61 goto LBL_ERR;
62 }
63 if ((err = omac_process(omac, in, inlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) {
67 goto LBL_ERR;
68 }
69
70 err = CRYPT_OK;
71 LBL_ERR:
72 #ifdef LTC_CLEAN_STACK
73 zeromem(omac, sizeof(omac_state));
74 #endif
75
76 XFREE(omac);
77 return err;
78 }
79
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file omac_memory_multi.c
15 LTC_OMAC1 support, process multiple blocks of memory, Tom St Denis
16 */
17
18 #ifdef LTC_OMAC
19
20 /**
21 LTC_OMAC multiple blocks of memory
22 @param cipher The index of the desired cipher
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] The destination of the authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag (octets)
27 @param in The data to send through LTC_OMAC
28 @param inlen The length of the data to send through LTC_OMAC (octets)
29 @param ... tuples of (data,len) pairs to LTC_OMAC, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int omac_memory_multi(int cipher,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36 {
37 int err;
38 omac_state *omac;
39 va_list args;
40 const unsigned char *curptr;
41 unsigned long curlen;
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 /* allocate ram for omac state */
49 omac = XMALLOC(sizeof(omac_state));
50 if (omac == NULL) {
51 return CRYPT_MEM;
52 }
53
54 /* omac process the message */
55 if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58 va_start(args, inlen);
59 curptr = in;
60 curlen = inlen;
61 for (;;) {
62 /* process buf */
63 if ((err = omac_process(omac, curptr, curlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 /* step to next */
67 curptr = va_arg(args, const unsigned char*);
68 if (curptr == NULL) {
69 break;
70 }
71 curlen = va_arg(args, unsigned long);
72 }
73 if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76 LBL_ERR:
77 #ifdef LTC_CLEAN_STACK
78 zeromem(omac, sizeof(omac_state));
79 #endif
80 XFREE(omac);
81 va_end(args);
82 return err;
83 }
84
85 #endif
86
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file omac_process.c
14 LTC_OMAC1 support, process data, Tom St Denis
15 */
16
17
18 #ifdef LTC_OMAC
19
20 /**
21 Process data through LTC_OMAC
22 @param omac The LTC_OMAC state
23 @param in The input data to send through LTC_OMAC
24 @param inlen The length of the input (octets)
25 @return CRYPT_OK if successful
26 */
27 int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
28 {
29 unsigned long n, x;
30 int err;
31
32 LTC_ARGCHK(omac != NULL);
33 LTC_ARGCHK(in != NULL);
34 if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) {
35 return err;
36 }
37
38 if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) ||
39 (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 #ifdef LTC_FAST
44 {
45 unsigned long blklen;
46
47 blklen = cipher_descriptor[omac->cipher_idx].block_length;
48 if (omac->buflen == 0 && inlen > blklen) {
49 unsigned long y;
50 for (x = 0; x < (inlen - blklen); x += blklen) {
51 for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) {
52 *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y]));
53 }
54 in += blklen;
55 if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) {
56 return err;
57 }
58 }
59 inlen -= x;
60 }
61 }
62 #endif
63
64 while (inlen != 0) {
65 /* ok if the block is full we xor in prev, encrypt and replace prev */
66 if (omac->buflen == omac->blklen) {
67 for (x = 0; x < (unsigned long)omac->blklen; x++) {
68 omac->block[x] ^= omac->prev[x];
69 }
70 if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) {
71 return err;
72 }
73 omac->buflen = 0;
74 }
75
76 /* add bytes */
77 n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen));
78 XMEMCPY(omac->block + omac->buflen, in, n);
79 omac->buflen += n;
80 inlen -= n;
81 in += n;
82 }
83
84 return CRYPT_OK;
85 }
86
87 #endif
88
89
90 /* $Source$ */
91 /* $Revision$ */
92 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pelican.c
14 Pelican MAC, initialize state, by Tom St Denis
15 */
16
17 #ifdef LTC_PELICAN
18
19 #define ENCRYPT_ONLY
20 #define PELI_TAB
21 #include "../../ciphers/aes/aes_tab.c.inc"
22
23 /**
24 Initialize a Pelican state
25 @param pelmac The Pelican state to initialize
26 @param key The secret key
27 @param keylen The length of the secret key (octets)
28 @return CRYPT_OK if successful
29 */
30 int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen)
31 {
32 int err;
33
34 LTC_ARGCHK(pelmac != NULL);
35 LTC_ARGCHK(key != NULL);
36
37 #ifdef LTC_FAST
38 if (16 % sizeof(LTC_FAST_TYPE)) {
39 return CRYPT_INVALID_ARG;
40 }
41 #endif
42
43 if ((err = aes_setup(key, keylen, 0, &pelmac->K)) != CRYPT_OK) {
44 return err;
45 }
46
47 zeromem(pelmac->state, 16);
48 aes_ecb_encrypt(pelmac->state, pelmac->state, &pelmac->K);
49 pelmac->buflen = 0;
50
51 return CRYPT_OK;
52 }
53
54 static void four_rounds(pelican_state *pelmac)
55 {
56 ulong32 s0, s1, s2, s3, t0, t1, t2, t3;
57 int r;
58
59 LOAD32H(s0, pelmac->state );
60 LOAD32H(s1, pelmac->state + 4);
61 LOAD32H(s2, pelmac->state + 8);
62 LOAD32H(s3, pelmac->state + 12);
63 for (r = 0; r < 4; r++) {
64 t0 =
65 Te0(byte(s0, 3)) ^
66 Te1(byte(s1, 2)) ^
67 Te2(byte(s2, 1)) ^
68 Te3(byte(s3, 0));
69 t1 =
70 Te0(byte(s1, 3)) ^
71 Te1(byte(s2, 2)) ^
72 Te2(byte(s3, 1)) ^
73 Te3(byte(s0, 0));
74 t2 =
75 Te0(byte(s2, 3)) ^
76 Te1(byte(s3, 2)) ^
77 Te2(byte(s0, 1)) ^
78 Te3(byte(s1, 0));
79 t3 =
80 Te0(byte(s3, 3)) ^
81 Te1(byte(s0, 2)) ^
82 Te2(byte(s1, 1)) ^
83 Te3(byte(s2, 0));
84 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
85 }
86 STORE32H(s0, pelmac->state );
87 STORE32H(s1, pelmac->state + 4);
88 STORE32H(s2, pelmac->state + 8);
89 STORE32H(s3, pelmac->state + 12);
90 }
91
92 /**
93 Process a block of text through Pelican
94 @param pelmac The Pelican MAC state
95 @param in The input
96 @param inlen The length input (octets)
97 @return CRYPT_OK on success
98 */
99 int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen)
100 {
101
102 LTC_ARGCHK(pelmac != NULL);
103 LTC_ARGCHK(in != NULL);
104
105 /* check range */
106 if (pelmac->buflen < 0 || pelmac->buflen > 15) {
107 return CRYPT_INVALID_ARG;
108 }
109
110 #ifdef LTC_FAST
111 if (pelmac->buflen == 0) {
112 while (inlen & ~15) {
113 int x;
114 for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
115 *((LTC_FAST_TYPE*)((unsigned char *)pelmac->state + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)in + x));
116 }
117 four_rounds(pelmac);
118 in += 16;
119 inlen -= 16;
120 }
121 }
122 #endif
123
124 while (inlen--) {
125 pelmac->state[pelmac->buflen++] ^= *in++;
126 if (pelmac->buflen == 16) {
127 four_rounds(pelmac);
128 pelmac->buflen = 0;
129 }
130 }
131 return CRYPT_OK;
132 }
133
134 /**
135 Terminate Pelican MAC
136 @param pelmac The Pelican MAC state
137 @param out [out] The TAG
138 @return CRYPT_OK on sucess
139 */
140 int pelican_done(pelican_state *pelmac, unsigned char *out)
141 {
142 LTC_ARGCHK(pelmac != NULL);
143 LTC_ARGCHK(out != NULL);
144
145 /* check range */
146 if (pelmac->buflen < 0 || pelmac->buflen > 16) {
147 return CRYPT_INVALID_ARG;
148 }
149
150 if (pelmac->buflen == 16) {
151 four_rounds(pelmac);
152 pelmac->buflen = 0;
153 }
154 pelmac->state[pelmac->buflen++] ^= 0x80;
155 aes_ecb_encrypt(pelmac->state, out, &pelmac->K);
156 aes_done(&pelmac->K);
157 return CRYPT_OK;
158 }
159
160 #endif
161
162 /* $Source$ */
163 /* $Revision$ */
164 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pelican_memory.c
14 Pelican MAC, MAC a block of memory, by Tom St Denis
15 */
16
17 #ifdef LTC_PELICAN
18
19 /**
20 Pelican block of memory
21 @param key The key for the MAC
22 @param keylen The length of the key (octets)
23 @param in The input to MAC
24 @param inlen The length of the input (octets)
25 @param out [out] The output TAG
26 @return CRYPT_OK on success
27 */
28 int pelican_memory(const unsigned char *key, unsigned long keylen,
29 const unsigned char *in, unsigned long inlen,
30 unsigned char *out)
31 {
32 pelican_state *pel;
33 int err;
34
35 pel = XMALLOC(sizeof(*pel));
36 if (pel == NULL) {
37 return CRYPT_MEM;
38 }
39
40 if ((err = pelican_init(pel, key, keylen)) != CRYPT_OK) {
41 XFREE(pel);
42 return err;
43 }
44 if ((err = pelican_process(pel, in ,inlen)) != CRYPT_OK) {
45 XFREE(pel);
46 return err;
47 }
48 err = pelican_done(pel, out);
49 XFREE(pel);
50 return err;
51 }
52
53
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_done.c
14 PMAC implementation, terminate a session, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen)
20 {
21 int err, x;
22
23 LTC_ARGCHK(state != NULL);
24 LTC_ARGCHK(out != NULL);
25 if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) {
26 return err;
27 }
28
29 if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) ||
30 (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) {
31 return CRYPT_INVALID_ARG;
32 }
33
34
35 /* handle padding. If multiple xor in L/x */
36
37 if (state->buflen == state->block_len) {
38 /* xor Lr against the checksum */
39 for (x = 0; x < state->block_len; x++) {
40 state->checksum[x] ^= state->block[x] ^ state->Lr[x];
41 }
42 } else {
43 /* otherwise xor message bytes then the 0x80 byte */
44 for (x = 0; x < state->buflen; x++) {
45 state->checksum[x] ^= state->block[x];
46 }
47 state->checksum[x] ^= 0x80;
48 }
49
50 /* encrypt it */
51 if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) {
52 return err;
53 }
54 cipher_descriptor[state->cipher_idx].done(&state->key);
55
56 /* store it */
57 for (x = 0; x < state->block_len && x < (int)*outlen; x++) {
58 out[x] = state->checksum[x];
59 }
60 *outlen = x;
61
62 #ifdef LTC_CLEAN_STACK
63 zeromem(state, sizeof(*state));
64 #endif
65 return CRYPT_OK;
66 }
67
68 #endif
69
70
71 /* $Source$ */
72 /* $Revision$ */
73 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_file.c
14 PMAC implementation, process a file, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 /**
20 PMAC a file
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param filename The name of the file to send through PMAC
25 @param out [out] Destination for the authentication tag
26 @param outlen [in/out] Max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int pmac_file(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const char *filename,
32 unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35 return CRYPT_NOP;
36 #else
37 int err, x;
38 pmac_state pmac;
39 FILE *in;
40 unsigned char buf[512];
41
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(filename != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 in = fopen(filename, "rb");
49 if (in == NULL) {
50 return CRYPT_FILE_NOTFOUND;
51 }
52
53 if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) {
54 fclose(in);
55 return err;
56 }
57
58 do {
59 x = fread(buf, 1, sizeof(buf), in);
60 if ((err = pmac_process(&pmac, buf, x)) != CRYPT_OK) {
61 fclose(in);
62 return err;
63 }
64 } while (x == sizeof(buf));
65 fclose(in);
66
67 if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) {
68 return err;
69 }
70
71 #ifdef LTC_CLEAN_STACK
72 zeromem(buf, sizeof(buf));
73 #endif
74
75 return CRYPT_OK;
76 #endif
77 }
78
79 #endif
80
81 /* $Source$ */
82 /* $Revision$ */
83 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_init.c
14 PMAC implementation, initialize state, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 static const struct {
20 int len;
21 unsigned char poly_div[MAXBLOCKSIZE],
22 poly_mul[MAXBLOCKSIZE];
23 } polys[] = {
24 {
25 8,
26 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
27 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
28 }, {
29 16,
30 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
32 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
34 }
35 };
36
37 /**
38 Initialize a PMAC state
39 @param pmac The PMAC state to initialize
40 @param cipher The index of the desired cipher
41 @param key The secret key
42 @param keylen The length of the secret key (octets)
43 @return CRYPT_OK if successful
44 */
45 int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen)
46 {
47 int poly, x, y, m, err;
48 unsigned char *L;
49
50 LTC_ARGCHK(pmac != NULL);
51 LTC_ARGCHK(key != NULL);
52
53 /* valid cipher? */
54 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
55 return err;
56 }
57
58 /* determine which polys to use */
59 pmac->block_len = cipher_descriptor[cipher].block_length;
60 for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) {
61 if (polys[poly].len == pmac->block_len) {
62 break;
63 }
64 }
65 if (polys[poly].len != pmac->block_len) {
66 return CRYPT_INVALID_ARG;
67 }
68
69 #ifdef LTC_FAST
70 if (pmac->block_len % sizeof(LTC_FAST_TYPE)) {
71 return CRYPT_INVALID_ARG;
72 }
73 #endif
74
75
76 /* schedule the key */
77 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) {
78 return err;
79 }
80
81 /* allocate L */
82 L = XMALLOC(pmac->block_len);
83 if (L == NULL) {
84 return CRYPT_MEM;
85 }
86
87 /* find L = E[0] */
88 zeromem(L, pmac->block_len);
89 if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) {
90 goto error;
91 }
92
93 /* find Ls[i] = L << i for i == 0..31 */
94 XMEMCPY(pmac->Ls[0], L, pmac->block_len);
95 for (x = 1; x < 32; x++) {
96 m = pmac->Ls[x-1][0] >> 7;
97 for (y = 0; y < pmac->block_len-1; y++) {
98 pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255;
99 }
100 pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255;
101
102 if (m == 1) {
103 for (y = 0; y < pmac->block_len; y++) {
104 pmac->Ls[x][y] ^= polys[poly].poly_mul[y];
105 }
106 }
107 }
108
109 /* find Lr = L / x */
110 m = L[pmac->block_len-1] & 1;
111
112 /* shift right */
113 for (x = pmac->block_len - 1; x > 0; x--) {
114 pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255;
115 }
116 pmac->Lr[0] = L[0] >> 1;
117
118 if (m == 1) {
119 for (x = 0; x < pmac->block_len; x++) {
120 pmac->Lr[x] ^= polys[poly].poly_div[x];
121 }
122 }
123
124 /* zero buffer, counters, etc... */
125 pmac->block_index = 1;
126 pmac->cipher_idx = cipher;
127 pmac->buflen = 0;
128 zeromem(pmac->block, sizeof(pmac->block));
129 zeromem(pmac->Li, sizeof(pmac->Li));
130 zeromem(pmac->checksum, sizeof(pmac->checksum));
131 err = CRYPT_OK;
132 error:
133 #ifdef LTC_CLEAN_STACK
134 zeromem(L, pmac->block_len);
135 #endif
136
137 XFREE(L);
138
139 return err;
140 }
141
142 #endif
143
144 /* $Source$ */
145 /* $Revision$ */
146 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_memory.c
14 PMAC implementation, process a block of memory, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 /**
20 PMAC a block of memory
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param in The data you wish to send through PMAC
25 @param inlen The length of data you wish to send through PMAC (octets)
26 @param out [out] Destination for the authentication tag
27 @param outlen [in/out] The max size and resulting size of the authentication tag
28 @return CRYPT_OK if successful
29 */
30 int pmac_memory(int cipher,
31 const unsigned char *key, unsigned long keylen,
32 const unsigned char *in, unsigned long inlen,
33 unsigned char *out, unsigned long *outlen)
34 {
35 int err;
36 pmac_state *pmac;
37
38 LTC_ARGCHK(key != NULL);
39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL);
42
43 /* allocate ram for pmac state */
44 pmac = XMALLOC(sizeof(pmac_state));
45 if (pmac == NULL) {
46 return CRYPT_MEM;
47 }
48
49 if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) {
50 goto LBL_ERR;
51 }
52 if ((err = pmac_process(pmac, in, inlen)) != CRYPT_OK) {
53 goto LBL_ERR;
54 }
55 if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58
59 err = CRYPT_OK;
60 LBL_ERR:
61 #ifdef LTC_CLEAN_STACK
62 zeromem(pmac, sizeof(pmac_state));
63 #endif
64
65 XFREE(pmac);
66 return err;
67 }
68
69 #endif
70
71 /* $Source$ */
72 /* $Revision$ */
73 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file pmac_memory_multi.c
15 PMAC implementation, process multiple blocks of memory, by Tom St Denis
16 */
17
18 #ifdef LTC_PMAC
19
20 /**
21 PMAC multiple blocks of memory
22 @param cipher The index of the cipher desired
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] Destination for the authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @param in The data you wish to send through PMAC
28 @param inlen The length of data you wish to send through PMAC (octets)
29 @param ... tuples of (data,len) pairs to PMAC, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int pmac_memory_multi(int cipher,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36 {
37 int err;
38 pmac_state *pmac;
39 va_list args;
40 const unsigned char *curptr;
41 unsigned long curlen;
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 /* allocate ram for pmac state */
49 pmac = XMALLOC(sizeof(pmac_state));
50 if (pmac == NULL) {
51 return CRYPT_MEM;
52 }
53
54 if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57 va_start(args, inlen);
58 curptr = in;
59 curlen = inlen;
60 for (;;) {
61 /* process buf */
62 if ((err = pmac_process(pmac, curptr, curlen)) != CRYPT_OK) {
63 goto LBL_ERR;
64 }
65 /* step to next */
66 curptr = va_arg(args, const unsigned char*);
67 if (curptr == NULL) {
68 break;
69 }
70 curlen = va_arg(args, unsigned long);
71 }
72 if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) {
73 goto LBL_ERR;
74 }
75 LBL_ERR:
76 #ifdef LTC_CLEAN_STACK
77 zeromem(pmac, sizeof(pmac_state));
78 #endif
79 XFREE(pmac);
80 va_end(args);
81 return err;
82 }
83
84 #endif
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_ntz.c
14 PMAC implementation, internal function, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 /**
20 Internal PMAC function
21 */
22 int pmac_ntz(unsigned long x)
23 {
24 int c;
25 x &= 0xFFFFFFFFUL;
26 c = 0;
27 while ((x & 1) == 0) {
28 ++c;
29 x >>= 1;
30 }
31 return c;
32 }
33
34 #endif
35
36 /* $Source$ */
37 /* $Revision$ */
38 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_process.c
14 PMAC implementation, process data, by Tom St Denis
15 */
16
17
18 #ifdef LTC_PMAC
19
20 /**
21 Process data in a PMAC stream
22 @param pmac The PMAC state
23 @param in The data to send through PMAC
24 @param inlen The length of the data to send through PMAC
25 @return CRYPT_OK if successful
26 */
27 int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen)
28 {
29 int err, n;
30 unsigned long x;
31 unsigned char Z[MAXBLOCKSIZE];
32
33 LTC_ARGCHK(pmac != NULL);
34 LTC_ARGCHK(in != NULL);
35 if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) {
36 return err;
37 }
38
39 if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) ||
40 (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 #ifdef LTC_FAST
45 if (pmac->buflen == 0 && inlen > 16) {
46 unsigned long y;
47 for (x = 0; x < (inlen - 16); x += 16) {
48 pmac_shift_xor(pmac);
49 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
50 *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y]));
51 }
52 if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
53 return err;
54 }
55 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
56 *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y]));
57 }
58 in += 16;
59 }
60 inlen -= x;
61 }
62 #endif
63
64 while (inlen != 0) {
65 /* ok if the block is full we xor in prev, encrypt and replace prev */
66 if (pmac->buflen == pmac->block_len) {
67 pmac_shift_xor(pmac);
68 for (x = 0; x < (unsigned long)pmac->block_len; x++) {
69 Z[x] = pmac->Li[x] ^ pmac->block[x];
70 }
71 if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
72 return err;
73 }
74 for (x = 0; x < (unsigned long)pmac->block_len; x++) {
75 pmac->checksum[x] ^= Z[x];
76 }
77 pmac->buflen = 0;
78 }
79
80 /* add bytes */
81 n = MIN(inlen, (unsigned long)(pmac->block_len - pmac->buflen));
82 XMEMCPY(pmac->block + pmac->buflen, in, n);
83 pmac->buflen += n;
84 inlen -= n;
85 in += n;
86 }
87
88 #ifdef LTC_CLEAN_STACK
89 zeromem(Z, sizeof(Z));
90 #endif
91
92 return CRYPT_OK;
93 }
94
95 #endif
96
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pmac_shift_xor.c
14 PMAC implementation, internal function, by Tom St Denis
15 */
16
17 #ifdef LTC_PMAC
18
19 /**
20 Internal function. Performs the state update (adding correct multiple)
21 @param pmac The PMAC state.
22 */
23 void pmac_shift_xor(pmac_state *pmac)
24 {
25 int x, y;
26 y = pmac_ntz(pmac->block_index++);
27 #ifdef LTC_FAST
28 for (x = 0; x < pmac->block_len; x += sizeof(LTC_FAST_TYPE)) {
29 *((LTC_FAST_TYPE*)((unsigned char *)pmac->Li + x)) ^=
30 *((LTC_FAST_TYPE*)((unsigned char *)pmac->Ls[y] + x));
31 }
32 #else
33 for (x = 0; x < pmac->block_len; x++) {
34 pmac->Li[x] ^= pmac->Ls[y][x];
35 }
36 #endif
37 }
38
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_done.c
14 XCBC Support, terminate the state
15 */
16
17 #ifdef LTC_XCBC
18
19 /** Terminate the XCBC-MAC state
20 @param xcbc XCBC state to terminate
21 @param out [out] Destination for the MAC tag
22 @param outlen [in/out] Destination size and final tag size
23 Return CRYPT_OK on success
24 */
25 int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen)
26 {
27 int err, x;
28 LTC_ARGCHK(xcbc != NULL);
29 LTC_ARGCHK(out != NULL);
30
31 /* check structure */
32 if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) {
33 return err;
34 }
35
36 if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) ||
37 (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) {
38 return CRYPT_INVALID_ARG;
39 }
40
41 /* which key do we use? */
42 if (xcbc->buflen == xcbc->blocksize) {
43 /* k2 */
44 for (x = 0; x < xcbc->blocksize; x++) {
45 xcbc->IV[x] ^= xcbc->K[1][x];
46 }
47 } else {
48 xcbc->IV[xcbc->buflen] ^= 0x80;
49 /* k3 */
50 for (x = 0; x < xcbc->blocksize; x++) {
51 xcbc->IV[x] ^= xcbc->K[2][x];
52 }
53 }
54
55 /* encrypt */
56 cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
57 cipher_descriptor[xcbc->cipher].done(&xcbc->key);
58
59 /* extract tag */
60 for (x = 0; x < xcbc->blocksize && (unsigned long)x < *outlen; x++) {
61 out[x] = xcbc->IV[x];
62 }
63 *outlen = x;
64
65 #ifdef LTC_CLEAN_STACK
66 zeromem(xcbc, sizeof(*xcbc));
67 #endif
68 return CRYPT_OK;
69 }
70
71 #endif
72
73 /* $Source$ */
74 /* $Revision$ */
75 /* $Date$ */
76
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_file.c
14 XCBC support, process a file, Tom St Denis
15 */
16
17 #ifdef LTC_XCBC
18
19 /**
20 XCBC a file
21 @param cipher The index of the cipher desired
22 @param key The secret key
23 @param keylen The length of the secret key (octets)
24 @param filename The name of the file you wish to XCBC
25 @param out [out] Where the authentication tag is to be stored
26 @param outlen [in/out] The max size and resulting size of the authentication tag
27 @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
29 int xcbc_file(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const char *filename,
32 unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35 return CRYPT_NOP;
36 #else
37 int err, x;
38 xcbc_state xcbc;
39 FILE *in;
40 unsigned char buf[512];
41
42 LTC_ARGCHK(key != NULL);
43 LTC_ARGCHK(filename != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 in = fopen(filename, "rb");
48 if (in == NULL) {
49 return CRYPT_FILE_NOTFOUND;
50 }
51
52 if ((err = xcbc_init(&xcbc, cipher, key, keylen)) != CRYPT_OK) {
53 fclose(in);
54 return err;
55 }
56
57 do {
58 x = fread(buf, 1, sizeof(buf), in);
59 if ((err = xcbc_process(&xcbc, buf, x)) != CRYPT_OK) {
60 fclose(in);
61 return err;
62 }
63 } while (x == sizeof(buf));
64 fclose(in);
65
66 if ((err = xcbc_done(&xcbc, out, outlen)) != CRYPT_OK) {
67 return err;
68 }
69
70 #ifdef LTC_CLEAN_STACK
71 zeromem(buf, sizeof(buf));
72 #endif
73
74 return CRYPT_OK;
75 #endif
76 }
77
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_init.c
14 XCBC Support, start an XCBC state
15 */
16
17 #ifdef LTC_XCBC
18
19 /** Initialize XCBC-MAC state
20 @param xcbc [out] XCBC state to initialize
21 @param cipher Index of cipher to use
22 @param key [in] Secret key
23 @param keylen Length of secret key in octets
24 Return CRYPT_OK on success
25 */
26 int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen)
27 {
28 int x, y, err;
29 symmetric_key *skey;
30 unsigned long k1;
31
32 LTC_ARGCHK(xcbc != NULL);
33 LTC_ARGCHK(key != NULL);
34
35 /* schedule the key */
36 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 #ifdef LTC_FAST
41 if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
42 return CRYPT_INVALID_ARG;
43 }
44 #endif
45
46 skey = NULL;
47
48 /* are we in pure XCBC mode with three keys? */
49 if (keylen & LTC_XCBC_PURE) {
50 keylen &= ~LTC_XCBC_PURE;
51
52 if (keylen < 2UL*cipher_descriptor[cipher].block_length) {
53 return CRYPT_INVALID_ARG;
54 }
55
56 k1 = keylen - 2*cipher_descriptor[cipher].block_length;
57 XMEMCPY(xcbc->K[0], key, k1);
58 XMEMCPY(xcbc->K[1], key+k1, cipher_descriptor[cipher].block_length);
59 XMEMCPY(xcbc->K[2], key+k1 + cipher_descriptor[cipher].block_length, cipher_descriptor[cipher].block_length);
60 } else {
61 /* use the key expansion */
62 k1 = cipher_descriptor[cipher].block_length;
63
64 /* schedule the user key */
65 skey = XCALLOC(1, sizeof(*skey));
66 if (skey == NULL) {
67 return CRYPT_MEM;
68 }
69
70 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
71 goto done;
72 }
73
74 /* make the three keys */
75 for (y = 0; y < 3; y++) {
76 for (x = 0; x < cipher_descriptor[cipher].block_length; x++) {
77 xcbc->K[y][x] = y + 1;
78 }
79 cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey);
80 }
81 }
82
83 /* setup K1 */
84 err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key);
85
86 /* setup struct */
87 zeromem(xcbc->IV, cipher_descriptor[cipher].block_length);
88 xcbc->blocksize = cipher_descriptor[cipher].block_length;
89 xcbc->cipher = cipher;
90 xcbc->buflen = 0;
91 done:
92 cipher_descriptor[cipher].done(skey);
93 if (skey != NULL) {
94 #ifdef LTC_CLEAN_STACK
95 zeromem(skey, sizeof(*skey));
96 #endif
97 XFREE(skey);
98 }
99 return err;
100 }
101
102 #endif
103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
107
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_process.c
14 XCBC Support, XCBC-MAC a block of memory
15 */
16
17 #ifdef LTC_XCBC
18
19 /** XCBC-MAC a block of memory
20 @param cipher Index of cipher to use
21 @param key [in] Secret key
22 @param keylen Length of key in octets
23 @param in [in] Message to MAC
24 @param inlen Length of input in octets
25 @param out [out] Destination for the MAC tag
26 @param outlen [in/out] Output size and final tag size
27 Return CRYPT_OK on success.
28 */
29 int xcbc_memory(int cipher,
30 const unsigned char *key, unsigned long keylen,
31 const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long *outlen)
33 {
34 xcbc_state *xcbc;
35 int err;
36
37 /* is the cipher valid? */
38 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* Use accelerator if found */
43 if (cipher_descriptor[cipher].xcbc_memory != NULL) {
44 return cipher_descriptor[cipher].xcbc_memory(key, keylen, in, inlen, out, outlen);
45 }
46
47 xcbc = XCALLOC(1, sizeof(*xcbc));
48 if (xcbc == NULL) {
49 return CRYPT_MEM;
50 }
51
52 if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) {
53 goto done;
54 }
55
56 if ((err = xcbc_process(xcbc, in, inlen)) != CRYPT_OK) {
57 goto done;
58 }
59
60 err = xcbc_done(xcbc, out, outlen);
61 done:
62 XFREE(xcbc);
63 return err;
64 }
65
66 #endif
67
68 /* $Source$ */
69 /* $Revision$ */
70 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file xcbc_memory_multi.c
15 XCBC support, process multiple blocks of memory, Tom St Denis
16 */
17
18 #ifdef LTC_XCBC
19
20 /**
21 XCBC multiple blocks of memory
22 @param cipher The index of the desired cipher
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param out [out] The destination of the authentication tag
26 @param outlen [in/out] The max size and resulting size of the authentication tag (octets)
27 @param in The data to send through XCBC
28 @param inlen The length of the data to send through XCBC (octets)
29 @param ... tuples of (data,len) pairs to XCBC, terminated with a (NULL,x) (x=don't care)
30 @return CRYPT_OK if successful
31 */
32 int xcbc_memory_multi(int cipher,
33 const unsigned char *key, unsigned long keylen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *in, unsigned long inlen, ...)
36 {
37 int err;
38 xcbc_state *xcbc;
39 va_list args;
40 const unsigned char *curptr;
41 unsigned long curlen;
42
43 LTC_ARGCHK(key != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47
48 /* allocate ram for xcbc state */
49 xcbc = XMALLOC(sizeof(xcbc_state));
50 if (xcbc == NULL) {
51 return CRYPT_MEM;
52 }
53
54 /* xcbc process the message */
55 if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) {
56 goto LBL_ERR;
57 }
58 va_start(args, inlen);
59 curptr = in;
60 curlen = inlen;
61 for (;;) {
62 /* process buf */
63 if ((err = xcbc_process(xcbc, curptr, curlen)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 /* step to next */
67 curptr = va_arg(args, const unsigned char*);
68 if (curptr == NULL) {
69 break;
70 }
71 curlen = va_arg(args, unsigned long);
72 }
73 if ((err = xcbc_done(xcbc, out, outlen)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76 LBL_ERR:
77 #ifdef LTC_CLEAN_STACK
78 zeromem(xcbc, sizeof(xcbc_state));
79 #endif
80 XFREE(xcbc);
81 va_end(args);
82 return err;
83 }
84
85 #endif
86
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file xcbc_process.c
14 XCBC Support, process blocks with XCBC
15 */
16
17 #ifdef LTC_XCBC
18
19 /** Process data through XCBC-MAC
20 @param xcbc The XCBC-MAC state
21 @param in Input data to process
22 @param inlen Length of input in octets
23 Return CRYPT_OK on success
24 */
25 int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen)
26 {
27 int err;
28 #ifdef LTC_FAST
29 int x;
30 #endif
31
32 LTC_ARGCHK(xcbc != NULL);
33 LTC_ARGCHK(in != NULL);
34
35 /* check structure */
36 if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) ||
41 (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 #ifdef LTC_FAST
46 if (xcbc->buflen == 0) {
47 while (inlen > (unsigned long)xcbc->blocksize) {
48 for (x = 0; x < xcbc->blocksize; x += sizeof(LTC_FAST_TYPE)) {
49 *((LTC_FAST_TYPE*)&(xcbc->IV[x])) ^= *((LTC_FAST_TYPE*)&(in[x]));
50 }
51 cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
52 in += xcbc->blocksize;
53 inlen -= xcbc->blocksize;
54 }
55 }
56 #endif
57
58 while (inlen) {
59 if (xcbc->buflen == xcbc->blocksize) {
60 cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
61 xcbc->buflen = 0;
62 }
63 xcbc->IV[xcbc->buflen++] ^= *in++;
64 --inlen;
65 }
66 return CRYPT_OK;
67 }
68
69 #endif
70
71 /* $Source$ */
72 /* $Revision$ */
73 /* $Date$ */
74
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ltc_ecc_fp_mulmod.c
14 ECC Crypto, Tom St Denis
15 */
16
17 #if defined(LTC_MECC) && defined(LTC_MECC_FP)
18 #include <limits.h>
19
20 /* number of entries in the cache */
21 #ifndef FP_ENTRIES
22 #define FP_ENTRIES 16
23 #endif
24
25 /* number of bits in LUT */
26 #ifndef FP_LUT
27 #define FP_LUT 8U
28 #endif
29
30 #if (FP_LUT > 12) || (FP_LUT < 2)
31 #error FP_LUT must be between 2 and 12 inclusively
32 #endif
33
34 /** Our FP cache */
35 static struct {
36 ecc_point *g, /* cached COPY of base point */
37 *LUT[1U<<FP_LUT]; /* fixed point lookup */
38 void *mu; /* copy of the montgomery constant */
39 int lru_count; /* amount of times this entry has been used */
40 int lock; /* flag to indicate cache eviction permitted (0) or not (1) */
41 } fp_cache[FP_ENTRIES];
42
43 LTC_MUTEX_GLOBAL(ltc_ecc_fp_lock)
44
45 /* simple table to help direct the generation of the LUT */
46 static const struct {
47 int ham, terma, termb;
48 } lut_orders[] = {
49 { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
50 { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
51 { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
52 { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
53 { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
54 { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
55 { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
56 { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
57 #if FP_LUT > 6
58 { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
59 { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
60 { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
61 { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
62 { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
63 { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
64 { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
65 { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
66 #if FP_LUT > 7
67 { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
68 { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
69 { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
70 { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
71 { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
72 { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
73 { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
74 { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
75 { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
76 { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
77 { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
78 { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
79 { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
80 { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
81 { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
82 { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
83 #if FP_LUT > 8
84 { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
85 { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
86 { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
87 { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
88 { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
89 { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
90 { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
91 { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
92 { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
93 { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
94 { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
95 { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
96 { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
97 { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
98 { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
99 { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
100 { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
101 { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
102 { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
103 { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
104 { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
105 { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
106 { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
107 { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
108 { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
109 { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
110 { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
111 { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
112 { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
113 { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
114 { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
115 { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
116 #if FP_LUT > 9
117 { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
118 { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
119 { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
120 { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
121 { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
122 { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
123 { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
124 { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
125 { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
126 { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
127 { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
128 { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
129 { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
130 { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
131 { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
132 { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
133 { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
134 { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
135 { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
136 { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
137 { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
138 { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
139 { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
140 { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
141 { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
142 { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
143 { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
144 { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
145 { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
146 { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
147 { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
148 { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
149 { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
150 { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
151 { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
152 { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
153 { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
154 { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
155 { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
156 { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
157 { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
158 { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
159 { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
160 { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
161 { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
162 { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
163 { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
164 { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
165 { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
166 { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
167 { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
168 { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
169 { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
170 { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
171 { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
172 { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
173 { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
174 { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
175 { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
176 { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
177 { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
178 { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
179 { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
180 { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
181 #if FP_LUT > 10
182 { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
183 { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
184 { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
185 { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
186 { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
187 { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
188 { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
189 { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
190 { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
191 { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
192 { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
193 { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
194 { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
195 { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
196 { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
197 { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
198 { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
199 { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
200 { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
201 { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
202 { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
203 { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
204 { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
205 { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
206 { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
207 { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
208 { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
209 { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
210 { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
211 { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
212 { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
213 { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
214 { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
215 { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
216 { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
217 { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
218 { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
219 { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
220 { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
221 { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
222 { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
223 { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
224 { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
225 { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
226 { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
227 { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
228 { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
229 { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
230 { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
231 { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
232 { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
233 { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
234 { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
235 { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
236 { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
237 { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
238 { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
239 { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
240 { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
241 { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
242 { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
243 { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
244 { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
245 { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
246 { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
247 { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
248 { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
249 { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
250 { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
251 { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
252 { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
253 { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
254 { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
255 { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
256 { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
257 { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
258 { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
259 { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
260 { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
261 { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
262 { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
263 { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
264 { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
265 { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
266 { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
267 { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
268 { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
269 { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
270 { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
271 { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
272 { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
273 { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
274 { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
275 { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
276 { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
277 { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
278 { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
279 { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
280 { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
281 { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
282 { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
283 { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
284 { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
285 { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
286 { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
287 { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
288 { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
289 { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
290 { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
291 { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
292 { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
293 { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
294 { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
295 { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
296 { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
297 { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
298 { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
299 { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
300 { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
301 { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
302 { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
303 { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
304 { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
305 { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
306 { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
307 { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
308 { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
309 { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
310 #if FP_LUT > 11
311 { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
312 { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
313 { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
314 { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
315 { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
316 { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
317 { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
318 { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
319 { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
320 { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
321 { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
322 { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
323 { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
324 { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
325 { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
326 { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
327 { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
328 { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
329 { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
330 { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
331 { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
332 { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
333 { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
334 { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
335 { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
336 { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
337 { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
338 { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
339 { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
340 { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
341 { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
342 { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
343 { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
344 { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
345 { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
346 { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
347 { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
348 { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
349 { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
350 { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
351 { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
352 { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
353 { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
354 { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
355 { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
356 { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
357 { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
358 { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
359 { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
360 { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
361 { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
362 { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
363 { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
364 { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
365 { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
366 { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
367 { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
368 { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
369 { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
370 { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
371 { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
372 { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
373 { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
374 { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
375 { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
376 { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
377 { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
378 { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
379 { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
380 { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
381 { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
382 { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
383 { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
384 { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
385 { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
386 { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
387 { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
388 { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
389 { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
390 { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
391 { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
392 { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
393 { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
394 { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
395 { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
396 { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
397 { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
398 { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
399 { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
400 { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
401 { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
402 { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
403 { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
404 { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
405 { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
406 { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
407 { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
408 { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
409 { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
410 { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
411 { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
412 { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
413 { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
414 { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
415 { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
416 { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
417 { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
418 { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
419 { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
420 { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
421 { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
422 { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
423 { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
424 { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
425 { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
426 { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
427 { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
428 { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
429 { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
430 { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
431 { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
432 { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
433 { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
434 { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
435 { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
436 { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
437 { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
438 { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
439 { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
440 { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
441 { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
442 { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
443 { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
444 { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
445 { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
446 { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
447 { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
448 { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
449 { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
450 { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
451 { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
452 { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
453 { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
454 { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
455 { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
456 { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
457 { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
458 { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
459 { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
460 { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
461 { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
462 { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
463 { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
464 { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
465 { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
466 { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
467 { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
468 { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
469 { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
470 { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
471 { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
472 { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
473 { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
474 { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
475 { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
476 { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
477 { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
478 { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
479 { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
480 { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
481 { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
482 { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
483 { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
484 { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
485 { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
486 { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
487 { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
488 { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
489 { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
490 { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
491 { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
492 { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
493 { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
494 { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
495 { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
496 { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
497 { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
498 { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
499 { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
500 { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
501 { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
502 { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
503 { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
504 { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
505 { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
506 { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
507 { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
508 { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
509 { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
510 { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
511 { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
512 { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
513 { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
514 { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
515 { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
516 { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
517 { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
518 { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
519 { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
520 { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
521 { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
522 { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
523 { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
524 { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
525 { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
526 { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
527 { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
528 { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
529 { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
530 { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
531 { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
532 { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
533 { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
534 { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
535 { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
536 { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
537 { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
538 { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
539 { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
540 { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
541 { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
542 { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
543 { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
544 { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
545 { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
546 { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
547 { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
548 { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
549 { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
550 { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
551 { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
552 { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
553 { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
554 { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
555 { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
556 { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
557 { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
558 { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
559 { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
560 { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
561 { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
562 { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
563 { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
564 { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
565 { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
566 { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
567 #endif
568 #endif
569 #endif
570 #endif
571 #endif
572 #endif
573 };
574
575 /* find a hole and free as required, return -1 if no hole found */
576 static int find_hole(void)
577 {
578 unsigned x;
579 int y, z;
580 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
581 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
582 z = x;
583 y = fp_cache[x].lru_count;
584 }
585 }
586
587 /* decrease all */
588 for (x = 0; x < FP_ENTRIES; x++) {
589 if (fp_cache[x].lru_count > 3) {
590 --(fp_cache[x].lru_count);
591 }
592 }
593
594 /* free entry z */
595 if (z >= 0 && fp_cache[z].g) {
596 if (fp_cache[z].mu != NULL) {
597 mp_clear(fp_cache[z].mu);
598 fp_cache[z].mu = NULL;
599 }
600 ltc_ecc_del_point(fp_cache[z].g);
601 fp_cache[z].g = NULL;
602 for (x = 0; x < (1U<<FP_LUT); x++) {
603 ltc_ecc_del_point(fp_cache[z].LUT[x]);
604 fp_cache[z].LUT[x] = NULL;
605 }
606 fp_cache[z].lru_count = 0;
607 }
608 return z;
609 }
610
611 /* determine if a base is already in the cache and if so, where */
612 static int find_base(ecc_point *g)
613 {
614 int x;
615 for (x = 0; x < FP_ENTRIES; x++) {
616 if (fp_cache[x].g != NULL &&
617 mp_cmp(fp_cache[x].g->x, g->x) == LTC_MP_EQ &&
618 mp_cmp(fp_cache[x].g->y, g->y) == LTC_MP_EQ &&
619 mp_cmp(fp_cache[x].g->z, g->z) == LTC_MP_EQ) {
620 break;
621 }
622 }
623 if (x == FP_ENTRIES) {
624 x = -1;
625 }
626 return x;
627 }
628
629 /* add a new base to the cache */
630 static int add_entry(int idx, ecc_point *g)
631 {
632 unsigned x, y;
633
634 /* allocate base and LUT */
635 fp_cache[idx].g = ltc_ecc_new_point();
636 if (fp_cache[idx].g == NULL) {
637 return CRYPT_MEM;
638 }
639
640 /* copy x and y */
641 if ((mp_copy(g->x, fp_cache[idx].g->x) != CRYPT_OK) ||
642 (mp_copy(g->y, fp_cache[idx].g->y) != CRYPT_OK) ||
643 (mp_copy(g->z, fp_cache[idx].g->z) != CRYPT_OK)) {
644 ltc_ecc_del_point(fp_cache[idx].g);
645 fp_cache[idx].g = NULL;
646 return CRYPT_MEM;
647 }
648
649 for (x = 0; x < (1U<<FP_LUT); x++) {
650 fp_cache[idx].LUT[x] = ltc_ecc_new_point();
651 if (fp_cache[idx].LUT[x] == NULL) {
652 for (y = 0; y < x; y++) {
653 ltc_ecc_del_point(fp_cache[idx].LUT[y]);
654 fp_cache[idx].LUT[y] = NULL;
655 }
656 ltc_ecc_del_point(fp_cache[idx].g);
657 fp_cache[idx].g = NULL;
658 fp_cache[idx].lru_count = 0;
659 return CRYPT_MEM;
660 }
661 }
662
663 fp_cache[idx].lru_count = 0;
664 return CRYPT_OK;
665 }
666
667 /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
668 *
669 * The algorithm builds patterns in increasing bit order by first making all
670 * single bit input patterns, then all two bit input patterns and so on
671 */
672 static int build_lut(int idx, void *modulus, void *mp, void *mu)
673 {
674 unsigned x, y, err, bitlen, lut_gap;
675 void *tmp;
676
677 tmp = NULL;
678
679 /* sanity check to make sure lut_order table is of correct size, should compile out to a NOP if true */
680 if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
681 err = CRYPT_INVALID_ARG;
682 goto DONE;
683 }
684
685 /* get bitlen and round up to next multiple of FP_LUT */
686 bitlen = mp_unsigned_bin_size(modulus) << 3;
687 x = bitlen % FP_LUT;
688 if (x) {
689 bitlen += FP_LUT - x;
690 }
691 lut_gap = bitlen / FP_LUT;
692
693 /* init the mu */
694 if ((err = mp_init_copy(&fp_cache[idx].mu, mu)) != CRYPT_OK) {
695 goto ERR;
696 }
697
698 /* copy base */
699 if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus, fp_cache[idx].LUT[1]->x) != CRYPT_OK) ||
700 (mp_mulmod(fp_cache[idx].g->y, mu, modulus, fp_cache[idx].LUT[1]->y) != CRYPT_OK) ||
701 (mp_mulmod(fp_cache[idx].g->z, mu, modulus, fp_cache[idx].LUT[1]->z) != CRYPT_OK)) { goto ERR; }
702
703 /* make all single bit entries */
704 for (x = 1; x < FP_LUT; x++) {
705 if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, fp_cache[idx].LUT[1<<x]->x) != CRYPT_OK) ||
706 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, fp_cache[idx].LUT[1<<x]->y) != CRYPT_OK) ||
707 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, fp_cache[idx].LUT[1<<x]->z) != CRYPT_OK)) { goto ERR; }
708
709 /* now double it bitlen/FP_LUT times */
710 for (y = 0; y < lut_gap; y++) {
711 if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<<x], fp_cache[idx].LUT[1<<x], modulus, mp)) != CRYPT_OK) {
712 goto ERR;
713 }
714 }
715 }
716
717 /* now make all entries in increase order of hamming weight */
718 for (x = 2; x <= FP_LUT; x++) {
719 for (y = 0; y < (1UL<<FP_LUT); y++) {
720 if (lut_orders[y].ham != (int)x) continue;
721
722 /* perform the add */
723 if ((err = ltc_mp.ecc_ptadd(fp_cache[idx].LUT[lut_orders[y].terma], fp_cache[idx].LUT[lut_orders[y].termb],
724 fp_cache[idx].LUT[y], modulus, mp)) != CRYPT_OK) {
725 goto ERR;
726 }
727 }
728 }
729
730 /* now map all entries back to affine space to make point addition faster */
731 if ((err = mp_init(&tmp)) != CRYPT_OK) { goto ERR; }
732 for (x = 1; x < (1UL<<FP_LUT); x++) {
733 /* convert z to normal from montgomery */
734 if ((err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp)) != CRYPT_OK) { goto ERR; }
735
736 /* invert it */
737 if ((err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, fp_cache[idx].LUT[x]->z)) != CRYPT_OK) { goto ERR; }
738
739 /* now square it */
740 if ((err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; }
741
742 /* fix x */
743 if ((err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus, fp_cache[idx].LUT[x]->x)) != CRYPT_OK) { goto ERR; }
744
745 /* get 1/z^3 */
746 if ((err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; }
747
748 /* fix y */
749 if ((err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus, fp_cache[idx].LUT[x]->y)) != CRYPT_OK) { goto ERR; }
750
751 /* free z */
752 mp_clear(fp_cache[idx].LUT[x]->z);
753 fp_cache[idx].LUT[x]->z = NULL;
754 }
755 mp_clear(tmp);
756
757 return CRYPT_OK;
758 ERR:
759 err = CRYPT_MEM;
760 DONE:
761 for (y = 0; y < (1U<<FP_LUT); y++) {
762 ltc_ecc_del_point(fp_cache[idx].LUT[y]);
763 fp_cache[idx].LUT[y] = NULL;
764 }
765 ltc_ecc_del_point(fp_cache[idx].g);
766 fp_cache[idx].g = NULL;
767 fp_cache[idx].lru_count = 0;
768 if (fp_cache[idx].mu != NULL) {
769 mp_clear(fp_cache[idx].mu);
770 fp_cache[idx].mu = NULL;
771 }
772 if (tmp != NULL) {
773 mp_clear(tmp);
774 }
775 return err;
776 }
777
778 /* perform a fixed point ECC mulmod */
779 static int accel_fp_mul(int idx, void *k, ecc_point *R, void *modulus, void *mp, int map)
780 {
781 unsigned char kb[128];
782 int x;
783 unsigned y, z, err, bitlen, bitpos, lut_gap, first;
784 void *tk, *order;
785
786 /* if it's smaller than modulus we fine */
787 if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
788 /* find order */
789 y = mp_unsigned_bin_size(modulus);
790 for (x = 0; ltc_ecc_sets[x].size; x++) {
791 if (y <= (unsigned)ltc_ecc_sets[x].size) break;
792 }
793
794 /* back off if we are on the 521 bit curve */
795 if (y == 66) --x;
796
797 if ((err = mp_init(&order)) != CRYPT_OK) {
798 return err;
799 }
800 if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) {
801 mp_clear(&order);
802 return err;
803 }
804
805 /* k must be less than modulus */
806 if (mp_cmp(k, order) != LTC_MP_LT) {
807 if ((err = mp_init(&tk)) != CRYPT_OK) {
808 mp_clear(order);
809 return err;
810 }
811 if ((err = mp_mod(k, order, tk)) != CRYPT_OK) {
812 mp_clear(tk);
813 mp_clear(order);
814 return err;
815 }
816 } else {
817 tk = k;
818 }
819 mp_clear(order);
820 } else {
821 tk = k;
822 }
823
824 /* get bitlen and round up to next multiple of FP_LUT */
825 bitlen = mp_unsigned_bin_size(modulus) << 3;
826 x = bitlen % FP_LUT;
827 if (x) {
828 bitlen += FP_LUT - x;
829 }
830 lut_gap = bitlen / FP_LUT;
831
832 /* get the k value */
833 if (mp_unsigned_bin_size(tk) > (sizeof(kb) - 2)) {
834 if (tk != k) {
835 mp_clear(tk);
836 }
837 return CRYPT_BUFFER_OVERFLOW;
838 }
839
840 /* store k */
841 zeromem(kb, sizeof(kb));
842 if ((err = mp_to_unsigned_bin(tk, kb)) != CRYPT_OK) {
843 if (tk != k) {
844 mp_clear(tk);
845 }
846 return err;
847 }
848
849 /* let's reverse kb so it's little endian */
850 x = 0;
851 y = mp_unsigned_bin_size(tk) - 1;
852 if (tk != k) {
853 mp_clear(tk);
854 }
855 while ((unsigned)x < y) {
856 z = kb[x]; kb[x] = kb[y]; kb[y] = z;
857 ++x; --y;
858 }
859
860 /* at this point we can start, yipee */
861 first = 1;
862 for (x = lut_gap-1; x >= 0; x--) {
863 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */
864 bitpos = x;
865 for (y = z = 0; y < FP_LUT; y++) {
866 z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;
867 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */
868 }
869
870 /* double if not first */
871 if (!first) {
872 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) {
873 return err;
874 }
875 }
876
877 /* add if not first, otherwise copy */
878 if (!first && z) {
879 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, modulus, mp)) != CRYPT_OK) {
880 return err;
881 }
882 } else if (z) {
883 if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != CRYPT_OK) ||
884 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != CRYPT_OK) ||
885 (mp_copy(fp_cache[idx].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; }
886 first = 0;
887 }
888 }
889 z = 0;
890 zeromem(kb, sizeof(kb));
891 /* map R back from projective space */
892 if (map) {
893 err = ltc_ecc_map(R, modulus, mp);
894 } else {
895 err = CRYPT_OK;
896 }
897 return err;
898 }
899
900 #ifdef LTC_ECC_SHAMIR
901 /* perform a fixed point ECC mulmod */
902 static int accel_fp_mul2add(int idx1, int idx2,
903 void *kA, void *kB,
904 ecc_point *R, void *modulus, void *mp)
905 {
906 unsigned char kb[2][128];
907 int x;
908 unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB;
909 void *tka, *tkb, *order;
910
911 /* if it's smaller than modulus we fine */
912 if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
913 /* find order */
914 y = mp_unsigned_bin_size(modulus);
915 for (x = 0; ltc_ecc_sets[x].size; x++) {
916 if (y <= (unsigned)ltc_ecc_sets[x].size) break;
917 }
918
919 /* back off if we are on the 521 bit curve */
920 if (y == 66) --x;
921
922 if ((err = mp_init(&order)) != CRYPT_OK) {
923 return err;
924 }
925 if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) {
926 mp_clear(&order);
927 return err;
928 }
929
930 /* kA must be less than modulus */
931 if (mp_cmp(kA, order) != LTC_MP_LT) {
932 if ((err = mp_init(&tka)) != CRYPT_OK) {
933 mp_clear(order);
934 return err;
935 }
936 if ((err = mp_mod(kA, order, tka)) != CRYPT_OK) {
937 mp_clear(tka);
938 mp_clear(order);
939 return err;
940 }
941 } else {
942 tka = kA;
943 }
944 mp_clear(order);
945 } else {
946 tka = kA;
947 }
948
949 /* if it's smaller than modulus we fine */
950 if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
951 /* find order */
952 y = mp_unsigned_bin_size(modulus);
953 for (x = 0; ltc_ecc_sets[x].size; x++) {
954 if (y <= (unsigned)ltc_ecc_sets[x].size) break;
955 }
956
957 /* back off if we are on the 521 bit curve */
958 if (y == 66) --x;
959
960 if ((err = mp_init(&order)) != CRYPT_OK) {
961 return err;
962 }
963 if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) {
964 mp_clear(&order);
965 return err;
966 }
967
968 /* kB must be less than modulus */
969 if (mp_cmp(kB, order) != LTC_MP_LT) {
970 if ((err = mp_init(&tkb)) != CRYPT_OK) {
971 mp_clear(order);
972 return err;
973 }
974 if ((err = mp_mod(kB, order, tkb)) != CRYPT_OK) {
975 mp_clear(tkb);
976 mp_clear(order);
977 return err;
978 }
979 } else {
980 tkb = kB;
981 }
982 mp_clear(order);
983 } else {
984 tkb = kB;
985 }
986
987 /* get bitlen and round up to next multiple of FP_LUT */
988 bitlen = mp_unsigned_bin_size(modulus) << 3;
989 x = bitlen % FP_LUT;
990 if (x) {
991 bitlen += FP_LUT - x;
992 }
993 lut_gap = bitlen / FP_LUT;
994
995 /* get the k value */
996 if ((mp_unsigned_bin_size(tka) > (sizeof(kb[0]) - 2)) || (mp_unsigned_bin_size(tkb) > (sizeof(kb[0]) - 2)) ) {
997 if (tka != kA) {
998 mp_clear(tka);
999 }
1000 if (tkb != kB) {
1001 mp_clear(tkb);
1002 }
1003 return CRYPT_BUFFER_OVERFLOW;
1004 }
1005
1006 /* store k */
1007 zeromem(kb, sizeof(kb));
1008 if ((err = mp_to_unsigned_bin(tka, kb[0])) != CRYPT_OK) {
1009 if (tka != kA) {
1010 mp_clear(tka);
1011 }
1012 if (tkb != kB) {
1013 mp_clear(tkb);
1014 }
1015 return err;
1016 }
1017
1018 /* let's reverse kb so it's little endian */
1019 x = 0;
1020 y = mp_unsigned_bin_size(tka) - 1;
1021 if (tka != kA) {
1022 mp_clear(tka);
1023 }
1024 while ((unsigned)x < y) {
1025 z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z;
1026 ++x; --y;
1027 }
1028
1029 /* store b */
1030 if ((err = mp_to_unsigned_bin(tkb, kb[1])) != CRYPT_OK) {
1031 if (tkb != kB) {
1032 mp_clear(tkb);
1033 }
1034 return err;
1035 }
1036
1037 x = 0;
1038 y = mp_unsigned_bin_size(tkb) - 1;
1039 if (tkb != kB) {
1040 mp_clear(tkb);
1041 }
1042 while ((unsigned)x < y) {
1043 z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z;
1044 ++x; --y;
1045 }
1046
1047 /* at this point we can start, yipee */
1048 first = 1;
1049 for (x = lut_gap-1; x >= 0; x--) {
1050 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */
1051 bitpos = x;
1052 for (y = zA = zB = 0; y < FP_LUT; y++) {
1053 zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
1054 zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
1055 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */
1056 }
1057
1058 /* double if not first */
1059 if (!first) {
1060 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) {
1061 return err;
1062 }
1063 }
1064
1065 /* add if not first, otherwise copy */
1066 if (!first) {
1067 if (zA) {
1068 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, modulus, mp)) != CRYPT_OK) {
1069 return err;
1070 }
1071 }
1072 if (zB) {
1073 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) {
1074 return err;
1075 }
1076 }
1077 } else {
1078 if (zA) {
1079 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != CRYPT_OK) ||
1080 (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != CRYPT_OK) ||
1081 (mp_copy(fp_cache[idx1].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; }
1082 first = 0;
1083 }
1084 if (zB && first == 0) {
1085 if (zB) {
1086 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) {
1087 return err;
1088 }
1089 }
1090 } else if (zB && first == 1) {
1091 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != CRYPT_OK) ||
1092 (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != CRYPT_OK) ||
1093 (mp_copy(fp_cache[idx2].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; }
1094 first = 0;
1095 }
1096 }
1097 }
1098 zeromem(kb, sizeof(kb));
1099 return ltc_ecc_map(R, modulus, mp);
1100 }
1101
1102 /** ECC Fixed Point mulmod global
1103 Computes kA*A + kB*B = C using Shamir's Trick
1104 @param A First point to multiply
1105 @param kA What to multiple A by
1106 @param B Second point to multiply
1107 @param kB What to multiple B by
1108 @param C [out] Destination point (can overlap with A or B)
1109 @param modulus Modulus for curve
1110 @return CRYPT_OK on success
1111 */
1112 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
1113 ecc_point *B, void *kB,
1114 ecc_point *C, void *modulus)
1115 {
1116 int idx1, idx2, err;
1117 void *mp, *mu;
1118
1119 mp = NULL;
1120 mu = NULL;
1121 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1122 /* find point */
1123 idx1 = find_base(A);
1124
1125 /* no entry? */
1126 if (idx1 == -1) {
1127 /* find hole and add it */
1128 if ((idx1 = find_hole()) >= 0) {
1129 if ((err = add_entry(idx1, A)) != CRYPT_OK) {
1130 goto LBL_ERR;
1131 }
1132 }
1133 }
1134 if (idx1 != -1) {
1135 /* increment LRU */
1136 ++(fp_cache[idx1].lru_count);
1137 }
1138
1139 /* find point */
1140 idx2 = find_base(B);
1141
1142 /* no entry? */
1143 if (idx2 == -1) {
1144 /* find hole and add it */
1145 if ((idx2 = find_hole()) >= 0) {
1146 if ((err = add_entry(idx2, B)) != CRYPT_OK) {
1147 goto LBL_ERR;
1148 }
1149 }
1150 }
1151 if (idx2 != -1) {
1152 /* increment LRU */
1153 ++(fp_cache[idx2].lru_count);
1154 }
1155
1156 /* if it's 2 build the LUT, if it's higher just use the LUT */
1157 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
1158 /* compute mp */
1159 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1160
1161 /* compute mu */
1162 if ((err = mp_init(&mu)) != CRYPT_OK) {
1163 goto LBL_ERR;
1164 }
1165 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1166 goto LBL_ERR;
1167 }
1168
1169 /* build the LUT */
1170 if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) {
1171 goto LBL_ERR;;
1172 }
1173 }
1174
1175 /* if it's 2 build the LUT, if it's higher just use the LUT */
1176 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
1177 if (mp == NULL) {
1178 /* compute mp */
1179 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1180
1181 /* compute mu */
1182 if ((err = mp_init(&mu)) != CRYPT_OK) {
1183 goto LBL_ERR;
1184 }
1185 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1186 goto LBL_ERR;
1187 }
1188 }
1189
1190 /* build the LUT */
1191 if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) {
1192 goto LBL_ERR;;
1193 }
1194 }
1195
1196
1197 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) {
1198 if (mp == NULL) {
1199 /* compute mp */
1200 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1201 }
1202 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp);
1203 } else {
1204 err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus);
1205 }
1206 LBL_ERR:
1207 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1208 if (mp != NULL) {
1209 mp_montgomery_free(mp);
1210 }
1211 if (mu != NULL) {
1212 mp_clear(mu);
1213 }
1214 return err;
1215 }
1216 #endif
1217
1218 /** ECC Fixed Point mulmod global
1219 @param k The multiplicand
1220 @param G Base point to multiply
1221 @param R [out] Destination of product
1222 @param modulus The modulus for the curve
1223 @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form
1224 @return CRYPT_OK if successful
1225 */
1226 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
1227 {
1228 int idx, err;
1229 void *mp, *mu;
1230
1231 mp = NULL;
1232 mu = NULL;
1233 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1234 /* find point */
1235 idx = find_base(G);
1236
1237 /* no entry? */
1238 if (idx == -1) {
1239 /* find hole and add it */
1240 idx = find_hole();
1241
1242 if (idx >= 0) {
1243 if ((err = add_entry(idx, G)) != CRYPT_OK) {
1244 goto LBL_ERR;
1245 }
1246 }
1247 }
1248 if (idx != -1) {
1249 /* increment LRU */
1250 ++(fp_cache[idx].lru_count);
1251 }
1252
1253
1254 /* if it's 2 build the LUT, if it's higher just use the LUT */
1255 if (idx >= 0 && fp_cache[idx].lru_count == 2) {
1256 /* compute mp */
1257 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1258
1259 /* compute mu */
1260 if ((err = mp_init(&mu)) != CRYPT_OK) {
1261 goto LBL_ERR;
1262 }
1263 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1264 goto LBL_ERR;
1265 }
1266
1267 /* build the LUT */
1268 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1269 goto LBL_ERR;;
1270 }
1271 }
1272
1273 if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
1274 if (mp == NULL) {
1275 /* compute mp */
1276 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1277 }
1278 err = accel_fp_mul(idx, k, R, modulus, mp, map);
1279 } else {
1280 err = ltc_ecc_mulmod(k, G, R, modulus, map);
1281 }
1282 LBL_ERR:
1283 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1284 if (mp != NULL) {
1285 mp_montgomery_free(mp);
1286 }
1287 if (mu != NULL) {
1288 mp_clear(mu);
1289 }
1290 return err;
1291 }
1292
1293 /* helper function for freeing the cache ... must be called with the cache mutex locked */
1294 static void ltc_ecc_fp_free_cache(void)
1295 {
1296 unsigned x, y;
1297 for (x = 0; x < FP_ENTRIES; x++) {
1298 if (fp_cache[x].g != NULL) {
1299 for (y = 0; y < (1U<<FP_LUT); y++) {
1300 ltc_ecc_del_point(fp_cache[x].LUT[y]);
1301 fp_cache[x].LUT[y] = NULL;
1302 }
1303 ltc_ecc_del_point(fp_cache[x].g);
1304 fp_cache[x].g = NULL;
1305 if (fp_cache[x].mu != NULL) {
1306 mp_clear(fp_cache[x].mu);
1307 fp_cache[x].mu = NULL;
1308 }
1309 fp_cache[x].lru_count = 0;
1310 fp_cache[x].lock = 0;
1311 }
1312 }
1313 }
1314
1315 /** Free the Fixed Point cache */
1316 void ltc_ecc_fp_free(void)
1317 {
1318 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1319 ltc_ecc_fp_free_cache();
1320 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1321 }
1322
1323 /** Add a point to the cache and initialize the LUT
1324 @param g The point to add
1325 @param modulus Modulus for curve
1326 @param lock Flag to indicate if this entry should be locked into the cache or not
1327 @return CRYPT_OK on success
1328 */
1329 int
1330 ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock)
1331 {
1332 int idx;
1333 int err;
1334 void *mp = NULL;
1335 void *mu = NULL;
1336
1337 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1338 if ((idx = find_base(g)) >= 0) {
1339 /* it is already in the cache ... just check that the LUT is initialized */
1340 if(fp_cache[idx].lru_count >= 2) {
1341 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1342 return CRYPT_OK;
1343 }
1344 }
1345
1346 if(idx == -1 && (idx = find_hole()) == -1) {
1347 err = CRYPT_BUFFER_OVERFLOW;
1348 goto LBL_ERR;
1349 }
1350 if ((err = add_entry(idx, g)) != CRYPT_OK) {
1351 goto LBL_ERR;
1352 }
1353 /* compute mp */
1354 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
1355 goto LBL_ERR;
1356 }
1357
1358 /* compute mu */
1359 if ((err = mp_init(&mu)) != CRYPT_OK) {
1360 goto LBL_ERR;
1361 }
1362 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1363 goto LBL_ERR;
1364 }
1365
1366 /* build the LUT */
1367 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1368 goto LBL_ERR;
1369 }
1370 fp_cache[idx].lru_count = 2;
1371 fp_cache[idx].lock = lock;
1372 LBL_ERR:
1373 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1374 if (mp != NULL) {
1375 mp_montgomery_free(mp);
1376 }
1377 if (mu != NULL) {
1378 mp_clear(mu);
1379 }
1380 return err;
1381 }
1382
1383 /** Prevent/permit the FP cache from being updated
1384 @param flag If flag is 0, remove cache lock (unlock), otherwise lock it
1385 */
1386 void ltc_ecc_fp_tablelock(int lock)
1387 {
1388 int i;
1389
1390 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1391 for (i = 0; i < FP_ENTRIES; i++) {
1392 fp_cache[i].lock = lock;
1393 }
1394 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1395 }
1396
1397 /** Export the current cache as a binary packet
1398 @param out [out] pointer to malloc'ed space containing the packet
1399 @param outlen [out] size of exported packet
1400 @return CRYPT_OK if successful
1401 */
1402 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen)
1403 {
1404 ltc_asn1_list *cache_entry;
1405 unsigned int i, j, k;
1406 unsigned long fp_entries, fp_lut, num_entries;
1407 int err;
1408
1409 LTC_ARGCHK(out != NULL);
1410 LTC_ARGCHK(outlen != NULL);
1411
1412 fp_entries = FP_ENTRIES;
1413 fp_lut = FP_LUT;
1414 num_entries = 0;
1415
1416 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1417 /*
1418 * build the list;
1419 Cache DEFINITIONS ::=
1420 BEGIN
1421 CacheDump ::= SEQUENCE {
1422 numEntries SHORTINTEGER,
1423 maxEntries SHORTINTEGER,
1424 numLUT SHORTINTEGER,
1425 cache SEQUENCE OF INTEGER
1426 }
1427 END
1428 *
1429 */
1430 /*
1431 * The cache itself is a point (3 INTEGERS),
1432 * the LUT as pairs of INTEGERS (2 * 1<<FP_LUT),
1433 * and the mu INTEGER
1434 */
1435 cache_entry = XCALLOC(FP_ENTRIES*(2*(1U<<FP_LUT)+4)+3, sizeof(ltc_asn1_list));
1436 if (cache_entry == NULL)
1437 return CRYPT_MEM;
1438 j = 1; /* handle the zero'th element later */
1439
1440 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1);
1441 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1);
1442
1443 for (i = 0; i < FP_ENTRIES; i++) {
1444 /*
1445 * do not save empty entries, or entries that have not yet had the lut built
1446 */
1447 if (fp_cache[i].g == NULL || fp_cache[i].lru_count < 2) {
1448 continue;
1449 }
1450 num_entries++;
1451 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1);
1452 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1);
1453 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1);
1454 for (k = 0; k < (1U<<FP_LUT); k++) {
1455 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->x, 1);
1456 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->y, 1);
1457 }
1458 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1);
1459 }
1460 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_EOL, 0, 0);
1461
1462 LTC_SET_ASN1(cache_entry, 0, LTC_ASN1_SHORT_INTEGER, &num_entries, 1);
1463
1464 if ((err = der_length_sequence(cache_entry, j, outlen)) != CRYPT_OK) {
1465 goto save_err;
1466 }
1467 if ((*out = XMALLOC(*outlen)) == NULL) {
1468 err = CRYPT_MEM;
1469 goto save_err;
1470 }
1471 err = der_encode_sequence(cache_entry, j, *out, outlen);
1472 save_err:
1473 XFREE(cache_entry);
1474 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1475 return err;
1476 }
1477
1478 /** Import a binary packet into the current cache
1479 @param in [in] pointer to packet
1480 @param inlen [in] size of packet (bytes)
1481 @return CRYPT_OK if successful
1482 */
1483 int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen)
1484 {
1485 int err;
1486 ltc_asn1_list *asn1_list;
1487 unsigned long num_entries, fp_entries, fp_lut;
1488 unsigned long i, j;
1489 unsigned int x;
1490
1491 LTC_ARGCHK(in != NULL);
1492 if (inlen == 0) {
1493 return CRYPT_INVALID_ARG;
1494 }
1495
1496 /* zero indecies */
1497 i = 0;
1498 j = 0;
1499 asn1_list = NULL;
1500
1501 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1502 /*
1503 * start with an empty cache
1504 */
1505 ltc_ecc_fp_free_cache();
1506
1507 /*
1508 * decode the input packet: It consists of a sequence with a few
1509 * integers (including the FP_ENTRIES and FP_LUT sizes), followed by a
1510 * SEQUENCE which is the cache itself.
1511 *
1512 * use standard decoding for the first part, then flexible for the second
1513 */
1514 if((err = der_decode_sequence_multi(in, inlen,
1515 LTC_ASN1_SHORT_INTEGER, 1, &num_entries,
1516 LTC_ASN1_SHORT_INTEGER, 1, &fp_entries,
1517 LTC_ASN1_SHORT_INTEGER, 1, &fp_lut,
1518 LTC_ASN1_EOL, 0, 0)) != CRYPT_OK) {
1519 goto ERR_OUT;
1520 }
1521 if (fp_entries != FP_ENTRIES || fp_lut != FP_LUT || num_entries > fp_entries) {
1522 err = CRYPT_INVALID_PACKET;
1523 goto ERR_OUT;
1524 }
1525 if ((asn1_list = XCALLOC(3+num_entries*(4+2*(1<<FP_LUT))+1, sizeof(ltc_asn1_list))) == NULL) {
1526 err = CRYPT_MEM;
1527 goto ERR_OUT;
1528 }
1529 j = 0;
1530 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &num_entries, 1);
1531 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1);
1532 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1);
1533 for (i = 0; i < num_entries; i++) {
1534 if((fp_cache[i].g = ltc_ecc_new_point()) == NULL) {
1535 err = CRYPT_MEM;
1536 goto ERR_OUT;
1537 }
1538 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1);
1539 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1);
1540 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1);
1541 for (x = 0; x < (1U<<FP_LUT); x++) {
1542 /* since we don't store z in the cache, don't use ltc_ecc_new_point()
1543 * (which allocates space for z, only to have to free it later) */
1544 ecc_point *p = XCALLOC(1, sizeof(*p));
1545
1546 if (p == NULL) {
1547 err = CRYPT_MEM;
1548 goto ERR_OUT;
1549 }
1550 fp_cache[i].LUT[x] = p;
1551 if ((err = mp_init_multi(&p->x, &p->y, NULL)) != CRYPT_OK) {
1552 goto ERR_OUT;
1553 }
1554 p->z = NULL;
1555 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->x, 1);
1556 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->y, 1);
1557 }
1558 if((err = mp_init(&fp_cache[i].mu)) != CRYPT_OK) {
1559 goto ERR_OUT;
1560 }
1561 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1);
1562 fp_cache[i].lru_count = 3;
1563 fp_cache[i].lock = 1;
1564 }
1565
1566 if ((err = der_decode_sequence(in, inlen, asn1_list, j)) != CRYPT_OK) {
1567 goto ERR_OUT;
1568 }
1569 XFREE(asn1_list);
1570 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1571 return CRYPT_OK;
1572 ERR_OUT:
1573 if(asn1_list)
1574 XFREE(asn1_list);
1575 ltc_ecc_fp_free_cache();
1576 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1577 return err;
1578 }
1579
1580 #endif
1581
1582
1583 /* $Source$ */
1584 /* $Revision$ */
1585 /* $Date$ */
1586
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #define DESC_DEF_ONLY
12 #include "tomcrypt.h"
13
14 #ifdef LTM_DESC
15
16 #include <tommath.h>
17
18 static const struct {
19 int mpi_code, ltc_code;
20 } mpi_to_ltc_codes[] = {
21 { MP_OKAY , CRYPT_OK},
22 { MP_MEM , CRYPT_MEM},
23 { MP_VAL , CRYPT_INVALID_ARG},
24 };
25
26 /**
27 Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no)
28 @param err The error to convert
29 @return The equivalent LTC error code or CRYPT_ERROR if none found
30 */
31 static int mpi_to_ltc_error(int err)
32 {
33 int x;
34
35 for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
36 if (err == mpi_to_ltc_codes[x].mpi_code) {
37 return mpi_to_ltc_codes[x].ltc_code;
38 }
39 }
40 return CRYPT_ERROR;
41 }
42
43 static int init(void **a)
44 {
45 int err;
46
47 LTC_ARGCHK(a != NULL);
48
49 *a = XCALLOC(1, sizeof(mp_int));
50 if (*a == NULL) {
51 return CRYPT_MEM;
52 }
53
54 if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) {
55 XFREE(*a);
56 }
57 return err;
58 }
59
60 static void deinit(void *a)
61 {
62 LTC_ARGCHKVD(a != NULL);
63 mp_clear(a);
64 XFREE(a);
65 }
66
67 static int neg(void *a, void *b)
68 {
69 LTC_ARGCHK(a != NULL);
70 LTC_ARGCHK(b != NULL);
71 return mpi_to_ltc_error(mp_neg(a, b));
72 }
73
74 static int copy(void *a, void *b)
75 {
76 LTC_ARGCHK(a != NULL);
77 LTC_ARGCHK(b != NULL);
78 return mpi_to_ltc_error(mp_copy(a, b));
79 }
80
81 static int init_copy(void **a, void *b)
82 {
83 if (init(a) != CRYPT_OK) {
84 return CRYPT_MEM;
85 }
86 return copy(b, *a);
87 }
88
89 /* ---- trivial ---- */
90 static int set_int(void *a, unsigned long b)
91 {
92 LTC_ARGCHK(a != NULL);
93 return mpi_to_ltc_error(mp_set_int(a, b));
94 }
95
96 static unsigned long get_int(void *a)
97 {
98 LTC_ARGCHK(a != NULL);
99 return mp_get_int(a);
100 }
101
102 static unsigned long get_digit(void *a, int n)
103 {
104 mp_int *A;
105 LTC_ARGCHK(a != NULL);
106 A = a;
107 return (n >= A->used || n < 0) ? 0 : A->dp[n];
108 }
109
110 static int get_digit_count(void *a)
111 {
112 mp_int *A;
113 LTC_ARGCHK(a != NULL);
114 A = a;
115 return A->used;
116 }
117
118 static int compare(void *a, void *b)
119 {
120 int ret;
121 LTC_ARGCHK(a != NULL);
122 LTC_ARGCHK(b != NULL);
123 ret = mp_cmp(a, b);
124 switch (ret) {
125 case MP_LT: return LTC_MP_LT;
126 case MP_EQ: return LTC_MP_EQ;
127 case MP_GT: return LTC_MP_GT;
128 }
129 return 0;
130 }
131
132 static int compare_d(void *a, unsigned long b)
133 {
134 int ret;
135 LTC_ARGCHK(a != NULL);
136 ret = mp_cmp_d(a, b);
137 switch (ret) {
138 case MP_LT: return LTC_MP_LT;
139 case MP_EQ: return LTC_MP_EQ;
140 case MP_GT: return LTC_MP_GT;
141 }
142 return 0;
143 }
144
145 static int count_bits(void *a)
146 {
147 LTC_ARGCHK(a != NULL);
148 return mp_count_bits(a);
149 }
150
151 static int count_lsb_bits(void *a)
152 {
153 LTC_ARGCHK(a != NULL);
154 return mp_cnt_lsb(a);
155 }
156
157
158 static int twoexpt(void *a, int n)
159 {
160 LTC_ARGCHK(a != NULL);
161 return mpi_to_ltc_error(mp_2expt(a, n));
162 }
163
164 /* ---- conversions ---- */
165
166 /* read ascii string */
167 static int read_radix(void *a, const char *b, int radix)
168 {
169 LTC_ARGCHK(a != NULL);
170 LTC_ARGCHK(b != NULL);
171 return mpi_to_ltc_error(mp_read_radix(a, b, radix));
172 }
173
174 /* write one */
175 static int write_radix(void *a, char *b, int radix)
176 {
177 LTC_ARGCHK(a != NULL);
178 LTC_ARGCHK(b != NULL);
179 return mpi_to_ltc_error(mp_toradix(a, b, radix));
180 }
181
182 /* get size as unsigned char string */
183 static unsigned long unsigned_size(void *a)
184 {
185 LTC_ARGCHK(a != NULL);
186 return mp_unsigned_bin_size(a);
187 }
188
189 /* store */
190 static int unsigned_write(void *a, unsigned char *b)
191 {
192 LTC_ARGCHK(a != NULL);
193 LTC_ARGCHK(b != NULL);
194 return mpi_to_ltc_error(mp_to_unsigned_bin(a, b));
195 }
196
197 /* read */
198 static int unsigned_read(void *a, unsigned char *b, unsigned long len)
199 {
200 LTC_ARGCHK(a != NULL);
201 LTC_ARGCHK(b != NULL);
202 return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len));
203 }
204
205 /* add */
206 static int add(void *a, void *b, void *c)
207 {
208 LTC_ARGCHK(a != NULL);
209 LTC_ARGCHK(b != NULL);
210 LTC_ARGCHK(c != NULL);
211 return mpi_to_ltc_error(mp_add(a, b, c));
212 }
213
214 static int addi(void *a, unsigned long b, void *c)
215 {
216 LTC_ARGCHK(a != NULL);
217 LTC_ARGCHK(c != NULL);
218 return mpi_to_ltc_error(mp_add_d(a, b, c));
219 }
220
221 /* sub */
222 static int sub(void *a, void *b, void *c)
223 {
224 LTC_ARGCHK(a != NULL);
225 LTC_ARGCHK(b != NULL);
226 LTC_ARGCHK(c != NULL);
227 return mpi_to_ltc_error(mp_sub(a, b, c));
228 }
229
230 static int subi(void *a, unsigned long b, void *c)
231 {
232 LTC_ARGCHK(a != NULL);
233 LTC_ARGCHK(c != NULL);
234 return mpi_to_ltc_error(mp_sub_d(a, b, c));
235 }
236
237 /* mul */
238 static int mul(void *a, void *b, void *c)
239 {
240 LTC_ARGCHK(a != NULL);
241 LTC_ARGCHK(b != NULL);
242 LTC_ARGCHK(c != NULL);
243 return mpi_to_ltc_error(mp_mul(a, b, c));
244 }
245
246 static int muli(void *a, unsigned long b, void *c)
247 {
248 LTC_ARGCHK(a != NULL);
249 LTC_ARGCHK(c != NULL);
250 return mpi_to_ltc_error(mp_mul_d(a, b, c));
251 }
252
253 /* sqr */
254 static int sqr(void *a, void *b)
255 {
256 LTC_ARGCHK(a != NULL);
257 LTC_ARGCHK(b != NULL);
258 return mpi_to_ltc_error(mp_sqr(a, b));
259 }
260
261 /* div */
262 static int divide(void *a, void *b, void *c, void *d)
263 {
264 LTC_ARGCHK(a != NULL);
265 LTC_ARGCHK(b != NULL);
266 return mpi_to_ltc_error(mp_div(a, b, c, d));
267 }
268
269 static int div_2(void *a, void *b)
270 {
271 LTC_ARGCHK(a != NULL);
272 LTC_ARGCHK(b != NULL);
273 return mpi_to_ltc_error(mp_div_2(a, b));
274 }
275
276 /* modi */
277 static int modi(void *a, unsigned long b, unsigned long *c)
278 {
279 mp_digit tmp;
280 int err;
281
282 LTC_ARGCHK(a != NULL);
283 LTC_ARGCHK(c != NULL);
284
285 if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) {
286 return err;
287 }
288 *c = tmp;
289 return CRYPT_OK;
290 }
291
292 /* gcd */
293 static int gcd(void *a, void *b, void *c)
294 {
295 LTC_ARGCHK(a != NULL);
296 LTC_ARGCHK(b != NULL);
297 LTC_ARGCHK(c != NULL);
298 return mpi_to_ltc_error(mp_gcd(a, b, c));
299 }
300
301 /* lcm */
302 static int lcm(void *a, void *b, void *c)
303 {
304 LTC_ARGCHK(a != NULL);
305 LTC_ARGCHK(b != NULL);
306 LTC_ARGCHK(c != NULL);
307 return mpi_to_ltc_error(mp_lcm(a, b, c));
308 }
309
310 static int addmod(void *a, void *b, void *c, void *d)
311 {
312 LTC_ARGCHK(a != NULL);
313 LTC_ARGCHK(b != NULL);
314 LTC_ARGCHK(c != NULL);
315 LTC_ARGCHK(d != NULL);
316 return mpi_to_ltc_error(mp_addmod(a,b,c,d));
317 }
318
319 static int submod(void *a, void *b, void *c, void *d)
320 {
321 LTC_ARGCHK(a != NULL);
322 LTC_ARGCHK(b != NULL);
323 LTC_ARGCHK(c != NULL);
324 LTC_ARGCHK(d != NULL);
325 return mpi_to_ltc_error(mp_submod(a,b,c,d));
326 }
327
328 static int mulmod(void *a, void *b, void *c, void *d)
329 {
330 LTC_ARGCHK(a != NULL);
331 LTC_ARGCHK(b != NULL);
332 LTC_ARGCHK(c != NULL);
333 LTC_ARGCHK(d != NULL);
334 return mpi_to_ltc_error(mp_mulmod(a,b,c,d));
335 }
336
337 static int sqrmod(void *a, void *b, void *c)
338 {
339 LTC_ARGCHK(a != NULL);
340 LTC_ARGCHK(b != NULL);
341 LTC_ARGCHK(c != NULL);
342 return mpi_to_ltc_error(mp_sqrmod(a,b,c));
343 }
344
345 /* invmod */
346 static int invmod(void *a, void *b, void *c)
347 {
348 LTC_ARGCHK(a != NULL);
349 LTC_ARGCHK(b != NULL);
350 LTC_ARGCHK(c != NULL);
351 return mpi_to_ltc_error(mp_invmod(a, b, c));
352 }
353
354 /* setup */
355 static int montgomery_setup(void *a, void **b)
356 {
357 int err;
358 LTC_ARGCHK(a != NULL);
359 LTC_ARGCHK(b != NULL);
360 *b = XCALLOC(1, sizeof(mp_digit));
361 if (*b == NULL) {
362 return CRYPT_MEM;
363 }
364 if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) {
365 XFREE(*b);
366 }
367 return err;
368 }
369
370 /* get normalization value */
371 static int montgomery_normalization(void *a, void *b)
372 {
373 LTC_ARGCHK(a != NULL);
374 LTC_ARGCHK(b != NULL);
375 return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b));
376 }
377
378 /* reduce */
379 static int montgomery_reduce(void *a, void *b, void *c)
380 {
381 LTC_ARGCHK(a != NULL);
382 LTC_ARGCHK(b != NULL);
383 LTC_ARGCHK(c != NULL);
384 return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c)));
385 }
386
387 /* clean up */
388 static void montgomery_deinit(void *a)
389 {
390 XFREE(a);
391 }
392
393 static int exptmod(void *a, void *b, void *c, void *d)
394 {
395 LTC_ARGCHK(a != NULL);
396 LTC_ARGCHK(b != NULL);
397 LTC_ARGCHK(c != NULL);
398 LTC_ARGCHK(d != NULL);
399 return mpi_to_ltc_error(mp_exptmod(a,b,c,d));
400 }
401
402 static int isprime(void *a, int *b)
403 {
404 int err;
405 LTC_ARGCHK(a != NULL);
406 LTC_ARGCHK(b != NULL);
407 err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b));
408 *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO;
409 return err;
410 }
411
412 static int set_rand(void *a, int size)
413 {
414 LTC_ARGCHK(a != NULL);
415 return mpi_to_ltc_error(mp_rand(a, size));
416 }
417
418 const ltc_math_descriptor ltm_desc = {
419
420 "LibTomMath",
421 (int)DIGIT_BIT,
422
423 &init,
424 &init_copy,
425 &deinit,
426
427 &neg,
428 &copy,
429
430 &set_int,
431 &get_int,
432 &get_digit,
433 &get_digit_count,
434 &compare,
435 &compare_d,
436 &count_bits,
437 &count_lsb_bits,
438 &twoexpt,
439
440 &read_radix,
441 &write_radix,
442 &unsigned_size,
443 &unsigned_write,
444 &unsigned_read,
445
446 &add,
447 &addi,
448 &sub,
449 &subi,
450 &mul,
451 &muli,
452 &sqr,
453 &divide,
454 &div_2,
455 &modi,
456 &gcd,
457 &lcm,
458
459 &mulmod,
460 &sqrmod,
461 &invmod,
462
463 &montgomery_setup,
464 &montgomery_normalization,
465 &montgomery_reduce,
466 &montgomery_deinit,
467
468 &exptmod,
469 &isprime,
470
471 #ifdef LTC_MECC
472 #ifdef LTC_MECC_FP
473 &ltc_ecc_fp_mulmod,
474 #else
475 &ltc_ecc_mulmod,
476 #endif
477 &ltc_ecc_projective_add_point,
478 &ltc_ecc_projective_dbl_point,
479 &ltc_ecc_map,
480 #ifdef LTC_ECC_SHAMIR
481 #ifdef LTC_MECC_FP
482 &ltc_ecc_fp_mul2add,
483 #else
484 &ltc_ecc_mul2add,
485 #endif /* LTC_MECC_FP */
486 #else
487 NULL,
488 #endif /* LTC_ECC_SHAMIR */
489 #else
490 NULL, NULL, NULL, NULL, NULL,
491 #endif /* LTC_MECC */
492
493 #ifdef LTC_MRSA
494 &rsa_make_key,
495 &rsa_exptmod,
496 #else
497 NULL, NULL,
498 #endif
499 &addmod,
500 &submod,
501
502 &set_rand,
503
504 };
505
506
507 #endif
508
509 /* $Source$ */
510 /* $Revision$ */
511 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 #ifdef MPI
13 #include <stdarg.h>
14
15 int ltc_init_multi(void **a, ...)
16 {
17 void **cur = a;
18 int np = 0;
19 va_list args;
20
21 va_start(args, a);
22 while (cur != NULL) {
23 if (mp_init(cur) != CRYPT_OK) {
24 /* failed */
25 va_list clean_list;
26
27 va_start(clean_list, a);
28 cur = a;
29 while (np--) {
30 mp_clear(*cur);
31 cur = va_arg(clean_list, void**);
32 }
33 va_end(clean_list);
34 return CRYPT_MEM;
35 }
36 ++np;
37 cur = va_arg(args, void**);
38 }
39 va_end(args);
40 return CRYPT_OK;
41 }
42
43 void ltc_deinit_multi(void *a, ...)
44 {
45 void *cur = a;
46 va_list args;
47
48 va_start(args, a);
49 while (cur != NULL) {
50 mp_clear(cur);
51 cur = va_arg(args, void *);
52 }
53 va_end(args);
54 }
55
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rand_prime.c
14 Generate a random prime, Tom St Denis
15 */
16
17 #define USE_BBS 1
18
19 int rand_prime(void *N, long len, prng_state *prng, int wprng)
20 {
21 int err, res, type;
22 unsigned char *buf;
23
24 LTC_ARGCHK(N != NULL);
25
26 /* get type */
27 if (len < 0) {
28 type = USE_BBS;
29 len = -len;
30 } else {
31 type = 0;
32 }
33
34 /* allow sizes between 2 and 512 bytes for a prime size */
35 if (len < 2 || len > 512) {
36 return CRYPT_INVALID_PRIME_SIZE;
37 }
38
39 /* valid PRNG? Better be! */
40 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
41 return err;
42 }
43
44 /* allocate buffer to work with */
45 buf = XCALLOC(1, len);
46 if (buf == NULL) {
47 return CRYPT_MEM;
48 }
49
50 do {
51 /* generate value */
52 if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) {
53 XFREE(buf);
54 return CRYPT_ERROR_READPRNG;
55 }
56
57 /* munge bits */
58 buf[0] |= 0x80 | 0x40;
59 buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
60
61 /* load value */
62 if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) {
63 XFREE(buf);
64 return err;
65 }
66
67 /* test */
68 if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) {
69 XFREE(buf);
70 return err;
71 }
72 } while (res == LTC_MP_NO);
73
74 #ifdef LTC_CLEAN_STACK
75 zeromem(buf, len);
76 #endif
77
78 XFREE(buf);
79 return CRYPT_OK;
80 }
81
82
83
84 /* $Source$ */
85 /* $Revision$ */
86 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #define DESC_DEF_ONLY
12 #include "tomcrypt.h"
13
14 #ifdef TFM_DESC
15
16 #include <tfm.h>
17
18 static const struct {
19 int tfm_code, ltc_code;
20 } tfm_to_ltc_codes[] = {
21 { FP_OKAY , CRYPT_OK},
22 { FP_MEM , CRYPT_MEM},
23 { FP_VAL , CRYPT_INVALID_ARG},
24 };
25
26 /**
27 Convert a tfm error to a LTC error (Possibly the most powerful function ever! Oh wait... no)
28 @param err The error to convert
29 @return The equivalent LTC error code or CRYPT_ERROR if none found
30 */
31 static int tfm_to_ltc_error(int err)
32 {
33 int x;
34
35 for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) {
36 if (err == tfm_to_ltc_codes[x].tfm_code) {
37 return tfm_to_ltc_codes[x].ltc_code;
38 }
39 }
40 return CRYPT_ERROR;
41 }
42
43 static int init(void **a)
44 {
45 LTC_ARGCHK(a != NULL);
46
47 *a = XCALLOC(1, sizeof(fp_int));
48 if (*a == NULL) {
49 return CRYPT_MEM;
50 }
51 fp_init(*a);
52 return CRYPT_OK;
53 }
54
55 static void deinit(void *a)
56 {
57 LTC_ARGCHKVD(a != NULL);
58 XFREE(a);
59 }
60
61 static int neg(void *a, void *b)
62 {
63 LTC_ARGCHK(a != NULL);
64 LTC_ARGCHK(b != NULL);
65 fp_neg(((fp_int*)a), ((fp_int*)b));
66 return CRYPT_OK;
67 }
68
69 static int copy(void *a, void *b)
70 {
71 LTC_ARGCHK(a != NULL);
72 LTC_ARGCHK(b != NULL);
73 fp_copy(a, b);
74 return CRYPT_OK;
75 }
76
77 static int init_copy(void **a, void *b)
78 {
79 if (init(a) != CRYPT_OK) {
80 return CRYPT_MEM;
81 }
82 return copy(b, *a);
83 }
84
85 /* ---- trivial ---- */
86 static int set_int(void *a, unsigned long b)
87 {
88 LTC_ARGCHK(a != NULL);
89 fp_set(a, b);
90 return CRYPT_OK;
91 }
92
93 static unsigned long get_int(void *a)
94 {
95 fp_int *A;
96 LTC_ARGCHK(a != NULL);
97 A = a;
98 return A->used > 0 ? A->dp[0] : 0;
99 }
100
101 static unsigned long get_digit(void *a, int n)
102 {
103 fp_int *A;
104 LTC_ARGCHK(a != NULL);
105 A = a;
106 return (n >= A->used || n < 0) ? 0 : A->dp[n];
107 }
108
109 static int get_digit_count(void *a)
110 {
111 fp_int *A;
112 LTC_ARGCHK(a != NULL);
113 A = a;
114 return A->used;
115 }
116
117 static int compare(void *a, void *b)
118 {
119 int ret;
120 LTC_ARGCHK(a != NULL);
121 LTC_ARGCHK(b != NULL);
122 ret = fp_cmp(a, b);
123 switch (ret) {
124 case FP_LT: return LTC_MP_LT;
125 case FP_EQ: return LTC_MP_EQ;
126 case FP_GT: return LTC_MP_GT;
127 }
128 return 0;
129 }
130
131 static int compare_d(void *a, unsigned long b)
132 {
133 int ret;
134 LTC_ARGCHK(a != NULL);
135 ret = fp_cmp_d(a, b);
136 switch (ret) {
137 case FP_LT: return LTC_MP_LT;
138 case FP_EQ: return LTC_MP_EQ;
139 case FP_GT: return LTC_MP_GT;
140 }
141 return 0;
142 }
143
144 static int count_bits(void *a)
145 {
146 LTC_ARGCHK(a != NULL);
147 return fp_count_bits(a);
148 }
149
150 static int count_lsb_bits(void *a)
151 {
152 LTC_ARGCHK(a != NULL);
153 return fp_cnt_lsb(a);
154 }
155
156 static int twoexpt(void *a, int n)
157 {
158 LTC_ARGCHK(a != NULL);
159 fp_2expt(a, n);
160 return CRYPT_OK;
161 }
162
163 /* ---- conversions ---- */
164
165 /* read ascii string */
166 static int read_radix(void *a, const char *b, int radix)
167 {
168 LTC_ARGCHK(a != NULL);
169 LTC_ARGCHK(b != NULL);
170 return tfm_to_ltc_error(fp_read_radix(a, (char *)b, radix));
171 }
172
173 /* write one */
174 static int write_radix(void *a, char *b, int radix)
175 {
176 LTC_ARGCHK(a != NULL);
177 LTC_ARGCHK(b != NULL);
178 return tfm_to_ltc_error(fp_toradix(a, b, radix));
179 }
180
181 /* get size as unsigned char string */
182 static unsigned long unsigned_size(void *a)
183 {
184 LTC_ARGCHK(a != NULL);
185 return fp_unsigned_bin_size(a);
186 }
187
188 /* store */
189 static int unsigned_write(void *a, unsigned char *b)
190 {
191 LTC_ARGCHK(a != NULL);
192 LTC_ARGCHK(b != NULL);
193 fp_to_unsigned_bin(a, b);
194 return CRYPT_OK;
195 }
196
197 /* read */
198 static int unsigned_read(void *a, unsigned char *b, unsigned long len)
199 {
200 LTC_ARGCHK(a != NULL);
201 LTC_ARGCHK(b != NULL);
202 fp_read_unsigned_bin(a, b, len);
203 return CRYPT_OK;
204 }
205
206 /* add */
207 static int add(void *a, void *b, void *c)
208 {
209 LTC_ARGCHK(a != NULL);
210 LTC_ARGCHK(b != NULL);
211 LTC_ARGCHK(c != NULL);
212 fp_add(a, b, c);
213 return CRYPT_OK;
214 }
215
216 static int addi(void *a, unsigned long b, void *c)
217 {
218 LTC_ARGCHK(a != NULL);
219 LTC_ARGCHK(c != NULL);
220 fp_add_d(a, b, c);
221 return CRYPT_OK;
222 }
223
224 /* sub */
225 static int sub(void *a, void *b, void *c)
226 {
227 LTC_ARGCHK(a != NULL);
228 LTC_ARGCHK(b != NULL);
229 LTC_ARGCHK(c != NULL);
230 fp_sub(a, b, c);
231 return CRYPT_OK;
232 }
233
234 static int subi(void *a, unsigned long b, void *c)
235 {
236 LTC_ARGCHK(a != NULL);
237 LTC_ARGCHK(c != NULL);
238 fp_sub_d(a, b, c);
239 return CRYPT_OK;
240 }
241
242 /* mul */
243 static int mul(void *a, void *b, void *c)
244 {
245 LTC_ARGCHK(a != NULL);
246 LTC_ARGCHK(b != NULL);
247 LTC_ARGCHK(c != NULL);
248 fp_mul(a, b, c);
249 return CRYPT_OK;
250 }
251
252 static int muli(void *a, unsigned long b, void *c)
253 {
254 LTC_ARGCHK(a != NULL);
255 LTC_ARGCHK(c != NULL);
256 fp_mul_d(a, b, c);
257 return CRYPT_OK;
258 }
259
260 /* sqr */
261 static int sqr(void *a, void *b)
262 {
263 LTC_ARGCHK(a != NULL);
264 LTC_ARGCHK(b != NULL);
265 fp_sqr(a, b);
266 return CRYPT_OK;
267 }
268
269 /* div */
270 static int divide(void *a, void *b, void *c, void *d)
271 {
272 LTC_ARGCHK(a != NULL);
273 LTC_ARGCHK(b != NULL);
274 return tfm_to_ltc_error(fp_div(a, b, c, d));
275 }
276
277 static int div_2(void *a, void *b)
278 {
279 LTC_ARGCHK(a != NULL);
280 LTC_ARGCHK(b != NULL);
281 fp_div_2(a, b);
282 return CRYPT_OK;
283 }
284
285 /* modi */
286 static int modi(void *a, unsigned long b, unsigned long *c)
287 {
288 fp_digit tmp;
289 int err;
290
291 LTC_ARGCHK(a != NULL);
292 LTC_ARGCHK(c != NULL);
293
294 if ((err = tfm_to_ltc_error(fp_mod_d(a, b, &tmp))) != CRYPT_OK) {
295 return err;
296 }
297 *c = tmp;
298 return CRYPT_OK;
299 }
300
301 /* gcd */
302 static int gcd(void *a, void *b, void *c)
303 {
304 LTC_ARGCHK(a != NULL);
305 LTC_ARGCHK(b != NULL);
306 LTC_ARGCHK(c != NULL);
307 fp_gcd(a, b, c);
308 return CRYPT_OK;
309 }
310
311 /* lcm */
312 static int lcm(void *a, void *b, void *c)
313 {
314 LTC_ARGCHK(a != NULL);
315 LTC_ARGCHK(b != NULL);
316 LTC_ARGCHK(c != NULL);
317 fp_lcm(a, b, c);
318 return CRYPT_OK;
319 }
320
321 static int addmod(void *a, void *b, void *c, void *d)
322 {
323 LTC_ARGCHK(a != NULL);
324 LTC_ARGCHK(b != NULL);
325 LTC_ARGCHK(c != NULL);
326 LTC_ARGCHK(d != NULL);
327 return tfm_to_ltc_error(fp_addmod(a,b,c,d));
328 }
329
330 static int submod(void *a, void *b, void *c, void *d)
331 {
332 LTC_ARGCHK(a != NULL);
333 LTC_ARGCHK(b != NULL);
334 LTC_ARGCHK(c != NULL);
335 LTC_ARGCHK(d != NULL);
336 return tfm_to_ltc_error(fp_submod(a,b,c,d));
337 }
338
339 static int mulmod(void *a, void *b, void *c, void *d)
340 {
341 LTC_ARGCHK(a != NULL);
342 LTC_ARGCHK(b != NULL);
343 LTC_ARGCHK(c != NULL);
344 LTC_ARGCHK(d != NULL);
345 return tfm_to_ltc_error(fp_mulmod(a,b,c,d));
346 }
347
348 static int sqrmod(void *a, void *b, void *c)
349 {
350 LTC_ARGCHK(a != NULL);
351 LTC_ARGCHK(b != NULL);
352 LTC_ARGCHK(c != NULL);
353 return tfm_to_ltc_error(fp_sqrmod(a,b,c));
354 }
355
356 /* invmod */
357 static int invmod(void *a, void *b, void *c)
358 {
359 LTC_ARGCHK(a != NULL);
360 LTC_ARGCHK(b != NULL);
361 LTC_ARGCHK(c != NULL);
362 return tfm_to_ltc_error(fp_invmod(a, b, c));
363 }
364
365 /* setup */
366 static int montgomery_setup(void *a, void **b)
367 {
368 int err;
369 LTC_ARGCHK(a != NULL);
370 LTC_ARGCHK(b != NULL);
371 *b = XCALLOC(1, sizeof(fp_digit));
372 if (*b == NULL) {
373 return CRYPT_MEM;
374 }
375 if ((err = tfm_to_ltc_error(fp_montgomery_setup(a, (fp_digit *)*b))) != CRYPT_OK) {
376 XFREE(*b);
377 }
378 return err;
379 }
380
381 /* get normalization value */
382 static int montgomery_normalization(void *a, void *b)
383 {
384 LTC_ARGCHK(a != NULL);
385 LTC_ARGCHK(b != NULL);
386 fp_montgomery_calc_normalization(a, b);
387 return CRYPT_OK;
388 }
389
390 /* reduce */
391 static int montgomery_reduce(void *a, void *b, void *c)
392 {
393 LTC_ARGCHK(a != NULL);
394 LTC_ARGCHK(b != NULL);
395 LTC_ARGCHK(c != NULL);
396 fp_montgomery_reduce(a, b, *((fp_digit *)c));
397 return CRYPT_OK;
398 }
399
400 /* clean up */
401 static void montgomery_deinit(void *a)
402 {
403 XFREE(a);
404 }
405
406 static int exptmod(void *a, void *b, void *c, void *d)
407 {
408 LTC_ARGCHK(a != NULL);
409 LTC_ARGCHK(b != NULL);
410 LTC_ARGCHK(c != NULL);
411 LTC_ARGCHK(d != NULL);
412 return tfm_to_ltc_error(fp_exptmod(a,b,c,d));
413 }
414
415 static int isprime(void *a, int *b)
416 {
417 LTC_ARGCHK(a != NULL);
418 LTC_ARGCHK(b != NULL);
419 *b = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO;
420 return CRYPT_OK;
421 }
422
423 #if defined(LTC_MECC) && defined(LTC_MECC_ACCEL)
424
425 static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp)
426 {
427 fp_int t1, t2;
428 fp_digit mp;
429
430 LTC_ARGCHK(P != NULL);
431 LTC_ARGCHK(R != NULL);
432 LTC_ARGCHK(modulus != NULL);
433 LTC_ARGCHK(Mp != NULL);
434
435 mp = *((fp_digit*)Mp);
436
437 fp_init(&t1);
438 fp_init(&t2);
439
440 if (P != R) {
441 fp_copy(P->x, R->x);
442 fp_copy(P->y, R->y);
443 fp_copy(P->z, R->z);
444 }
445
446 /* t1 = Z * Z */
447 fp_sqr(R->z, &t1);
448 fp_montgomery_reduce(&t1, modulus, mp);
449 /* Z = Y * Z */
450 fp_mul(R->z, R->y, R->z);
451 fp_montgomery_reduce(R->z, modulus, mp);
452 /* Z = 2Z */
453 fp_add(R->z, R->z, R->z);
454 if (fp_cmp(R->z, modulus) != FP_LT) {
455 fp_sub(R->z, modulus, R->z);
456 }
457
458 /* &t2 = X - T1 */
459 fp_sub(R->x, &t1, &t2);
460 if (fp_cmp_d(&t2, 0) == FP_LT) {
461 fp_add(&t2, modulus, &t2);
462 }
463 /* T1 = X + T1 */
464 fp_add(&t1, R->x, &t1);
465 if (fp_cmp(&t1, modulus) != FP_LT) {
466 fp_sub(&t1, modulus, &t1);
467 }
468 /* T2 = T1 * T2 */
469 fp_mul(&t1, &t2, &t2);
470 fp_montgomery_reduce(&t2, modulus, mp);
471 /* T1 = 2T2 */
472 fp_add(&t2, &t2, &t1);
473 if (fp_cmp(&t1, modulus) != FP_LT) {
474 fp_sub(&t1, modulus, &t1);
475 }
476 /* T1 = T1 + T2 */
477 fp_add(&t1, &t2, &t1);
478 if (fp_cmp(&t1, modulus) != FP_LT) {
479 fp_sub(&t1, modulus, &t1);
480 }
481
482 /* Y = 2Y */
483 fp_add(R->y, R->y, R->y);
484 if (fp_cmp(R->y, modulus) != FP_LT) {
485 fp_sub(R->y, modulus, R->y);
486 }
487 /* Y = Y * Y */
488 fp_sqr(R->y, R->y);
489 fp_montgomery_reduce(R->y, modulus, mp);
490 /* T2 = Y * Y */
491 fp_sqr(R->y, &t2);
492 fp_montgomery_reduce(&t2, modulus, mp);
493 /* T2 = T2/2 */
494 if (fp_isodd(&t2)) {
495 fp_add(&t2, modulus, &t2);
496 }
497 fp_div_2(&t2, &t2);
498 /* Y = Y * X */
499 fp_mul(R->y, R->x, R->y);
500 fp_montgomery_reduce(R->y, modulus, mp);
501
502 /* X = T1 * T1 */
503 fp_sqr(&t1, R->x);
504 fp_montgomery_reduce(R->x, modulus, mp);
505 /* X = X - Y */
506 fp_sub(R->x, R->y, R->x);
507 if (fp_cmp_d(R->x, 0) == FP_LT) {
508 fp_add(R->x, modulus, R->x);
509 }
510 /* X = X - Y */
511 fp_sub(R->x, R->y, R->x);
512 if (fp_cmp_d(R->x, 0) == FP_LT) {
513 fp_add(R->x, modulus, R->x);
514 }
515
516 /* Y = Y - X */
517 fp_sub(R->y, R->x, R->y);
518 if (fp_cmp_d(R->y, 0) == FP_LT) {
519 fp_add(R->y, modulus, R->y);
520 }
521 /* Y = Y * T1 */
522 fp_mul(R->y, &t1, R->y);
523 fp_montgomery_reduce(R->y, modulus, mp);
524 /* Y = Y - T2 */
525 fp_sub(R->y, &t2, R->y);
526 if (fp_cmp_d(R->y, 0) == FP_LT) {
527 fp_add(R->y, modulus, R->y);
528 }
529
530 return CRYPT_OK;
531 }
532
533 /**
534 Add two ECC points
535 @param P The point to add
536 @param Q The point to add
537 @param R [out] The destination of the double
538 @param modulus The modulus of the field the ECC curve is in
539 @param mp The "b" value from montgomery_setup()
540 @return CRYPT_OK on success
541 */
542 static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp)
543 {
544 fp_int t1, t2, x, y, z;
545 fp_digit mp;
546
547 LTC_ARGCHK(P != NULL);
548 LTC_ARGCHK(Q != NULL);
549 LTC_ARGCHK(R != NULL);
550 LTC_ARGCHK(modulus != NULL);
551 LTC_ARGCHK(Mp != NULL);
552
553 mp = *((fp_digit*)Mp);
554
555 fp_init(&t1);
556 fp_init(&t2);
557 fp_init(&x);
558 fp_init(&y);
559 fp_init(&z);
560
561 /* should we dbl instead? */
562 fp_sub(modulus, Q->y, &t1);
563 if ( (fp_cmp(P->x, Q->x) == FP_EQ) &&
564 (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) &&
565 (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) {
566 return tfm_ecc_projective_dbl_point(P, R, modulus, Mp);
567 }
568
569 fp_copy(P->x, &x);
570 fp_copy(P->y, &y);
571 fp_copy(P->z, &z);
572
573 /* if Z is one then these are no-operations */
574 if (Q->z != NULL) {
575 /* T1 = Z' * Z' */
576 fp_sqr(Q->z, &t1);
577 fp_montgomery_reduce(&t1, modulus, mp);
578 /* X = X * T1 */
579 fp_mul(&t1, &x, &x);
580 fp_montgomery_reduce(&x, modulus, mp);
581 /* T1 = Z' * T1 */
582 fp_mul(Q->z, &t1, &t1);
583 fp_montgomery_reduce(&t1, modulus, mp);
584 /* Y = Y * T1 */
585 fp_mul(&t1, &y, &y);
586 fp_montgomery_reduce(&y, modulus, mp);
587 }
588
589 /* T1 = Z*Z */
590 fp_sqr(&z, &t1);
591 fp_montgomery_reduce(&t1, modulus, mp);
592 /* T2 = X' * T1 */
593 fp_mul(Q->x, &t1, &t2);
594 fp_montgomery_reduce(&t2, modulus, mp);
595 /* T1 = Z * T1 */
596 fp_mul(&z, &t1, &t1);
597 fp_montgomery_reduce(&t1, modulus, mp);
598 /* T1 = Y' * T1 */
599 fp_mul(Q->y, &t1, &t1);
600 fp_montgomery_reduce(&t1, modulus, mp);
601
602 /* Y = Y - T1 */
603 fp_sub(&y, &t1, &y);
604 if (fp_cmp_d(&y, 0) == FP_LT) {
605 fp_add(&y, modulus, &y);
606 }
607 /* T1 = 2T1 */
608 fp_add(&t1, &t1, &t1);
609 if (fp_cmp(&t1, modulus) != FP_LT) {
610 fp_sub(&t1, modulus, &t1);
611 }
612 /* T1 = Y + T1 */
613 fp_add(&t1, &y, &t1);
614 if (fp_cmp(&t1, modulus) != FP_LT) {
615 fp_sub(&t1, modulus, &t1);
616 }
617 /* X = X - T2 */
618 fp_sub(&x, &t2, &x);
619 if (fp_cmp_d(&x, 0) == FP_LT) {
620 fp_add(&x, modulus, &x);
621 }
622 /* T2 = 2T2 */
623 fp_add(&t2, &t2, &t2);
624 if (fp_cmp(&t2, modulus) != FP_LT) {
625 fp_sub(&t2, modulus, &t2);
626 }
627 /* T2 = X + T2 */
628 fp_add(&t2, &x, &t2);
629 if (fp_cmp(&t2, modulus) != FP_LT) {
630 fp_sub(&t2, modulus, &t2);
631 }
632
633 /* if Z' != 1 */
634 if (Q->z != NULL) {
635 /* Z = Z * Z' */
636 fp_mul(&z, Q->z, &z);
637 fp_montgomery_reduce(&z, modulus, mp);
638 }
639
640 /* Z = Z * X */
641 fp_mul(&z, &x, &z);
642 fp_montgomery_reduce(&z, modulus, mp);
643
644 /* T1 = T1 * X */
645 fp_mul(&t1, &x, &t1);
646 fp_montgomery_reduce(&t1, modulus, mp);
647 /* X = X * X */
648 fp_sqr(&x, &x);
649 fp_montgomery_reduce(&x, modulus, mp);
650 /* T2 = T2 * x */
651 fp_mul(&t2, &x, &t2);
652 fp_montgomery_reduce(&t2, modulus, mp);
653 /* T1 = T1 * X */
654 fp_mul(&t1, &x, &t1);
655 fp_montgomery_reduce(&t1, modulus, mp);
656
657 /* X = Y*Y */
658 fp_sqr(&y, &x);
659 fp_montgomery_reduce(&x, modulus, mp);
660 /* X = X - T2 */
661 fp_sub(&x, &t2, &x);
662 if (fp_cmp_d(&x, 0) == FP_LT) {
663 fp_add(&x, modulus, &x);
664 }
665
666 /* T2 = T2 - X */
667 fp_sub(&t2, &x, &t2);
668 if (fp_cmp_d(&t2, 0) == FP_LT) {
669 fp_add(&t2, modulus, &t2);
670 }
671 /* T2 = T2 - X */
672 fp_sub(&t2, &x, &t2);
673 if (fp_cmp_d(&t2, 0) == FP_LT) {
674 fp_add(&t2, modulus, &t2);
675 }
676 /* T2 = T2 * Y */
677 fp_mul(&t2, &y, &t2);
678 fp_montgomery_reduce(&t2, modulus, mp);
679 /* Y = T2 - T1 */
680 fp_sub(&t2, &t1, &y);
681 if (fp_cmp_d(&y, 0) == FP_LT) {
682 fp_add(&y, modulus, &y);
683 }
684 /* Y = Y/2 */
685 if (fp_isodd(&y)) {
686 fp_add(&y, modulus, &y);
687 }
688 fp_div_2(&y, &y);
689
690 fp_copy(&x, R->x);
691 fp_copy(&y, R->y);
692 fp_copy(&z, R->z);
693
694 return CRYPT_OK;
695 }
696
697
698 #endif
699
700 const ltc_math_descriptor tfm_desc = {
701
702 "TomsFastMath",
703 (int)DIGIT_BIT,
704
705 &init,
706 &init_copy,
707 &deinit,
708
709 &neg,
710 &copy,
711
712 &set_int,
713 &get_int,
714 &get_digit,
715 &get_digit_count,
716 &compare,
717 &compare_d,
718 &count_bits,
719 &count_lsb_bits,
720 &twoexpt,
721
722 &read_radix,
723 &write_radix,
724 &unsigned_size,
725 &unsigned_write,
726 &unsigned_read,
727
728 &add,
729 &addi,
730 &sub,
731 &subi,
732 &mul,
733 &muli,
734 &sqr,
735 &divide,
736 &div_2,
737 &modi,
738 &gcd,
739 &lcm,
740
741 &mulmod,
742 &sqrmod,
743 &invmod,
744
745 &montgomery_setup,
746 &montgomery_normalization,
747 &montgomery_reduce,
748 &montgomery_deinit,
749
750 &exptmod,
751 &isprime,
752
753 #ifdef LTC_MECC
754 #ifdef LTC_MECC_FP
755 &ltc_ecc_fp_mulmod,
756 #else
757 &ltc_ecc_mulmod,
758 #endif /* LTC_MECC_FP */
759 #ifdef LTC_MECC_ACCEL
760 &tfm_ecc_projective_add_point,
761 &tfm_ecc_projective_dbl_point,
762 #else
763 &ltc_ecc_projective_add_point,
764 &ltc_ecc_projective_dbl_point,
765 #endif /* LTC_MECC_ACCEL */
766 &ltc_ecc_map,
767 #ifdef LTC_ECC_SHAMIR
768 #ifdef LTC_MECC_FP
769 &ltc_ecc_fp_mul2add,
770 #else
771 &ltc_ecc_mul2add,
772 #endif /* LTC_MECC_FP */
773 #else
774 NULL,
775 #endif /* LTC_ECC_SHAMIR */
776 #else
777 NULL, NULL, NULL, NULL, NULL,
778 #endif /* LTC_MECC */
779
780 #ifdef LTC_MRSA
781 &rsa_make_key,
782 &rsa_exptmod,
783 #else
784 NULL, NULL,
785 #endif
786 &addmod,
787 &submod,
788
789 NULL,
790
791 };
792
793
794 #endif
795
796 /* $Source$ */
797 /* $Revision$ */
798 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file base64_decode.c
14 Compliant base64 code donated by Wayne Scott (wscott@bitmover.com)
15 base64 URL Safe variant (RFC 4648 section 5) by Karel Miko
16 */
17
18
19 #ifdef LTC_BASE64
20
21 static const unsigned char map_base64[256] = {
22 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
23 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
24 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
25 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
26 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
27 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
28 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
29 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
30 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
31 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
32 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
33 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
34 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
35 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
36 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
37 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
39 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255 };
44
45 static const unsigned char map_base64url[256] = {
46 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
47 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
48 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
49 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255,
50 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
51 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
52 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
53 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63,
54 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
55 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
56 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
64 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
65 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
66 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
67 255, 255, 255, 255 };
68
69 /**
70 base64 decode a block of memory
71 @param in The base64 data to decode
72 @param inlen The length of the base64 data
73 @param out [out] The destination of the binary decoded data
74 @param outlen [in/out] The max size and resulting size of the decoded data
75 @return CRYPT_OK if successful
76 */
77 int base64_decode(const unsigned char *in, unsigned long inlen,
78 unsigned char *out, unsigned long *outlen)
79 {
80 return base64_decode_internal(in, inlen, out, outlen, map_base64);
81 }
82
83 /**
84 base64 (URL Safe, RFC 4648 section 5) decode a block of memory
85 @param in The base64 data to decode
86 @param inlen The length of the base64 data
87 @param out [out] The destination of the binary decoded data
88 @param outlen [in/out] The max size and resulting size of the decoded data
89 @return CRYPT_OK if successful
90 */
91 int base64url_decode(const unsigned char *in, unsigned long inlen,
92 unsigned char *out, unsigned long *outlen)
93 {
94 return base64_decode_internal(in, inlen, out, outlen, map_base64url);
95 }
96
97 int base64_decode_internal(const unsigned char *in, unsigned long inlen,
98 unsigned char *out, unsigned long *outlen,
99 const unsigned char *map)
100 {
101 unsigned long t, x, y, z;
102 unsigned char c;
103 int g;
104
105 LTC_ARGCHK(in != NULL);
106 LTC_ARGCHK(out != NULL);
107 LTC_ARGCHK(outlen != NULL);
108
109 g = 3;
110 for (x = y = z = t = 0; x < inlen; x++) {
111 c = map[in[x]&0xFF];
112 if (c == 255) continue;
113 /* the final = symbols are read and used to trim the remaining bytes */
114 if (c == 254) {
115 c = 0;
116 /* prevent g < 0 which would potentially allow an overflow later */
117 if (--g < 0) {
118 return CRYPT_INVALID_PACKET;
119 }
120 } else if (g != 3) {
121 /* we only allow = to be at the end */
122 return CRYPT_INVALID_PACKET;
123 }
124
125 t = (t<<6)|c;
126
127 if (++y == 4) {
128 if (z + g > *outlen) {
129 return CRYPT_BUFFER_OVERFLOW;
130 }
131 out[z++] = (unsigned char)((t>>16)&255);
132 if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
133 if (g > 2) out[z++] = (unsigned char)(t&255);
134 y = t = 0;
135 }
136 }
137 if (y != 0) {
138 return CRYPT_INVALID_PACKET;
139 }
140 *outlen = z;
141 return CRYPT_OK;
142 }
143
144 #endif
145
146
147 /* $Source$ */
148 /* $Revision$ */
149 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file base64_encode.c
14 Compliant base64 encoder donated by Wayne Scott (wscott@bitmover.com)
15 base64 URL Safe variant (RFC 4648 section 5) by Karel Miko
16 */
17
18
19 #ifdef LTC_BASE64
20
21 static const char *codes_base64 =
22 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
23
24 static const char *codes_base64url =
25 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
26
27 /**
28 base64 Encode a buffer (NUL terminated)
29 @param in The input buffer to encode
30 @param inlen The length of the input buffer
31 @param out [out] The destination of the base64 encoded data
32 @param outlen [in/out] The max size and resulting size
33 @return CRYPT_OK if successful
34 */
35 int base64_encode(const unsigned char *in, unsigned long inlen,
36 unsigned char *out, unsigned long *outlen)
37 {
38 return base64_encode_internal(in, inlen, out, outlen, codes_base64, 1);
39 }
40
41 /**
42 base64 (URL Safe, RFC 4648 section 5) Encode a buffer (NUL terminated)
43 @param in The input buffer to encode
44 @param inlen The length of the input buffer
45 @param out [out] The destination of the base64 encoded data
46 @param outlen [in/out] The max size and resulting size
47 @return CRYPT_OK if successful
48 */
49 int base64url_encode(const unsigned char *in, unsigned long inlen,
50 unsigned char *out, unsigned long *outlen)
51 {
52 return base64_encode_internal(in, inlen, out, outlen, codes_base64url, 0);
53 }
54
55 int base64_encode_internal(const unsigned char *in, unsigned long inlen,
56 unsigned char *out, unsigned long *outlen,
57 const char *codes, int pad)
58 {
59 unsigned long i, len2, leven;
60 unsigned char *p;
61
62 LTC_ARGCHK(in != NULL);
63 LTC_ARGCHK(out != NULL);
64 LTC_ARGCHK(outlen != NULL);
65
66 /* valid output size ? */
67 len2 = 4 * ((inlen + 2) / 3);
68 if (*outlen < len2 + 1) {
69 *outlen = len2 + 1;
70 return CRYPT_BUFFER_OVERFLOW;
71 }
72 p = out;
73 leven = 3*(inlen / 3);
74 for (i = 0; i < leven; i += 3) {
75 *p++ = codes[(in[0] >> 2) & 0x3F];
76 *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F];
77 *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
78 *p++ = codes[in[2] & 0x3F];
79 in += 3;
80 }
81 /* Pad it if necessary... */
82 if (i < inlen) {
83 unsigned a = in[0];
84 unsigned b = (i+1 < inlen) ? in[1] : 0;
85
86 *p++ = codes[(a >> 2) & 0x3F];
87 *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
88 if (pad) {
89 *p++ = (i+1 < inlen) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
90 *p++ = '=';
91 }
92 else {
93 if (i+1 < inlen) *p++ = codes[(((b & 0xf) << 2)) & 0x3F];
94 }
95 }
96
97 /* append a NULL byte */
98 *p = '\0';
99
100 /* return ok */
101 *outlen = p - out;
102 return CRYPT_OK;
103 }
104
105 #endif
106
107
108 /* $Source$ */
109 /* $Revision$ */
110 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file burn_stack.c
14 Burn stack, Tom St Denis
15 */
16
17 /**
18 Burn some stack memory
19 @param len amount of stack to burn in bytes
20 */
21 void burn_stack(unsigned long len)
22 {
23 unsigned char buf[32];
24 zeromem(buf, sizeof(buf));
25 if (len > (unsigned long)sizeof(buf))
26 burn_stack(len - sizeof(buf));
27 }
28
29
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt.c
14 Build strings, Tom St Denis
15 */
16
17 const char *crypt_build_settings =
18 "LibTomCrypt " SCRYPT " (Tom St Denis, tomstdenis@gmail.com)\n"
19 "LibTomCrypt is public domain software.\n"
20 "Built on " __DATE__ " at " __TIME__ "\n\n\n"
21 "Endianess: "
22 #if defined(ENDIAN_NEUTRAL)
23 "neutral\n"
24 #elif defined(ENDIAN_LITTLE)
25 "little"
26 #if defined(ENDIAN_32BITWORD)
27 " (32-bit words)\n"
28 #else
29 " (64-bit words)\n"
30 #endif
31 #elif defined(ENDIAN_BIG)
32 "big"
33 #if defined(ENDIAN_32BITWORD)
34 " (32-bit words)\n"
35 #else
36 " (64-bit words)\n"
37 #endif
38 #endif
39 "Clean stack: "
40 #if defined(LTC_CLEAN_STACK)
41 "enabled\n"
42 #else
43 "disabled\n"
44 #endif
45 "Ciphers built-in:\n"
46 #if defined(LTC_BLOWFISH)
47 " Blowfish\n"
48 #endif
49 #if defined(LTC_RC2)
50 " LTC_RC2\n"
51 #endif
52 #if defined(LTC_RC5)
53 " LTC_RC5\n"
54 #endif
55 #if defined(LTC_RC6)
56 " LTC_RC6\n"
57 #endif
58 #if defined(LTC_SAFERP)
59 " Safer+\n"
60 #endif
61 #if defined(LTC_SAFER)
62 " Safer\n"
63 #endif
64 #if defined(LTC_RIJNDAEL)
65 " Rijndael\n"
66 #endif
67 #if defined(LTC_XTEA)
68 " LTC_XTEA\n"
69 #endif
70 #if defined(LTC_TWOFISH)
71 " Twofish "
72 #if defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES)
73 "(small, tables, all_tables)\n"
74 #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES)
75 "(small, tables)\n"
76 #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_ALL_TABLES)
77 "(small, all_tables)\n"
78 #elif defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES)
79 "(tables, all_tables)\n"
80 #elif defined(LTC_TWOFISH_SMALL)
81 "(small)\n"
82 #elif defined(LTC_TWOFISH_TABLES)
83 "(tables)\n"
84 #elif defined(LTC_TWOFISH_ALL_TABLES)
85 "(all_tables)\n"
86 #else
87 "\n"
88 #endif
89 #endif
90 #if defined(LTC_DES)
91 " LTC_DES\n"
92 #endif
93 #if defined(LTC_CAST5)
94 " LTC_CAST5\n"
95 #endif
96 #if defined(LTC_NOEKEON)
97 " Noekeon\n"
98 #endif
99 #if defined(LTC_SKIPJACK)
100 " Skipjack\n"
101 #endif
102 #if defined(LTC_KHAZAD)
103 " Khazad\n"
104 #endif
105 #if defined(LTC_ANUBIS)
106 " Anubis "
107 #endif
108 #if defined(LTC_ANUBIS_TWEAK)
109 " (tweaked)"
110 #endif
111 "\n"
112 #if defined(LTC_KSEED)
113 " LTC_KSEED\n"
114 #endif
115 #if defined(LTC_KASUMI)
116 " KASUMI\n"
117 #endif
118 #if defined(LTC_MULTI2)
119 " MULTI2\n"
120 #endif
121 #if defined(LTC_CAMELLIA)
122 " Camellia\n"
123 #endif
124
125 "\nHashes built-in:\n"
126 #if defined(LTC_SHA512)
127 " LTC_SHA-512\n"
128 #endif
129 #if defined(LTC_SHA384)
130 " LTC_SHA-384\n"
131 #endif
132 #if defined(LTC_SHA256)
133 " LTC_SHA-256\n"
134 #endif
135 #if defined(LTC_SHA224)
136 " LTC_SHA-224\n"
137 #endif
138 #if defined(LTC_TIGER)
139 " LTC_TIGER\n"
140 #endif
141 #if defined(LTC_SHA1)
142 " LTC_SHA1\n"
143 #endif
144 #if defined(LTC_MD5)
145 " LTC_MD5\n"
146 #endif
147 #if defined(LTC_MD4)
148 " LTC_MD4\n"
149 #endif
150 #if defined(LTC_MD2)
151 " LTC_MD2\n"
152 #endif
153 #if defined(LTC_RIPEMD128)
154 " LTC_RIPEMD128\n"
155 #endif
156 #if defined(LTC_RIPEMD160)
157 " LTC_RIPEMD160\n"
158 #endif
159 #if defined(LTC_RIPEMD256)
160 " LTC_RIPEMD256\n"
161 #endif
162 #if defined(LTC_RIPEMD320)
163 " LTC_RIPEMD320\n"
164 #endif
165 #if defined(LTC_WHIRLPOOL)
166 " LTC_WHIRLPOOL\n"
167 #endif
168 #if defined(LTC_CHC_HASH)
169 " LTC_CHC_HASH \n"
170 #endif
171
172 "\nBlock Chaining Modes:\n"
173 #if defined(LTC_CFB_MODE)
174 " CFB\n"
175 #endif
176 #if defined(LTC_OFB_MODE)
177 " OFB\n"
178 #endif
179 #if defined(LTC_ECB_MODE)
180 " ECB\n"
181 #endif
182 #if defined(LTC_CBC_MODE)
183 " CBC\n"
184 #endif
185 #if defined(LTC_CTR_MODE)
186 " CTR "
187 #endif
188 #if defined(LTC_CTR_OLD)
189 " (CTR_OLD) "
190 #endif
191 "\n"
192 #if defined(LRW_MODE)
193 " LRW_MODE"
194 #if defined(LRW_TABLES)
195 " (LRW_TABLES) "
196 #endif
197 "\n"
198 #endif
199 #if defined(LTC_F8_MODE)
200 " F8 MODE\n"
201 #endif
202 #if defined(LTC_XTS_MODE)
203 " LTC_XTS_MODE\n"
204 #endif
205
206 "\nMACs:\n"
207 #if defined(LTC_HMAC)
208 " LTC_HMAC\n"
209 #endif
210 #if defined(LTC_OMAC)
211 " LTC_OMAC\n"
212 #endif
213 #if defined(LTC_PMAC)
214 " PMAC\n"
215 #endif
216 #if defined(LTC_PELICAN)
217 " LTC_PELICAN\n"
218 #endif
219 #if defined(LTC_XCBC)
220 " XCBC-MAC\n"
221 #endif
222 #if defined(LTC_F9_MODE)
223 " F9-MAC\n"
224 #endif
225
226 "\nENC + AUTH modes:\n"
227 #if defined(LTC_EAX_MODE)
228 " LTC_EAX_MODE\n"
229 #endif
230 #if defined(LTC_OCB_MODE)
231 " LTC_OCB_MODE\n"
232 #endif
233 #if defined(LTC_OCB3_MODE)
234 " LTC_OCB3_MODE\n"
235 #endif
236 #if defined(LTC_CCM_MODE)
237 " LTC_CCM_MODE\n"
238 #endif
239 #if defined(LTC_GCM_MODE)
240 " LTC_GCM_MODE "
241 #endif
242 #if defined(LTC_GCM_TABLES)
243 " (LTC_GCM_TABLES) "
244 #endif
245 "\n"
246
247 "\nPRNG:\n"
248 #if defined(LTC_YARROW)
249 " Yarrow\n"
250 #endif
251 #if defined(LTC_SPRNG)
252 " LTC_SPRNG\n"
253 #endif
254 #if defined(LTC_RC4)
255 " LTC_RC4\n"
256 #endif
257 #if defined(LTC_FORTUNA)
258 " Fortuna\n"
259 #endif
260 #if defined(LTC_SOBER128)
261 " LTC_SOBER128\n"
262 #endif
263
264 "\nPK Algs:\n"
265 #if defined(LTC_MRSA)
266 " RSA \n"
267 #endif
268 #if defined(LTC_MECC)
269 " ECC\n"
270 #endif
271 #if defined(LTC_MDSA)
272 " DSA\n"
273 #endif
274 #if defined(MKAT)
275 " Katja\n"
276 #endif
277
278 "\nCompiler:\n"
279 #if defined(WIN32)
280 " WIN32 platform detected.\n"
281 #endif
282 #if defined(__CYGWIN__)
283 " CYGWIN Detected.\n"
284 #endif
285 #if defined(__DJGPP__)
286 " DJGPP Detected.\n"
287 #endif
288 #if defined(_MSC_VER)
289 " MSVC compiler detected.\n"
290 #endif
291 #if defined(__clang_version__)
292 " Clang compiler " __clang_version__ ".\n"
293 #elif defined(__GNUC__) /* clang also defines __GNUC__ */
294 " GCC compiler detected.\n"
295 #endif
296 #if defined(INTEL_CC)
297 " Intel C Compiler detected.\n"
298 #endif
299 #if defined(__x86_64__)
300 " x86-64 detected.\n"
301 #endif
302 #if defined(LTC_PPC32)
303 " LTC_PPC32 defined \n"
304 #endif
305
306 "\nVarious others: "
307 #if defined(LTC_BASE64)
308 " LTC_BASE64 "
309 #endif
310 #if defined(MPI)
311 " MPI "
312 #endif
313 #if defined(TRY_UNRANDOM_FIRST)
314 " TRY_UNRANDOM_FIRST "
315 #endif
316 #if defined(LTC_TEST)
317 " LTC_TEST "
318 #endif
319 #if defined(LTC_PKCS_1)
320 " LTC_PKCS#1 "
321 #endif
322 #if defined(LTC_PKCS_5)
323 " LTC_PKCS#5 "
324 #endif
325 #if defined(LTC_SMALL_CODE)
326 " LTC_SMALL_CODE "
327 #endif
328 #if defined(LTC_NO_FILE)
329 " LTC_NO_FILE "
330 #endif
331 #if defined(LTC_DER)
332 " LTC_DER "
333 #endif
334 #if defined(LTC_FAST)
335 " LTC_FAST "
336 #endif
337 #if defined(LTC_NO_FAST)
338 " LTC_NO_FAST "
339 #endif
340 #if defined(LTC_NO_BSWAP)
341 " LTC_NO_BSWAP "
342 #endif
343 #if defined(LTC_NO_ASM)
344 " LTC_NO_ASM "
345 #endif
346 #if defined(LTC_NO_TEST)
347 " LTC_NO_TEST "
348 #endif
349 #if defined(LTC_NO_TABLES)
350 " LTC_NO_TABLES "
351 #endif
352 #if defined(LTC_PTHREAD)
353 " LTC_PTHREAD "
354 #endif
355 #if defined(LTM_LTC_DESC)
356 " LTM_DESC "
357 #endif
358 #if defined(TFM_LTC_DESC)
359 " TFM_DESC "
360 #endif
361 #if defined(LTC_MECC_ACCEL)
362 " LTC_MECC_ACCEL "
363 #endif
364 #if defined(GMP_LTC_DESC)
365 " GMP_DESC "
366 #endif
367 #if defined(LTC_EASY)
368 " (easy) "
369 #endif
370 #if defined(LTC_MECC_FP)
371 " LTC_MECC_FP "
372 #endif
373 #if defined(LTC_ECC_SHAMIR)
374 " LTC_ECC_SHAMIR "
375 #endif
376 "\n"
377 "\n\n\n"
378 ;
379
380
381 /* $Source$ */
382 /* $Revision$ */
383 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <signal.h>
12
13 /**
14 @file crypt_argchk.c
15 Perform argument checking, Tom St Denis
16 */
17
18 #if (ARGTYPE == 0)
19 void crypt_argchk(char *v, char *s, int d)
20 {
21 fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n",
22 v, d, s);
23 (void)raise(SIGABRT);
24 }
25 #endif
26
27 /* $Source$ */
28 /* $Revision$ */
29 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_cipher_descriptor.c
14 Stores the cipher descriptor table, Tom St Denis
15 */
16
17 struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = {
18 { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
19 };
20
21 LTC_MUTEX_GLOBAL(ltc_cipher_mutex)
22
23
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_cipher_is_valid.c
14 Determine if cipher is valid, Tom St Denis
15 */
16
17 /*
18 Test if a cipher index is valid
19 @param idx The index of the cipher to search for
20 @return CRYPT_OK if valid
21 */
22 int cipher_is_valid(int idx)
23 {
24 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
25 if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
26 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
27 return CRYPT_INVALID_CIPHER;
28 }
29 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
30 return CRYPT_OK;
31 }
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_cipher.c
14 Find a cipher in the descriptor tables, Tom St Denis
15 */
16
17 /**
18 Find a registered cipher by name
19 @param name The name of the cipher to look for
20 @return >= 0 if found, -1 if not present
21 */
22 int find_cipher(const char *name)
23 {
24 int x;
25 LTC_ARGCHK(name != NULL);
26 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
27 for (x = 0; x < TAB_SIZE; x++) {
28 if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) {
29 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
34 return -1;
35 }
36
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_cipher_any.c
14 Find a cipher in the descriptor tables, Tom St Denis
15 */
16
17 /**
18 Find a cipher flexibly. First by name then if not present by block and key size
19 @param name The name of the cipher desired
20 @param blocklen The minimum length of the block cipher desired (octets)
21 @param keylen The minimum length of the key size desired (octets)
22 @return >= 0 if found, -1 if not present
23 */
24 int find_cipher_any(const char *name, int blocklen, int keylen)
25 {
26 int x;
27
28 LTC_ARGCHK(name != NULL);
29
30 x = find_cipher(name);
31 if (x != -1) return x;
32
33 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
34 for (x = 0; x < TAB_SIZE; x++) {
35 if (cipher_descriptor[x].name == NULL) {
36 continue;
37 }
38 if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
39 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
40 return x;
41 }
42 }
43 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
44 return -1;
45 }
46
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_cipher_id.c
14 Find cipher by ID, Tom St Denis
15 */
16
17 /**
18 Find a cipher by ID number
19 @param ID The ID (not same as index) of the cipher to find
20 @return >= 0 if found, -1 if not present
21 */
22 int find_cipher_id(unsigned char ID)
23 {
24 int x;
25 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
26 for (x = 0; x < TAB_SIZE; x++) {
27 if (cipher_descriptor[x].ID == ID) {
28 x = (cipher_descriptor[x].name == NULL) ? -1 : x;
29 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
34 return -1;
35 }
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_hash.c
14 Find a hash, Tom St Denis
15 */
16
17 /**
18 Find a registered hash by name
19 @param name The name of the hash to look for
20 @return >= 0 if found, -1 if not present
21 */
22 int find_hash(const char *name)
23 {
24 int x;
25 LTC_ARGCHK(name != NULL);
26 LTC_MUTEX_LOCK(&ltc_hash_mutex);
27 for (x = 0; x < TAB_SIZE; x++) {
28 if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) {
29 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
34 return -1;
35 }
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_hash_any.c
14 Find a hash, Tom St Denis
15 */
16
17 /**
18 Find a hash flexibly. First by name then if not present by digest size
19 @param name The name of the hash desired
20 @param digestlen The minimum length of the digest size (octets)
21 @return >= 0 if found, -1 if not present
22 */int find_hash_any(const char *name, int digestlen)
23 {
24 int x, y, z;
25 LTC_ARGCHK(name != NULL);
26
27 x = find_hash(name);
28 if (x != -1) return x;
29
30 LTC_MUTEX_LOCK(&ltc_hash_mutex);
31 y = MAXBLOCKSIZE+1;
32 z = -1;
33 for (x = 0; x < TAB_SIZE; x++) {
34 if (hash_descriptor[x].name == NULL) {
35 continue;
36 }
37 if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) {
38 z = x;
39 y = hash_descriptor[x].hashsize;
40 }
41 }
42 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
43 return z;
44 }
45
46 /* $Source$ */
47 /* $Revision$ */
48 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_hash_id.c
14 Find hash by ID, Tom St Denis
15 */
16
17 /**
18 Find a hash by ID number
19 @param ID The ID (not same as index) of the hash to find
20 @return >= 0 if found, -1 if not present
21 */
22 int find_hash_id(unsigned char ID)
23 {
24 int x;
25 LTC_MUTEX_LOCK(&ltc_hash_mutex);
26 for (x = 0; x < TAB_SIZE; x++) {
27 if (hash_descriptor[x].ID == ID) {
28 x = (hash_descriptor[x].name == NULL) ? -1 : x;
29 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
34 return -1;
35 }
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_hash_oid.c
14 Find a hash, Tom St Denis
15 */
16
17 int find_hash_oid(const unsigned long *ID, unsigned long IDlen)
18 {
19 int x;
20 LTC_ARGCHK(ID != NULL);
21 LTC_MUTEX_LOCK(&ltc_hash_mutex);
22 for (x = 0; x < TAB_SIZE; x++) {
23 if (hash_descriptor[x].name != NULL && hash_descriptor[x].OIDlen == IDlen && !XMEMCMP(hash_descriptor[x].OID, ID, sizeof(unsigned long) * IDlen)) {
24 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
25 return x;
26 }
27 }
28 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
29 return -1;
30 }
31
32 /* $Source$ */
33 /* $Revision$ */
34 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_find_prng.c
14 Find a PRNG, Tom St Denis
15 */
16
17 /**
18 Find a registered PRNG by name
19 @param name The name of the PRNG to look for
20 @return >= 0 if found, -1 if not present
21 */
22 int find_prng(const char *name)
23 {
24 int x;
25 LTC_ARGCHK(name != NULL);
26 LTC_MUTEX_LOCK(&ltc_prng_mutex);
27 for (x = 0; x < TAB_SIZE; x++) {
28 if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) {
29 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
30 return x;
31 }
32 }
33 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
34 return -1;
35 }
36
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13 /**
14 @file crypt_fsa.c
15 LibTomCrypt FULL SPEED AHEAD!, Tom St Denis
16 */
17
18 /* format is ltc_mp, cipher_desc, [cipher_desc], NULL, hash_desc, [hash_desc], NULL, prng_desc, [prng_desc], NULL */
19 int crypt_fsa(void *mp, ...)
20 {
21 va_list args;
22 void *p;
23
24 va_start(args, mp);
25 if (mp != NULL) {
26 XMEMCPY(&ltc_mp, mp, sizeof(ltc_mp));
27 }
28
29 while ((p = va_arg(args, void*)) != NULL) {
30 if (register_cipher(p) == -1) {
31 va_end(args);
32 return CRYPT_INVALID_CIPHER;
33 }
34 }
35
36 while ((p = va_arg(args, void*)) != NULL) {
37 if (register_hash(p) == -1) {
38 va_end(args);
39 return CRYPT_INVALID_HASH;
40 }
41 }
42
43 while ((p = va_arg(args, void*)) != NULL) {
44 if (register_prng(p) == -1) {
45 va_end(args);
46 return CRYPT_INVALID_PRNG;
47 }
48 }
49
50 va_end(args);
51 return CRYPT_OK;
52 }
53
54
55 /* $Source$ */
56 /* $Revision$ */
57 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_hash_descriptor.c
14 Stores the hash descriptor table, Tom St Denis
15 */
16
17 struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = {
18 { NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL }
19 };
20
21 LTC_MUTEX_GLOBAL(ltc_hash_mutex)
22
23
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_hash_is_valid.c
14 Determine if hash is valid, Tom St Denis
15 */
16
17 /*
18 Test if a hash index is valid
19 @param idx The index of the hash to search for
20 @return CRYPT_OK if valid
21 */
22 int hash_is_valid(int idx)
23 {
24 LTC_MUTEX_LOCK(&ltc_hash_mutex);
25 if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
26 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
27 return CRYPT_INVALID_HASH;
28 }
29 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
30 return CRYPT_OK;
31 }
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 ltc_math_descriptor ltc_mp;
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_prng_descriptor.c
14 Stores the PRNG descriptors, Tom St Denis
15 */
16 struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = {
17 { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
18 };
19
20 LTC_MUTEX_GLOBAL(ltc_prng_mutex)
21
22
23 /* $Source$ */
24 /* $Revision$ */
25 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_prng_is_valid.c
14 Determine if PRNG is valid, Tom St Denis
15 */
16
17 /*
18 Test if a PRNG index is valid
19 @param idx The index of the PRNG to search for
20 @return CRYPT_OK if valid
21 */
22 int prng_is_valid(int idx)
23 {
24 LTC_MUTEX_LOCK(&ltc_prng_mutex);
25 if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
26 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
27 return CRYPT_INVALID_PRNG;
28 }
29 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
30 return CRYPT_OK;
31 }
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_register_cipher.c
14 Register a cipher, Tom St Denis
15 */
16
17 /**
18 Register a cipher with the descriptor table
19 @param cipher The cipher you wish to register
20 @return value >= 0 if successfully added (or already present), -1 if unsuccessful
21 */
22 int register_cipher(const struct ltc_cipher_descriptor *cipher)
23 {
24 int x;
25
26 LTC_ARGCHK(cipher != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
32 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
33 return x;
34 }
35 }
36
37 /* find a blank spot */
38 for (x = 0; x < TAB_SIZE; x++) {
39 if (cipher_descriptor[x].name == NULL) {
40 XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor));
41 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
42 return x;
43 }
44 }
45
46 /* no spot */
47 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
48 return -1;
49 }
50
51 /* $Source$ */
52 /* $Revision$ */
53 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_register_hash.c
14 Register a HASH, Tom St Denis
15 */
16
17 /**
18 Register a hash with the descriptor table
19 @param hash The hash you wish to register
20 @return value >= 0 if successfully added (or already present), -1 if unsuccessful
21 */
22 int register_hash(const struct ltc_hash_descriptor *hash)
23 {
24 int x;
25
26 LTC_ARGCHK(hash != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_hash_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
32 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
33 return x;
34 }
35 }
36
37 /* find a blank spot */
38 for (x = 0; x < TAB_SIZE; x++) {
39 if (hash_descriptor[x].name == NULL) {
40 XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor));
41 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
42 return x;
43 }
44 }
45
46 /* no spot */
47 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
48 return -1;
49 }
50
51 /* $Source$ */
52 /* $Revision$ */
53 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_register_prng.c
14 Register a PRNG, Tom St Denis
15 */
16
17 /**
18 Register a PRNG with the descriptor table
19 @param prng The PRNG you wish to register
20 @return value >= 0 if successfully added (or already present), -1 if unsuccessful
21 */
22 int register_prng(const struct ltc_prng_descriptor *prng)
23 {
24 int x;
25
26 LTC_ARGCHK(prng != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_prng_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
32 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
33 return x;
34 }
35 }
36
37 /* find a blank spot */
38 for (x = 0; x < TAB_SIZE; x++) {
39 if (prng_descriptor[x].name == NULL) {
40 XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor));
41 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
42 return x;
43 }
44 }
45
46 /* no spot */
47 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
48 return -1;
49 }
50
51 /* $Source$ */
52 /* $Revision$ */
53 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_unregister_cipher.c
14 Unregister a cipher, Tom St Denis
15 */
16
17 /**
18 Unregister a cipher from the descriptor table
19 @param cipher The cipher descriptor to remove
20 @return CRYPT_OK on success
21 */
22 int unregister_cipher(const struct ltc_cipher_descriptor *cipher)
23 {
24 int x;
25
26 LTC_ARGCHK(cipher != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_cipher_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) {
32 cipher_descriptor[x].name = NULL;
33 cipher_descriptor[x].ID = 255;
34 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
35 return CRYPT_OK;
36 }
37 }
38 LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
39 return CRYPT_ERROR;
40 }
41
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_unregister_hash.c
14 Unregister a hash, Tom St Denis
15 */
16
17 /**
18 Unregister a hash from the descriptor table
19 @param hash The hash descriptor to remove
20 @return CRYPT_OK on success
21 */
22 int unregister_hash(const struct ltc_hash_descriptor *hash)
23 {
24 int x;
25
26 LTC_ARGCHK(hash != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_hash_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
32 hash_descriptor[x].name = NULL;
33 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
34 return CRYPT_OK;
35 }
36 }
37 LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
38 return CRYPT_ERROR;
39 }
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file crypt_unregister_prng.c
14 Unregister a PRNG, Tom St Denis
15 */
16
17 /**
18 Unregister a PRNG from the descriptor table
19 @param prng The PRNG descriptor to remove
20 @return CRYPT_OK on success
21 */
22 int unregister_prng(const struct ltc_prng_descriptor *prng)
23 {
24 int x;
25
26 LTC_ARGCHK(prng != NULL);
27
28 /* is it already registered? */
29 LTC_MUTEX_LOCK(&ltc_prng_mutex);
30 for (x = 0; x < TAB_SIZE; x++) {
31 if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) != 0) {
32 prng_descriptor[x].name = NULL;
33 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
34 return CRYPT_OK;
35 }
36 }
37 LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
38 return CRYPT_ERROR;
39 }
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 #include "tomcrypt.h"
12
13 /**
14 @file error_to_string.c
15 Convert error codes to ASCII strings, Tom St Denis
16 */
17
18 static const char *err_2_str[] =
19 {
20 "CRYPT_OK",
21 "CRYPT_ERROR",
22 "Non-fatal 'no-operation' requested.",
23
24 "Invalid keysize for block cipher.",
25 "Invalid number of rounds for block cipher.",
26 "Algorithm failed test vectors.",
27
28 "Buffer overflow.",
29 "Invalid input packet.",
30
31 "Invalid number of bits for a PRNG.",
32 "Error reading the PRNG.",
33
34 "Invalid cipher specified.",
35 "Invalid hash specified.",
36 "Invalid PRNG specified.",
37
38 "Out of memory.",
39
40 "Invalid PK key or key type specified for function.",
41 "A private PK key is required.",
42
43 "Invalid argument provided.",
44 "File Not Found",
45
46 "Invalid PK type.",
47 "Invalid PK system.",
48 "Duplicate PK key found on keyring.",
49 "Key not found in keyring.",
50 "Invalid sized parameter.",
51
52 "Invalid size for prime.",
53
54 };
55
56 /**
57 Convert an LTC error code to ASCII
58 @param err The error code
59 @return A pointer to the ASCII NUL terminated string for the error or "Invalid error code." if the err code was not valid.
60 */
61 const char *error_to_string(int err)
62 {
63 if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
64 return "Invalid error code.";
65 } else {
66 return err_2_str[err];
67 }
68 }
69
70
71 /* $Source$ */
72 /* $Revision$ */
73 /* $Date$ */
0 #include <assert.h>
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <tomcrypt.h>
5
6 #ifndef MIN
7 #define MIN(a,b) ((a)<(b))?(a):(b)
8 #endif
9
10 /* This is mostly just a wrapper around hmac_memory */
11 int hkdf_extract(int hash_idx, const unsigned char *salt, unsigned long saltlen,
12 const unsigned char *in, unsigned long inlen,
13 unsigned char *out, unsigned long *outlen)
14 {
15 /* libtomcrypt chokes on a zero length HMAC key, so we need to check for
16 that. HMAC specifies that keys shorter than the hash's blocksize are
17 0 padded to the block size. HKDF specifies that a NULL salt is to be
18 substituted with a salt comprised of hashLen 0 bytes. HMAC's padding
19 means that in either case the HMAC is actually using a blocksize long
20 zero filled key. Unless blocksize < hashLen (which wouldn't make any
21 sense), we can use a single 0 byte as the HMAC key and still generate
22 valid results for HKDF. */
23 if (salt == NULL || saltlen == 0) {
24 return hmac_memory(hash_idx, (const unsigned char *)"", 1, in, inlen, out, outlen);
25 } else {
26 return hmac_memory(hash_idx, salt, saltlen, in, inlen, out, outlen);
27 }
28 }
29
30 int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen,
31 const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long outlen)
33 {
34 unsigned long hashsize;
35 int err;
36 unsigned char N;
37 unsigned long Noutlen, outoff;
38
39 unsigned char *T, *dat;
40 unsigned long Tlen, datlen;
41
42 /* make sure hash descriptor is valid */
43 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
44 return err;
45 }
46
47 hashsize = hash_descriptor[hash_idx].hashsize;
48
49 /* RFC5869 parameter restrictions */
50 if (inlen < hashsize || outlen > hashsize * 255)
51 return CRYPT_INVALID_ARG;
52 if (info == NULL && infolen != 0)
53 return CRYPT_INVALID_ARG;
54 LTC_ARGCHK(out != NULL);
55
56 Tlen = hashsize + infolen + 1;
57 T = XMALLOC(Tlen); /* Replace with static buffer? */
58 if (T == NULL) {
59 return CRYPT_MEM;
60 }
61 XMEMCPY(T + hashsize, info, infolen);
62
63 /* HMAC data T(1) doesn't include a previous hash value */
64 dat = T + hashsize;
65 datlen = Tlen - hashsize;
66
67 N = 0;
68 outoff = 0; /* offset in out to write to */
69 while (1) { /* an exit condition breaks mid-loop */
70 Noutlen = MIN(hashsize, outlen - outoff);
71 T[Tlen - 1] = ++N;
72 if ((err = hmac_memory(hash_idx, in, inlen, dat, datlen,
73 out + outoff, &Noutlen)) != CRYPT_OK) {
74 zeromem(T, Tlen);
75 XFREE(T);
76 return err;
77 }
78 outoff += Noutlen;
79
80 if (outoff >= outlen) /* loop exit condition */
81 break;
82
83 /* All subsequent HMAC data T(N) DOES include the previous hash value */
84 XMEMCPY(T, out + hashsize * (N-1), hashsize);
85 if (N == 1) {
86 dat = T;
87 datlen = Tlen;
88 }
89 }
90 zeromem(T, Tlen);
91 XFREE(T);
92 return CRYPT_OK;
93 }
94
95 /* all in one step */
96 int hkdf(int hash_idx, const unsigned char *salt, unsigned long saltlen,
97 const unsigned char *info, unsigned long infolen,
98 const unsigned char *in, unsigned long inlen,
99 unsigned char *out, unsigned long outlen)
100 {
101 unsigned long hashsize;
102 int err;
103 unsigned char *extracted;
104
105 /* make sure hash descriptor is valid */
106 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
107 return err;
108 }
109
110 hashsize = hash_descriptor[hash_idx].hashsize;
111
112 extracted = XMALLOC(hashsize); /* replace with static buffer? */
113 if (extracted == NULL) {
114 return CRYPT_MEM;
115 }
116 if ((err = hkdf_extract(hash_idx, salt, saltlen, in, inlen, extracted, &hashsize)) != 0) {
117 zeromem(extracted, hashsize);
118 XFREE(extracted);
119 return err;
120 }
121 #if 0
122 {
123 int j;
124 printf("\nPRK: 0x");
125 for(j=0; j < hashsize; j++) {
126 printf("%02x ", extracted[j]);
127 }
128 for(j=0; j < hashsize; j++) {
129 printf("%02x ", extracted[j]);
130 }
131 }
132 #endif
133 err = hkdf_expand(hash_idx, info, infolen, extracted, hashsize, out, outlen);
134 zeromem(extracted, hashsize);
135 XFREE(extracted);
136 return err;
137 }
138
139
140 /* vim: set ts=2 sw=2 et ai si: */
0 /* LibTomCrypt, modular cryptographic library
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9 #include "tomcrypt.h"
10
11 static const oid_st rsa_oid = {
12 { 1, 2, 840, 113549, 1, 1, 1 },
13 7,
14 };
15
16 static const oid_st dsa_oid = {
17 { 1, 2, 840, 10040, 4, 1 },
18 6,
19 };
20
21 /*
22 Returns the OID of the public key algorithm.
23 @return CRYPT_OK if valid
24 */
25 int pk_get_oid(int pk, oid_st *st)
26 {
27 switch (pk) {
28 case PKA_RSA:
29 memcpy(st, &rsa_oid, sizeof(*st));
30 break;
31 case PKA_DSA:
32 memcpy(st, &dsa_oid, sizeof(*st));
33 break;
34 default:
35 return CRYPT_INVALID_ARG;
36 }
37 return CRYPT_OK;
38 }
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include <tomcrypt.h>
11
12 /**
13 @file pkcs_5_1.c
14 LTC_PKCS #5, Algorithm #1, Tom St Denis
15 */
16 #ifdef LTC_PKCS_5
17 /**
18 Execute LTC_PKCS #5 v1
19 @param password The password (or key)
20 @param password_len The length of the password (octet)
21 @param salt The salt (or nonce) which is 8 octets long
22 @param iteration_count The LTC_PKCS #5 v1 iteration count
23 @param hash_idx The index of the hash desired
24 @param out [out] The destination for this algorithm
25 @param outlen [in/out] The max size and resulting size of the algorithm output
26 @return CRYPT_OK if successful
27 */
28 int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
29 const unsigned char *salt,
30 int iteration_count, int hash_idx,
31 unsigned char *out, unsigned long *outlen)
32 {
33 int err;
34 unsigned long x;
35 hash_state *md;
36 unsigned char *buf;
37
38 LTC_ARGCHK(password != NULL);
39 LTC_ARGCHK(salt != NULL);
40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL);
42
43 /* test hash IDX */
44 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* allocate memory */
49 md = XMALLOC(sizeof(hash_state));
50 buf = XMALLOC(MAXBLOCKSIZE);
51 if (md == NULL || buf == NULL) {
52 if (md != NULL) {
53 XFREE(md);
54 }
55 if (buf != NULL) {
56 XFREE(buf);
57 }
58 return CRYPT_MEM;
59 }
60
61 /* hash initial password + salt */
62 if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
63 goto LBL_ERR;
64 }
65 if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) {
66 goto LBL_ERR;
67 }
68 if ((err = hash_descriptor[hash_idx].process(md, salt, 8)) != CRYPT_OK) {
69 goto LBL_ERR;
70 }
71 if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
72 goto LBL_ERR;
73 }
74
75 while (--iteration_count) {
76 /* code goes here. */
77 x = MAXBLOCKSIZE;
78 if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) {
79 goto LBL_ERR;
80 }
81 }
82
83 /* copy upto outlen bytes */
84 for (x = 0; x < hash_descriptor[hash_idx].hashsize && x < *outlen; x++) {
85 out[x] = buf[x];
86 }
87 *outlen = x;
88 err = CRYPT_OK;
89 LBL_ERR:
90 #ifdef LTC_CLEAN_STACK
91 zeromem(buf, MAXBLOCKSIZE);
92 zeromem(md, sizeof(hash_state));
93 #endif
94
95 XFREE(buf);
96 XFREE(md);
97
98 return err;
99 }
100
101 #endif
102
103 /* $Source$ */
104 /* $Revision$ */
105 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include <tomcrypt.h>
11
12 /**
13 @file pkcs_5_2.c
14 LTC_PKCS #5, Algorithm #2, Tom St Denis
15 */
16 #ifdef LTC_PKCS_5
17
18 /**
19 Execute LTC_PKCS #5 v2
20 @param password The input password (or key)
21 @param password_len The length of the password (octets)
22 @param salt The salt (or nonce)
23 @param salt_len The length of the salt (octets)
24 @param iteration_count # of iterations desired for LTC_PKCS #5 v2 [read specs for more]
25 @param hash_idx The index of the hash desired
26 @param out [out] The destination for this algorithm
27 @param outlen [in/out] The max size and resulting size of the algorithm output
28 @return CRYPT_OK if successful
29 */
30 int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
31 const unsigned char *salt, unsigned long salt_len,
32 int iteration_count, int hash_idx,
33 unsigned char *out, unsigned long *outlen)
34 {
35 int err, itts;
36 ulong32 blkno;
37 unsigned long stored, left, x, y;
38 unsigned char *buf[2];
39 hmac_state *hmac;
40
41 LTC_ARGCHK(password != NULL);
42 LTC_ARGCHK(salt != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45
46 /* test hash IDX */
47 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
48 return err;
49 }
50
51 buf[0] = XMALLOC(MAXBLOCKSIZE * 2);
52 hmac = XMALLOC(sizeof(hmac_state));
53 if (hmac == NULL || buf[0] == NULL) {
54 if (hmac != NULL) {
55 XFREE(hmac);
56 }
57 if (buf[0] != NULL) {
58 XFREE(buf[0]);
59 }
60 return CRYPT_MEM;
61 }
62 /* buf[1] points to the second block of MAXBLOCKSIZE bytes */
63 buf[1] = buf[0] + MAXBLOCKSIZE;
64
65 left = *outlen;
66 blkno = 1;
67 stored = 0;
68 while (left != 0) {
69 /* process block number blkno */
70 zeromem(buf[0], MAXBLOCKSIZE*2);
71
72 /* store current block number and increment for next pass */
73 STORE32H(blkno, buf[1]);
74 ++blkno;
75
76 /* get PRF(P, S||int(blkno)) */
77 if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80 if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {
81 goto LBL_ERR;
82 }
83 if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {
84 goto LBL_ERR;
85 }
86 x = MAXBLOCKSIZE;
87 if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {
88 goto LBL_ERR;
89 }
90
91 /* now compute repeated and XOR it in buf[1] */
92 XMEMCPY(buf[1], buf[0], x);
93 for (itts = 1; itts < iteration_count; ++itts) {
94 if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {
95 goto LBL_ERR;
96 }
97 for (y = 0; y < x; y++) {
98 buf[1][y] ^= buf[0][y];
99 }
100 }
101
102 /* now emit upto x bytes of buf[1] to output */
103 for (y = 0; y < x && left != 0; ++y) {
104 out[stored++] = buf[1][y];
105 --left;
106 }
107 }
108 *outlen = stored;
109
110 err = CRYPT_OK;
111 LBL_ERR:
112 #ifdef LTC_CLEAN_STACK
113 zeromem(buf[0], MAXBLOCKSIZE*2);
114 zeromem(hmac, sizeof(hmac_state));
115 #endif
116
117 XFREE(hmac);
118 XFREE(buf[0]);
119
120 return err;
121 }
122
123 #endif
124
125
126 /* $Source$ */
127 /* $Revision$ */
128 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file zeromem.c
14 Zero a block of memory, Tom St Denis
15 */
16
17 /**
18 Zero a block of memory
19 @param out The destination of the area to zero
20 @param outlen The length of the area to zero (octets)
21 */
22 void zeromem(volatile void *out, size_t outlen)
23 {
24 volatile char *mem = out;
25 LTC_ARGCHKVD(out != NULL);
26 while (outlen-- > 0) {
27 *mem++ = '\0';
28 }
29 }
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_decrypt.c
14 CBC implementation, encrypt block, Tom St Denis
15 */
16
17
18 #ifdef LTC_CBC_MODE
19
20 /**
21 CBC decrypt
22 @param ct Ciphertext
23 @param pt [out] Plaintext
24 @param len The number of bytes to process (must be multiple of block length)
25 @param cbc CBC state
26 @return CRYPT_OK if successful
27 */
28 int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc)
29 {
30 int x, err;
31 unsigned char tmp[16];
32 #ifdef LTC_FAST
33 LTC_FAST_TYPE tmpy;
34 #else
35 unsigned char tmpy;
36 #endif
37
38 LTC_ARGCHK(pt != NULL);
39 LTC_ARGCHK(ct != NULL);
40 LTC_ARGCHK(cbc != NULL);
41
42 if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
43 return err;
44 }
45
46 /* is blocklen valid? */
47 if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
48 return CRYPT_INVALID_ARG;
49 }
50
51 if (len % cbc->blocklen) {
52 return CRYPT_INVALID_ARG;
53 }
54 #ifdef LTC_FAST
55 if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
56 return CRYPT_INVALID_ARG;
57 }
58 #endif
59
60 if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
61 return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
62 } else {
63 while (len) {
64 /* decrypt */
65 if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
66 return err;
67 }
68
69 /* xor IV against plaintext */
70 #if defined(LTC_FAST)
71 for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
72 tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x));
73 *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
74 *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy;
75 }
76 #else
77 for (x = 0; x < cbc->blocklen; x++) {
78 tmpy = tmp[x] ^ cbc->IV[x];
79 cbc->IV[x] = ct[x];
80 pt[x] = tmpy;
81 }
82 #endif
83
84 ct += cbc->blocklen;
85 pt += cbc->blocklen;
86 len -= cbc->blocklen;
87 }
88 }
89 return CRYPT_OK;
90 }
91
92 #endif
93
94 /* $Source$ */
95 /* $Revision$ */
96 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_done.c
14 CBC implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_CBC_MODE
18
19 /** Terminate the chain
20 @param cbc The CBC chain to terminate
21 @return CRYPT_OK on success
22 */
23 int cbc_done(symmetric_CBC *cbc)
24 {
25 int err;
26 LTC_ARGCHK(cbc != NULL);
27
28 if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[cbc->cipher].done(&cbc->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_encrypt.c
14 CBC implementation, encrypt block, Tom St Denis
15 */
16
17
18 #ifdef LTC_CBC_MODE
19
20 /**
21 CBC encrypt
22 @param pt Plaintext
23 @param ct [out] Ciphertext
24 @param len The number of bytes to process (must be multiple of block length)
25 @param cbc CBC state
26 @return CRYPT_OK if successful
27 */
28 int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc)
29 {
30 int x, err;
31
32 LTC_ARGCHK(pt != NULL);
33 LTC_ARGCHK(ct != NULL);
34 LTC_ARGCHK(cbc != NULL);
35
36 if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 /* is blocklen valid? */
41 if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 if (len % cbc->blocklen) {
46 return CRYPT_INVALID_ARG;
47 }
48 #ifdef LTC_FAST
49 if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
50 return CRYPT_INVALID_ARG;
51 }
52 #endif
53
54 if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
55 return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
56 } else {
57 while (len) {
58 /* xor IV against plaintext */
59 #if defined(LTC_FAST)
60 for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
61 *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x));
62 }
63 #else
64 for (x = 0; x < cbc->blocklen; x++) {
65 cbc->IV[x] ^= pt[x];
66 }
67 #endif
68
69 /* encrypt */
70 if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
71 return err;
72 }
73
74 /* store IV [ciphertext] for a future block */
75 #if defined(LTC_FAST)
76 for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
77 *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
78 }
79 #else
80 for (x = 0; x < cbc->blocklen; x++) {
81 cbc->IV[x] = ct[x];
82 }
83 #endif
84
85 ct += cbc->blocklen;
86 pt += cbc->blocklen;
87 len -= cbc->blocklen;
88 }
89 }
90 return CRYPT_OK;
91 }
92
93 #endif
94
95 /* $Source$ */
96 /* $Revision$ */
97 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_getiv.c
14 CBC implementation, get IV, Tom St Denis
15 */
16
17 #ifdef LTC_CBC_MODE
18
19 /**
20 Get the current initial vector
21 @param IV [out] The destination of the initial vector
22 @param len [in/out] The max size and resulting size of the initial vector
23 @param cbc The CBC state
24 @return CRYPT_OK if successful
25 */
26 int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc)
27 {
28 LTC_ARGCHK(IV != NULL);
29 LTC_ARGCHK(len != NULL);
30 LTC_ARGCHK(cbc != NULL);
31 if ((unsigned long)cbc->blocklen > *len) {
32 *len = cbc->blocklen;
33 return CRYPT_BUFFER_OVERFLOW;
34 }
35 XMEMCPY(IV, cbc->IV, cbc->blocklen);
36 *len = cbc->blocklen;
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_setiv.c
14 CBC implementation, set IV, Tom St Denis
15 */
16
17
18 #ifdef LTC_CBC_MODE
19
20 /**
21 Set an initial vector
22 @param IV The initial vector
23 @param len The length of the vector (in octets)
24 @param cbc The CBC state
25 @return CRYPT_OK if successful
26 */
27 int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc)
28 {
29 LTC_ARGCHK(IV != NULL);
30 LTC_ARGCHK(cbc != NULL);
31 if (len != (unsigned long)cbc->blocklen) {
32 return CRYPT_INVALID_ARG;
33 }
34 XMEMCPY(cbc->IV, IV, len);
35 return CRYPT_OK;
36 }
37
38 #endif
39
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cbc_start.c
14 CBC implementation, start chain, Tom St Denis
15 */
16
17 #ifdef LTC_CBC_MODE
18
19 /**
20 Initialize a CBC context
21 @param cipher The index of the cipher desired
22 @param IV The initial vector
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param num_rounds Number of rounds in the cipher desired (0 for default)
26 @param cbc The CBC state to initialize
27 @return CRYPT_OK if successful
28 */
29 int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
30 int keylen, int num_rounds, symmetric_CBC *cbc)
31 {
32 int x, err;
33
34 LTC_ARGCHK(IV != NULL);
35 LTC_ARGCHK(key != NULL);
36 LTC_ARGCHK(cbc != NULL);
37
38 /* bad param? */
39 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* setup cipher */
44 if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* copy IV */
49 cbc->blocklen = cipher_descriptor[cipher].block_length;
50 cbc->cipher = cipher;
51 for (x = 0; x < cbc->blocklen; x++) {
52 cbc->IV[x] = IV[x];
53 }
54 return CRYPT_OK;
55 }
56
57 #endif
58
59 /* $Source$ */
60 /* $Revision$ */
61 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_decrypt.c
14 CFB implementation, decrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /**
20 CFB decrypt
21 @param ct Ciphertext
22 @param pt [out] Plaintext
23 @param len Length of ciphertext (octets)
24 @param cfb CFB state
25 @return CRYPT_OK if successful
26 */
27 int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb)
28 {
29 int err;
30
31 LTC_ARGCHK(pt != NULL);
32 LTC_ARGCHK(ct != NULL);
33 LTC_ARGCHK(cfb != NULL);
34
35 if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
36 return err;
37 }
38
39 /* is blocklen/padlen valid? */
40 if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) ||
41 cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 while (len-- > 0) {
46 if (cfb->padlen == cfb->blocklen) {
47 if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
48 return err;
49 }
50 cfb->padlen = 0;
51 }
52 cfb->pad[cfb->padlen] = *ct;
53 *pt = *ct ^ cfb->IV[cfb->padlen];
54 ++pt;
55 ++ct;
56 ++(cfb->padlen);
57 }
58 return CRYPT_OK;
59 }
60
61 #endif
62
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_done.c
14 CFB implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /** Terminate the chain
20 @param cfb The CFB chain to terminate
21 @return CRYPT_OK on success
22 */
23 int cfb_done(symmetric_CFB *cfb)
24 {
25 int err;
26 LTC_ARGCHK(cfb != NULL);
27
28 if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[cfb->cipher].done(&cfb->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_encrypt.c
14 CFB implementation, encrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /**
20 CFB encrypt
21 @param pt Plaintext
22 @param ct [out] Ciphertext
23 @param len Length of plaintext (octets)
24 @param cfb CFB state
25 @return CRYPT_OK if successful
26 */
27 int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb)
28 {
29 int err;
30
31 LTC_ARGCHK(pt != NULL);
32 LTC_ARGCHK(ct != NULL);
33 LTC_ARGCHK(cfb != NULL);
34
35 if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
36 return err;
37 }
38
39 /* is blocklen/padlen valid? */
40 if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) ||
41 cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 while (len-- > 0) {
46 if (cfb->padlen == cfb->blocklen) {
47 if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
48 return err;
49 }
50 cfb->padlen = 0;
51 }
52 cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
53 ++pt;
54 ++ct;
55 ++(cfb->padlen);
56 }
57 return CRYPT_OK;
58 }
59
60 #endif
61
62 /* $Source$ */
63 /* $Revision$ */
64 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_getiv.c
14 CFB implementation, get IV, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /**
20 Get the current initial vector
21 @param IV [out] The destination of the initial vector
22 @param len [in/out] The max size and resulting size of the initial vector
23 @param cfb The CFB state
24 @return CRYPT_OK if successful
25 */
26 int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb)
27 {
28 LTC_ARGCHK(IV != NULL);
29 LTC_ARGCHK(len != NULL);
30 LTC_ARGCHK(cfb != NULL);
31 if ((unsigned long)cfb->blocklen > *len) {
32 *len = cfb->blocklen;
33 return CRYPT_BUFFER_OVERFLOW;
34 }
35 XMEMCPY(IV, cfb->IV, cfb->blocklen);
36 *len = cfb->blocklen;
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_setiv.c
14 CFB implementation, set IV, Tom St Denis
15 */
16
17 #ifdef LTC_CFB_MODE
18
19 /**
20 Set an initial vector
21 @param IV The initial vector
22 @param len The length of the vector (in octets)
23 @param cfb The CFB state
24 @return CRYPT_OK if successful
25 */
26 int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
27 {
28 int err;
29
30 LTC_ARGCHK(IV != NULL);
31 LTC_ARGCHK(cfb != NULL);
32
33 if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36
37 if (len != (unsigned long)cfb->blocklen) {
38 return CRYPT_INVALID_ARG;
39 }
40
41 /* force next block */
42 cfb->padlen = 0;
43 return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
44 }
45
46 #endif
47
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file cfb_start.c
14 CFB implementation, start chain, Tom St Denis
15 */
16
17
18 #ifdef LTC_CFB_MODE
19
20 /**
21 Initialize a CFB context
22 @param cipher The index of the cipher desired
23 @param IV The initial vector
24 @param key The secret key
25 @param keylen The length of the secret key (octets)
26 @param num_rounds Number of rounds in the cipher desired (0 for default)
27 @param cfb The CFB state to initialize
28 @return CRYPT_OK if successful
29 */
30 int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
31 int keylen, int num_rounds, symmetric_CFB *cfb)
32 {
33 int x, err;
34
35 LTC_ARGCHK(IV != NULL);
36 LTC_ARGCHK(key != NULL);
37 LTC_ARGCHK(cfb != NULL);
38
39 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
40 return err;
41 }
42
43
44 /* copy data */
45 cfb->cipher = cipher;
46 cfb->blocklen = cipher_descriptor[cipher].block_length;
47 for (x = 0; x < cfb->blocklen; x++)
48 cfb->IV[x] = IV[x];
49
50 /* init the cipher */
51 if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) {
52 return err;
53 }
54
55 /* encrypt the IV */
56 cfb->padlen = 0;
57 return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
58 }
59
60 #endif
61
62 /* $Source$ */
63 /* $Revision$ */
64 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_decrypt.c
14 CTR implementation, decrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_CTR_MODE
18
19 /**
20 CTR decrypt
21 @param ct Ciphertext
22 @param pt [out] Plaintext
23 @param len Length of ciphertext (octets)
24 @param ctr CTR state
25 @return CRYPT_OK if successful
26 */
27 int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr)
28 {
29 LTC_ARGCHK(pt != NULL);
30 LTC_ARGCHK(ct != NULL);
31 LTC_ARGCHK(ctr != NULL);
32
33 return ctr_encrypt(ct, pt, len, ctr);
34 }
35
36 #endif
37
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_done.c
14 CTR implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_CTR_MODE
18
19 /** Terminate the chain
20 @param ctr The CTR chain to terminate
21 @return CRYPT_OK on success
22 */
23 int ctr_done(symmetric_CTR *ctr)
24 {
25 int err;
26 LTC_ARGCHK(ctr != NULL);
27
28 if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[ctr->cipher].done(&ctr->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_encrypt.c
14 CTR implementation, encrypt data, Tom St Denis
15 */
16
17
18 #ifdef LTC_CTR_MODE
19
20 /**
21 CTR encrypt
22 @param pt Plaintext
23 @param ct [out] Ciphertext
24 @param len Length of plaintext (octets)
25 @param ctr CTR state
26 @return CRYPT_OK if successful
27 */
28 int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
29 {
30 int x, err;
31
32 LTC_ARGCHK(pt != NULL);
33 LTC_ARGCHK(ct != NULL);
34 LTC_ARGCHK(ctr != NULL);
35
36 if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 /* is blocklen/padlen valid? */
41 if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) ||
42 ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) {
43 return CRYPT_INVALID_ARG;
44 }
45
46 #ifdef LTC_FAST
47 if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
48 return CRYPT_INVALID_ARG;
49 }
50 #endif
51
52 /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
53 if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
54 if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
55 return err;
56 }
57 len %= ctr->blocklen;
58 }
59
60 while (len) {
61 /* is the pad empty? */
62 if (ctr->padlen == ctr->blocklen) {
63 /* increment counter */
64 if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
65 /* little-endian */
66 for (x = 0; x < ctr->ctrlen; x++) {
67 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
68 if (ctr->ctr[x] != (unsigned char)0) {
69 break;
70 }
71 }
72 } else {
73 /* big-endian */
74 for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
75 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
76 if (ctr->ctr[x] != (unsigned char)0) {
77 break;
78 }
79 }
80 }
81
82 /* encrypt it */
83 if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
84 return err;
85 }
86 ctr->padlen = 0;
87 }
88 #ifdef LTC_FAST
89 if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) {
90 for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
91 *((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^
92 *((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x));
93 }
94 pt += ctr->blocklen;
95 ct += ctr->blocklen;
96 len -= ctr->blocklen;
97 ctr->padlen = ctr->blocklen;
98 continue;
99 }
100 #endif
101 *ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
102 --len;
103 }
104 return CRYPT_OK;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_getiv.c
14 CTR implementation, get IV, Tom St Denis
15 */
16
17 #ifdef LTC_CTR_MODE
18
19 /**
20 Get the current initial vector
21 @param IV [out] The destination of the initial vector
22 @param len [in/out] The max size and resulting size of the initial vector
23 @param ctr The CTR state
24 @return CRYPT_OK if successful
25 */
26 int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr)
27 {
28 LTC_ARGCHK(IV != NULL);
29 LTC_ARGCHK(len != NULL);
30 LTC_ARGCHK(ctr != NULL);
31 if ((unsigned long)ctr->blocklen > *len) {
32 *len = ctr->blocklen;
33 return CRYPT_BUFFER_OVERFLOW;
34 }
35 XMEMCPY(IV, ctr->ctr, ctr->blocklen);
36 *len = ctr->blocklen;
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_setiv.c
14 CTR implementation, set IV, Tom St Denis
15 */
16
17 #ifdef LTC_CTR_MODE
18
19 /**
20 Set an initial vector
21 @param IV The initial vector
22 @param len The length of the vector (in octets)
23 @param ctr The CTR state
24 @return CRYPT_OK if successful
25 */
26 int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
27 {
28 int err;
29
30 LTC_ARGCHK(IV != NULL);
31 LTC_ARGCHK(ctr != NULL);
32
33 /* bad param? */
34 if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
35 return err;
36 }
37
38 if (len != (unsigned long)ctr->blocklen) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 /* set IV */
43 XMEMCPY(ctr->ctr, IV, len);
44
45 /* force next block */
46 ctr->padlen = 0;
47 return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
48 }
49
50 #endif
51
52
53 /* $Source$ */
54 /* $Revision$ */
55 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ctr_start.c
14 CTR implementation, start chain, Tom St Denis
15 */
16
17
18 #ifdef LTC_CTR_MODE
19
20 /**
21 Initialize a CTR context
22 @param cipher The index of the cipher desired
23 @param IV The initial vector
24 @param key The secret key
25 @param keylen The length of the secret key (octets)
26 @param num_rounds Number of rounds in the cipher desired (0 for default)
27 @param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN)
28 @param ctr The CTR state to initialize
29 @return CRYPT_OK if successful
30 */
31 int ctr_start( int cipher,
32 const unsigned char *IV,
33 const unsigned char *key, int keylen,
34 int num_rounds, int ctr_mode,
35 symmetric_CTR *ctr)
36 {
37 int x, err;
38
39 LTC_ARGCHK(IV != NULL);
40 LTC_ARGCHK(key != NULL);
41 LTC_ARGCHK(ctr != NULL);
42
43 /* bad param? */
44 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
45 return err;
46 }
47
48 /* ctrlen == counter width */
49 ctr->ctrlen = (ctr_mode & 255) ? (ctr_mode & 255) : cipher_descriptor[cipher].block_length;
50 if (ctr->ctrlen > cipher_descriptor[cipher].block_length) {
51 return CRYPT_INVALID_ARG;
52 }
53
54 if ((ctr_mode & 0x1000) == CTR_COUNTER_BIG_ENDIAN) {
55 ctr->ctrlen = cipher_descriptor[cipher].block_length - ctr->ctrlen;
56 }
57
58 /* setup cipher */
59 if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) {
60 return err;
61 }
62
63 /* copy ctr */
64 ctr->blocklen = cipher_descriptor[cipher].block_length;
65 ctr->cipher = cipher;
66 ctr->padlen = 0;
67 ctr->mode = ctr_mode & 0x1000;
68 for (x = 0; x < ctr->blocklen; x++) {
69 ctr->ctr[x] = IV[x];
70 }
71
72 if (ctr_mode & LTC_CTR_RFC3686) {
73 /* increment the IV as per RFC 3686 */
74 if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
75 /* little-endian */
76 for (x = 0; x < ctr->ctrlen; x++) {
77 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
78 if (ctr->ctr[x] != (unsigned char)0) {
79 break;
80 }
81 }
82 } else {
83 /* big-endian */
84 for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
85 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
86 if (ctr->ctr[x] != (unsigned char)0) {
87 break;
88 }
89 }
90 }
91 }
92
93 return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
94 }
95
96 #endif
97
98 /* $Source$ */
99 /* $Revision$ */
100 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ecb_decrypt.c
14 ECB implementation, decrypt a block, Tom St Denis
15 */
16
17 #ifdef LTC_ECB_MODE
18
19 /**
20 ECB decrypt
21 @param ct Ciphertext
22 @param pt [out] Plaintext
23 @param len The number of octets to process (must be multiple of the cipher block size)
24 @param ecb ECB state
25 @return CRYPT_OK if successful
26 */
27 int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb)
28 {
29 int err;
30 LTC_ARGCHK(pt != NULL);
31 LTC_ARGCHK(ct != NULL);
32 LTC_ARGCHK(ecb != NULL);
33 if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36 if (len % cipher_descriptor[ecb->cipher].block_length) {
37 return CRYPT_INVALID_ARG;
38 }
39
40 /* check for accel */
41 if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) {
42 return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
43 } else {
44 while (len) {
45 if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) {
46 return err;
47 }
48 pt += cipher_descriptor[ecb->cipher].block_length;
49 ct += cipher_descriptor[ecb->cipher].block_length;
50 len -= cipher_descriptor[ecb->cipher].block_length;
51 }
52 }
53 return CRYPT_OK;
54 }
55
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ecb_done.c
14 ECB implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_ECB_MODE
18
19 /** Terminate the chain
20 @param ecb The ECB chain to terminate
21 @return CRYPT_OK on success
22 */
23 int ecb_done(symmetric_ECB *ecb)
24 {
25 int err;
26 LTC_ARGCHK(ecb != NULL);
27
28 if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[ecb->cipher].done(&ecb->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ecb_encrypt.c
14 ECB implementation, encrypt a block, Tom St Denis
15 */
16
17 #ifdef LTC_ECB_MODE
18
19 /**
20 ECB encrypt
21 @param pt Plaintext
22 @param ct [out] Ciphertext
23 @param len The number of octets to process (must be multiple of the cipher block size)
24 @param ecb ECB state
25 @return CRYPT_OK if successful
26 */
27 int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb)
28 {
29 int err;
30 LTC_ARGCHK(pt != NULL);
31 LTC_ARGCHK(ct != NULL);
32 LTC_ARGCHK(ecb != NULL);
33 if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36 if (len % cipher_descriptor[ecb->cipher].block_length) {
37 return CRYPT_INVALID_ARG;
38 }
39
40 /* check for accel */
41 if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) {
42 return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
43 } else {
44 while (len) {
45 if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) {
46 return err;
47 }
48 pt += cipher_descriptor[ecb->cipher].block_length;
49 ct += cipher_descriptor[ecb->cipher].block_length;
50 len -= cipher_descriptor[ecb->cipher].block_length;
51 }
52 }
53 return CRYPT_OK;
54 }
55
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ecb_start.c
14 ECB implementation, start chain, Tom St Denis
15 */
16
17
18 #ifdef LTC_ECB_MODE
19
20 /**
21 Initialize a ECB context
22 @param cipher The index of the cipher desired
23 @param key The secret key
24 @param keylen The length of the secret key (octets)
25 @param num_rounds Number of rounds in the cipher desired (0 for default)
26 @param ecb The ECB state to initialize
27 @return CRYPT_OK if successful
28 */
29 int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb)
30 {
31 int err;
32 LTC_ARGCHK(key != NULL);
33 LTC_ARGCHK(ecb != NULL);
34
35 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
36 return err;
37 }
38 ecb->cipher = cipher;
39 ecb->blocklen = cipher_descriptor[cipher].block_length;
40 return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key);
41 }
42
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_decrypt.c
14 OFB implementation, decrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /**
20 OFB decrypt
21 @param ct Ciphertext
22 @param pt [out] Plaintext
23 @param len Length of ciphertext (octets)
24 @param ofb OFB state
25 @return CRYPT_OK if successful
26 */
27 int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb)
28 {
29 LTC_ARGCHK(pt != NULL);
30 LTC_ARGCHK(ct != NULL);
31 LTC_ARGCHK(ofb != NULL);
32 return ofb_encrypt(ct, pt, len, ofb);
33 }
34
35
36 #endif
37
38
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_done.c
14 OFB implementation, finish chain, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /** Terminate the chain
20 @param ofb The OFB chain to terminate
21 @return CRYPT_OK on success
22 */
23 int ofb_done(symmetric_OFB *ofb)
24 {
25 int err;
26 LTC_ARGCHK(ofb != NULL);
27
28 if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
29 return err;
30 }
31 cipher_descriptor[ofb->cipher].done(&ofb->key);
32 return CRYPT_OK;
33 }
34
35
36
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_encrypt.c
14 OFB implementation, encrypt data, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /**
20 OFB encrypt
21 @param pt Plaintext
22 @param ct [out] Ciphertext
23 @param len Length of plaintext (octets)
24 @param ofb OFB state
25 @return CRYPT_OK if successful
26 */
27 int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb)
28 {
29 int err;
30 LTC_ARGCHK(pt != NULL);
31 LTC_ARGCHK(ct != NULL);
32 LTC_ARGCHK(ofb != NULL);
33 if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36
37 /* is blocklen/padlen valid? */
38 if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) ||
39 ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) {
40 return CRYPT_INVALID_ARG;
41 }
42
43 while (len-- > 0) {
44 if (ofb->padlen == ofb->blocklen) {
45 if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) {
46 return err;
47 }
48 ofb->padlen = 0;
49 }
50 *ct++ = *pt++ ^ ofb->IV[(ofb->padlen)++];
51 }
52 return CRYPT_OK;
53 }
54
55 #endif
56
57 /* $Source$ */
58 /* $Revision$ */
59 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_getiv.c
14 OFB implementation, get IV, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /**
20 Get the current initial vector
21 @param IV [out] The destination of the initial vector
22 @param len [in/out] The max size and resulting size of the initial vector
23 @param ofb The OFB state
24 @return CRYPT_OK if successful
25 */
26 int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb)
27 {
28 LTC_ARGCHK(IV != NULL);
29 LTC_ARGCHK(len != NULL);
30 LTC_ARGCHK(ofb != NULL);
31 if ((unsigned long)ofb->blocklen > *len) {
32 *len = ofb->blocklen;
33 return CRYPT_BUFFER_OVERFLOW;
34 }
35 XMEMCPY(IV, ofb->IV, ofb->blocklen);
36 *len = ofb->blocklen;
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_setiv.c
14 OFB implementation, set IV, Tom St Denis
15 */
16
17 #ifdef LTC_OFB_MODE
18
19 /**
20 Set an initial vector
21 @param IV The initial vector
22 @param len The length of the vector (in octets)
23 @param ofb The OFB state
24 @return CRYPT_OK if successful
25 */
26 int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
27 {
28 int err;
29
30 LTC_ARGCHK(IV != NULL);
31 LTC_ARGCHK(ofb != NULL);
32
33 if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
34 return err;
35 }
36
37 if (len != (unsigned long)ofb->blocklen) {
38 return CRYPT_INVALID_ARG;
39 }
40
41 /* force next block */
42 ofb->padlen = 0;
43 return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
44 }
45
46 #endif
47
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file ofb_start.c
14 OFB implementation, start chain, Tom St Denis
15 */
16
17
18 #ifdef LTC_OFB_MODE
19
20 /**
21 Initialize a OFB context
22 @param cipher The index of the cipher desired
23 @param IV The initial vector
24 @param key The secret key
25 @param keylen The length of the secret key (octets)
26 @param num_rounds Number of rounds in the cipher desired (0 for default)
27 @param ofb The OFB state to initialize
28 @return CRYPT_OK if successful
29 */
30 int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
31 int keylen, int num_rounds, symmetric_OFB *ofb)
32 {
33 int x, err;
34
35 LTC_ARGCHK(IV != NULL);
36 LTC_ARGCHK(key != NULL);
37 LTC_ARGCHK(ofb != NULL);
38
39 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* copy details */
44 ofb->cipher = cipher;
45 ofb->blocklen = cipher_descriptor[cipher].block_length;
46 for (x = 0; x < ofb->blocklen; x++) {
47 ofb->IV[x] = IV[x];
48 }
49
50 /* init the cipher */
51 ofb->padlen = ofb->blocklen;
52 return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key);
53 }
54
55 #endif
56
57 /* $Source$ */
58 /* $Revision$ */
59 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_bit_string.c
14 ASN.1 DER, encode a BIT STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a BIT STRING
22 @param in The DER encoded BIT STRING
23 @param inlen The size of the DER BIT STRING
24 @param out [out] The array of bits stored (one per char)
25 @param outlen [in/out] The number of bits stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long dlen, blen, x, y;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* packet must be at least 4 bytes */
38 if (inlen < 4) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 /* check for 0x03 */
43 if ((in[0]&0x1F) != 0x03) {
44 return CRYPT_INVALID_PACKET;
45 }
46
47 /* offset in the data */
48 x = 1;
49
50 /* get the length of the data */
51 if (in[x] & 0x80) {
52 /* long format get number of length bytes */
53 y = in[x++] & 0x7F;
54
55 /* invalid if 0 or > 2 */
56 if (y == 0 || y > 2) {
57 return CRYPT_INVALID_PACKET;
58 }
59
60 /* read the data len */
61 dlen = 0;
62 while (y--) {
63 dlen = (dlen << 8) | (unsigned long)in[x++];
64 }
65 } else {
66 /* short format */
67 dlen = in[x++] & 0x7F;
68 }
69
70 /* is the data len too long or too short? */
71 if ((dlen == 0) || (dlen + x > inlen)) {
72 return CRYPT_INVALID_PACKET;
73 }
74
75 /* get padding count */
76 blen = ((dlen - 1) << 3) - (in[x++] & 7);
77
78 /* too many bits? */
79 if (blen > *outlen) {
80 *outlen = blen;
81 return CRYPT_BUFFER_OVERFLOW;
82 }
83
84 /* decode/store the bits */
85 for (y = 0; y < blen; y++) {
86 out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0;
87 if ((y & 7) == 7) {
88 ++x;
89 }
90 }
91
92 /* we done */
93 *outlen = blen;
94 return CRYPT_OK;
95 }
96
97 #endif
98
99 /* $Source$ */
100 /* $Revision$ */
101 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_bit_string.c
14 ASN.1 DER, encode a BIT STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 #define setbit(v, n) (v=((unsigned char)(v) | (1U << (unsigned char)(n))))
21
22 /**
23 Store a BIT STRING
24 @param in The DER encoded BIT STRING
25 @param inlen The size of the DER BIT STRING
26 @param out [out] The array of bits stored (8 per char)
27 @param outlen [in/out] The number of bits stored
28 @return CRYPT_OK if successful
29 */
30 int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
31 unsigned char *out, unsigned long *outlen)
32 {
33 unsigned long dlen, blen, x, y;
34
35 LTC_ARGCHK(in != NULL);
36 LTC_ARGCHK(out != NULL);
37 LTC_ARGCHK(outlen != NULL);
38
39 /* packet must be at least 4 bytes */
40 if (inlen < 4) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 /* check for 0x03 */
45 if ((in[0]&0x1F) != 0x03) {
46 return CRYPT_INVALID_PACKET;
47 }
48
49 /* offset in the data */
50 x = 1;
51
52 /* get the length of the data */
53 if (in[x] & 0x80) {
54 /* long format get number of length bytes */
55 y = in[x++] & 0x7F;
56
57 /* invalid if 0 or > 2 */
58 if (y == 0 || y > 2) {
59 return CRYPT_INVALID_PACKET;
60 }
61
62 /* read the data len */
63 dlen = 0;
64 while (y--) {
65 dlen = (dlen << 8) | (unsigned long)in[x++];
66 }
67 } else {
68 /* short format */
69 dlen = in[x++] & 0x7F;
70 }
71
72 /* is the data len too long or too short? */
73 if ((dlen == 0) || (dlen + x > inlen)) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* get padding count */
78 blen = ((dlen - 1) << 3) - (in[x++] & 7);
79
80 /* too many bits? */
81 if (blen > *outlen) {
82 *outlen = blen;
83 return CRYPT_BUFFER_OVERFLOW;
84 }
85
86 /* decode/store the bits */
87 for (y = 0; y < blen; y++) {
88 if (in[x] & (1 << (7 - (y & 7)))) {
89 setbit(out[y/8], 7-(y%8));
90 }
91 if ((y & 7) == 7) {
92 ++x;
93 }
94 }
95
96 /* we done */
97 *outlen = blen;
98 return CRYPT_OK;
99 }
100
101 #endif
102
103 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */
104 /* $Revision: 1.5 $ */
105 /* $Date: 2006/12/28 01:27:24 $ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_bit_string.c
14 ASN.1 DER, encode a BIT STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a BIT STRING
22 @param in The array of bits to store (one per char)
23 @param inlen The number of bits tostore
24 @param out [out] The destination for the DER encoded BIT STRING
25 @param outlen [in/out] The max size and resulting size of the DER BIT STRING
26 @return CRYPT_OK if successful
27 */
28 int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long len, x, y;
32 unsigned char buf;
33 int err;
34
35 LTC_ARGCHK(in != NULL);
36 LTC_ARGCHK(out != NULL);
37 LTC_ARGCHK(outlen != NULL);
38
39 /* avoid overflows */
40 if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) {
41 return err;
42 }
43
44 if (len > *outlen) {
45 *outlen = len;
46 return CRYPT_BUFFER_OVERFLOW;
47 }
48
49 /* store header (include bit padding count in length) */
50 x = 0;
51 y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
52
53 out[x++] = 0x03;
54 if (y < 128) {
55 out[x++] = (unsigned char)y;
56 } else if (y < 256) {
57 out[x++] = 0x81;
58 out[x++] = (unsigned char)y;
59 } else if (y < 65536) {
60 out[x++] = 0x82;
61 out[x++] = (unsigned char)((y>>8)&255);
62 out[x++] = (unsigned char)(y&255);
63 }
64
65 /* store number of zero padding bits */
66 out[x++] = (unsigned char)((8 - inlen) & 7);
67
68 /* store the bits in big endian format */
69 for (y = buf = 0; y < inlen; y++) {
70 buf |= (in[y] ? 1 : 0) << (7 - (y & 7));
71 if ((y & 7) == 7) {
72 out[x++] = buf;
73 buf = 0;
74 }
75 }
76 /* store last byte */
77 if (inlen & 7) {
78 out[x++] = buf;
79 }
80 *outlen = x;
81 return CRYPT_OK;
82 }
83
84 #endif
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_bit_string.c
14 ASN.1 DER, encode a BIT STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 #define getbit(n, k) (((n) & ( 1 << (k) )) >> (k))
21
22 /**
23 Store a BIT STRING
24 @param in The array of bits to store (8 per char)
25 @param inlen The number of bits tostore
26 @param out [out] The destination for the DER encoded BIT STRING
27 @param outlen [in/out] The max size and resulting size of the DER BIT STRING
28 @return CRYPT_OK if successful
29 */
30 int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
31 unsigned char *out, unsigned long *outlen)
32 {
33 unsigned long len, x, y;
34 unsigned char buf;
35 int err;
36
37 LTC_ARGCHK(in != NULL);
38 LTC_ARGCHK(out != NULL);
39 LTC_ARGCHK(outlen != NULL);
40
41 /* avoid overflows */
42 if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) {
43 return err;
44 }
45
46 if (len > *outlen) {
47 *outlen = len;
48 return CRYPT_BUFFER_OVERFLOW;
49 }
50
51 /* store header (include bit padding count in length) */
52 x = 0;
53 y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
54
55 out[x++] = 0x03;
56 if (y < 128) {
57 out[x++] = (unsigned char)y;
58 } else if (y < 256) {
59 out[x++] = 0x81;
60 out[x++] = (unsigned char)y;
61 } else if (y < 65536) {
62 out[x++] = 0x82;
63 out[x++] = (unsigned char)((y>>8)&255);
64 out[x++] = (unsigned char)(y&255);
65 }
66
67 /* store number of zero padding bits */
68 out[x++] = (unsigned char)((8 - inlen) & 7);
69
70 /* store the bits in big endian format */
71 for (y = buf = 0; y < inlen; y++) {
72 buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7));
73 if ((y & 7) == 7) {
74 out[x++] = buf;
75 buf = 0;
76 }
77 }
78 /* store last byte */
79 if (inlen & 7) {
80 out[x++] = buf;
81 }
82
83 *outlen = x;
84 return CRYPT_OK;
85 }
86
87 #endif
88
89 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */
90 /* $Revision: 1.5 $ */
91 /* $Date: 2006/12/28 01:27:24 $ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_bit_string.c
14 ASN.1 DER, get length of BIT STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Gets length of DER encoding of BIT STRING
20 @param nbits The number of bits in the string to encode
21 @param outlen [out] The length of the DER encoding for the given string
22 @return CRYPT_OK if successful
23 */
24 int der_length_bit_string(unsigned long nbits, unsigned long *outlen)
25 {
26 unsigned long nbytes;
27 LTC_ARGCHK(outlen != NULL);
28
29 /* get the number of the bytes */
30 nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
31
32 if (nbytes < 128) {
33 /* 03 LL PP DD DD DD ... */
34 *outlen = 2 + nbytes;
35 } else if (nbytes < 256) {
36 /* 03 81 LL PP DD DD DD ... */
37 *outlen = 3 + nbytes;
38 } else if (nbytes < 65536) {
39 /* 03 82 LL LL PP DD DD DD ... */
40 *outlen = 4 + nbytes;
41 } else {
42 return CRYPT_INVALID_ARG;
43 }
44
45 return CRYPT_OK;
46 }
47
48 #endif
49
50
51 /* $Source$ */
52 /* $Revision$ */
53 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_boolean.c
14 ASN.1 DER, decode a BOOLEAN, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Read a BOOLEAN
22 @param in The destination for the DER encoded BOOLEAN
23 @param inlen The size of the DER BOOLEAN
24 @param out [out] The boolean to decode
25 @return CRYPT_OK if successful
26 */
27 int der_decode_boolean(const unsigned char *in, unsigned long inlen,
28 int *out)
29 {
30 LTC_ARGCHK(in != NULL);
31 LTC_ARGCHK(out != NULL);
32
33 if (inlen < 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) {
34 return CRYPT_INVALID_ARG;
35 }
36
37 *out = (in[2]==0xFF) ? 1 : 0;
38
39 return CRYPT_OK;
40 }
41
42 #endif
43
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_boolean.c
14 ASN.1 DER, encode a BOOLEAN, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a BOOLEAN
22 @param in The boolean to encode
23 @param out [out] The destination for the DER encoded BOOLEAN
24 @param outlen [in/out] The max size and resulting size of the DER BOOLEAN
25 @return CRYPT_OK if successful
26 */
27 int der_encode_boolean(int in,
28 unsigned char *out, unsigned long *outlen)
29 {
30 LTC_ARGCHK(outlen != NULL);
31 LTC_ARGCHK(out != NULL);
32
33 if (*outlen < 3) {
34 *outlen = 3;
35 return CRYPT_BUFFER_OVERFLOW;
36 }
37
38 *outlen = 3;
39 out[0] = 0x01;
40 out[1] = 0x01;
41 out[2] = in ? 0xFF : 0x00;
42
43 return CRYPT_OK;
44 }
45
46 #endif
47
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_boolean.c
14 ASN.1 DER, get length of a BOOLEAN, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Gets length of DER encoding of a BOOLEAN
20 @param outlen [out] The length of the DER encoding
21 @return CRYPT_OK if successful
22 */
23 int der_length_boolean(unsigned long *outlen)
24 {
25 LTC_ARGCHK(outlen != NULL);
26 *outlen = 3;
27 return CRYPT_OK;
28 }
29
30 #endif
31
32 /* $Source$ */
33 /* $Revision$ */
34 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_choice.c
14 ASN.1 DER, decode a CHOICE, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Decode a CHOICE
21 @param in The DER encoded input
22 @param inlen [in/out] The size of the input and resulting size of read type
23 @param list The list of items to decode
24 @param outlen The number of items in the list
25 @return CRYPT_OK on success
26 */
27 int der_decode_choice(const unsigned char *in, unsigned long *inlen,
28 ltc_asn1_list *list, unsigned long outlen)
29 {
30 unsigned long size, x, z;
31 void *data;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(inlen != NULL);
35 LTC_ARGCHK(list != NULL);
36
37 /* get blk size */
38 if (*inlen < 2) {
39 return CRYPT_INVALID_PACKET;
40 }
41
42 /* set all of the "used" flags to zero */
43 for (x = 0; x < outlen; x++) {
44 list[x].used = 0;
45 }
46
47 /* now scan until we have a winner */
48 for (x = 0; x < outlen; x++) {
49 size = list[x].size;
50 data = list[x].data;
51
52 switch (list[x].type) {
53 case LTC_ASN1_INTEGER:
54 if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
55 if (der_length_integer(data, &z) == CRYPT_OK) {
56 list[x].used = 1;
57 *inlen = z;
58 return CRYPT_OK;
59 }
60 }
61 break;
62
63 case LTC_ASN1_SHORT_INTEGER:
64 if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) {
65 if (der_length_short_integer(size, &z) == CRYPT_OK) {
66 list[x].used = 1;
67 *inlen = z;
68 return CRYPT_OK;
69 }
70 }
71 break;
72
73 case LTC_ASN1_BIT_STRING:
74 if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
75 if (der_length_bit_string(size, &z) == CRYPT_OK) {
76 list[x].used = 1;
77 list[x].size = size;
78 *inlen = z;
79 return CRYPT_OK;
80 }
81 }
82 break;
83
84 case LTC_ASN1_OCTET_STRING:
85 if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
86 if (der_length_octet_string(size, &z) == CRYPT_OK) {
87 list[x].used = 1;
88 list[x].size = size;
89 *inlen = z;
90 return CRYPT_OK;
91 }
92 }
93 break;
94
95 case LTC_ASN1_NULL:
96 if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
97 *inlen = 2;
98 list[x].used = 1;
99 return CRYPT_OK;
100 }
101 break;
102
103 case LTC_ASN1_OBJECT_IDENTIFIER:
104 if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) {
105 if (der_length_object_identifier(data, size, &z) == CRYPT_OK) {
106 list[x].used = 1;
107 list[x].size = size;
108 *inlen = z;
109 return CRYPT_OK;
110 }
111 }
112 break;
113
114 case LTC_ASN1_IA5_STRING:
115 if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
116 if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
117 list[x].used = 1;
118 list[x].size = size;
119 *inlen = z;
120 return CRYPT_OK;
121 }
122 }
123 break;
124
125
126 case LTC_ASN1_PRINTABLE_STRING:
127 if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) {
128 if (der_length_printable_string(data, size, &z) == CRYPT_OK) {
129 list[x].used = 1;
130 list[x].size = size;
131 *inlen = z;
132 return CRYPT_OK;
133 }
134 }
135 break;
136
137 case LTC_ASN1_UTF8_STRING:
138 if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) {
139 if (der_length_utf8_string(data, size, &z) == CRYPT_OK) {
140 list[x].used = 1;
141 list[x].size = size;
142 *inlen = z;
143 return CRYPT_OK;
144 }
145 }
146 break;
147
148 case LTC_ASN1_UTCTIME:
149 z = *inlen;
150 if (der_decode_utctime(in, &z, data) == CRYPT_OK) {
151 list[x].used = 1;
152 *inlen = z;
153 return CRYPT_OK;
154 }
155 break;
156
157 case LTC_ASN1_SET:
158 case LTC_ASN1_SETOF:
159 case LTC_ASN1_SEQUENCE:
160 if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
161 if (der_length_sequence(data, size, &z) == CRYPT_OK) {
162 list[x].used = 1;
163 *inlen = z;
164 return CRYPT_OK;
165 }
166 }
167 break;
168
169 default:
170 return CRYPT_INVALID_ARG;
171 }
172 }
173
174 return CRYPT_INVALID_PACKET;
175 }
176
177 #endif
178
179 /* $Source$ */
180 /* $Revision$ */
181 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_ia5_string.c
14 ASN.1 DER, encode a IA5 STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a IA5 STRING
22 @param in The DER encoded IA5 STRING
23 @param inlen The size of the DER IA5 STRING
24 @param out [out] The array of octets stored (one per char)
25 @param outlen [in/out] The number of octets stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32 int t;
33
34 LTC_ARGCHK(in != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* must have header at least */
39 if (inlen < 2) {
40 return CRYPT_INVALID_PACKET;
41 }
42
43 /* check for 0x16 */
44 if ((in[0] & 0x1F) != 0x16) {
45 return CRYPT_INVALID_PACKET;
46 }
47 x = 1;
48
49 /* decode the length */
50 if (in[x] & 0x80) {
51 /* valid # of bytes in length are 1,2,3 */
52 y = in[x] & 0x7F;
53 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* read the length in */
58 len = 0;
59 ++x;
60 while (y--) {
61 len = (len << 8) | in[x++];
62 }
63 } else {
64 len = in[x++] & 0x7F;
65 }
66
67 /* is it too long? */
68 if (len > *outlen) {
69 *outlen = len;
70 return CRYPT_BUFFER_OVERFLOW;
71 }
72
73 if (len + x > inlen) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* read the data */
78 for (y = 0; y < len; y++) {
79 t = der_ia5_value_decode(in[x++]);
80 if (t == -1) {
81 return CRYPT_INVALID_ARG;
82 }
83 out[y] = t;
84 }
85
86 *outlen = y;
87
88 return CRYPT_OK;
89 }
90
91 #endif
92
93 /* $Source$ */
94 /* $Revision$ */
95 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_ia5_string.c
14 ASN.1 DER, encode a IA5 STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Store an IA5 STRING
21 @param in The array of IA5 to store (one per char)
22 @param inlen The number of IA5 to store
23 @param out [out] The destination for the DER encoded IA5 STRING
24 @param outlen [in/out] The max size and resulting size of the DER IA5 STRING
25 @return CRYPT_OK if successful
26 */
27 int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
28 unsigned char *out, unsigned long *outlen)
29 {
30 unsigned long x, y, len;
31 int err;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* get the size */
38 if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* too big? */
43 if (len > *outlen) {
44 *outlen = len;
45 return CRYPT_BUFFER_OVERFLOW;
46 }
47
48 /* encode the header+len */
49 x = 0;
50 out[x++] = 0x16;
51 if (inlen < 128) {
52 out[x++] = (unsigned char)inlen;
53 } else if (inlen < 256) {
54 out[x++] = 0x81;
55 out[x++] = (unsigned char)inlen;
56 } else if (inlen < 65536UL) {
57 out[x++] = 0x82;
58 out[x++] = (unsigned char)((inlen>>8)&255);
59 out[x++] = (unsigned char)(inlen&255);
60 } else if (inlen < 16777216UL) {
61 out[x++] = 0x83;
62 out[x++] = (unsigned char)((inlen>>16)&255);
63 out[x++] = (unsigned char)((inlen>>8)&255);
64 out[x++] = (unsigned char)(inlen&255);
65 } else {
66 return CRYPT_INVALID_ARG;
67 }
68
69 /* store octets */
70 for (y = 0; y < inlen; y++) {
71 out[x++] = der_ia5_char_encode(in[y]);
72 }
73
74 /* retun length */
75 *outlen = x;
76
77 return CRYPT_OK;
78 }
79
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_ia5_string.c
14 ASN.1 DER, get length of IA5 STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static const struct {
20 int code, value;
21 } ia5_table[] = {
22 { '\0', 0 },
23 { '\a', 7 },
24 { '\b', 8 },
25 { '\t', 9 },
26 { '\n', 10 },
27 { '\f', 12 },
28 { '\r', 13 },
29 { ' ', 32 },
30 { '!', 33 },
31 { '"', 34 },
32 { '#', 35 },
33 { '$', 36 },
34 { '%', 37 },
35 { '&', 38 },
36 { '\'', 39 },
37 { '(', 40 },
38 { ')', 41 },
39 { '*', 42 },
40 { '+', 43 },
41 { ',', 44 },
42 { '-', 45 },
43 { '.', 46 },
44 { '/', 47 },
45 { '0', 48 },
46 { '1', 49 },
47 { '2', 50 },
48 { '3', 51 },
49 { '4', 52 },
50 { '5', 53 },
51 { '6', 54 },
52 { '7', 55 },
53 { '8', 56 },
54 { '9', 57 },
55 { ':', 58 },
56 { ';', 59 },
57 { '<', 60 },
58 { '=', 61 },
59 { '>', 62 },
60 { '?', 63 },
61 { '@', 64 },
62 { 'A', 65 },
63 { 'B', 66 },
64 { 'C', 67 },
65 { 'D', 68 },
66 { 'E', 69 },
67 { 'F', 70 },
68 { 'G', 71 },
69 { 'H', 72 },
70 { 'I', 73 },
71 { 'J', 74 },
72 { 'K', 75 },
73 { 'L', 76 },
74 { 'M', 77 },
75 { 'N', 78 },
76 { 'O', 79 },
77 { 'P', 80 },
78 { 'Q', 81 },
79 { 'R', 82 },
80 { 'S', 83 },
81 { 'T', 84 },
82 { 'U', 85 },
83 { 'V', 86 },
84 { 'W', 87 },
85 { 'X', 88 },
86 { 'Y', 89 },
87 { 'Z', 90 },
88 { '[', 91 },
89 { '\\', 92 },
90 { ']', 93 },
91 { '^', 94 },
92 { '_', 95 },
93 { '`', 96 },
94 { 'a', 97 },
95 { 'b', 98 },
96 { 'c', 99 },
97 { 'd', 100 },
98 { 'e', 101 },
99 { 'f', 102 },
100 { 'g', 103 },
101 { 'h', 104 },
102 { 'i', 105 },
103 { 'j', 106 },
104 { 'k', 107 },
105 { 'l', 108 },
106 { 'm', 109 },
107 { 'n', 110 },
108 { 'o', 111 },
109 { 'p', 112 },
110 { 'q', 113 },
111 { 'r', 114 },
112 { 's', 115 },
113 { 't', 116 },
114 { 'u', 117 },
115 { 'v', 118 },
116 { 'w', 119 },
117 { 'x', 120 },
118 { 'y', 121 },
119 { 'z', 122 },
120 { '{', 123 },
121 { '|', 124 },
122 { '}', 125 },
123 { '~', 126 }
124 };
125
126 int der_ia5_char_encode(int c)
127 {
128 int x;
129 for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
130 if (ia5_table[x].code == c) {
131 return ia5_table[x].value;
132 }
133 }
134 return -1;
135 }
136
137 int der_ia5_value_decode(int v)
138 {
139 int x;
140 for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
141 if (ia5_table[x].value == v) {
142 return ia5_table[x].code;
143 }
144 }
145 return -1;
146 }
147
148 /**
149 Gets length of DER encoding of IA5 STRING
150 @param octets The values you want to encode
151 @param noctets The number of octets in the string to encode
152 @param outlen [out] The length of the DER encoding for the given string
153 @return CRYPT_OK if successful
154 */
155 int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
156 {
157 unsigned long x;
158
159 LTC_ARGCHK(outlen != NULL);
160 LTC_ARGCHK(octets != NULL);
161
162 /* scan string for validity */
163 for (x = 0; x < noctets; x++) {
164 if (der_ia5_char_encode(octets[x]) == -1) {
165 return CRYPT_INVALID_ARG;
166 }
167 }
168
169 if (noctets < 128) {
170 /* 16 LL DD DD DD ... */
171 *outlen = 2 + noctets;
172 } else if (noctets < 256) {
173 /* 16 81 LL DD DD DD ... */
174 *outlen = 3 + noctets;
175 } else if (noctets < 65536UL) {
176 /* 16 82 LL LL DD DD DD ... */
177 *outlen = 4 + noctets;
178 } else if (noctets < 16777216UL) {
179 /* 16 83 LL LL LL DD DD DD ... */
180 *outlen = 5 + noctets;
181 } else {
182 return CRYPT_INVALID_ARG;
183 }
184
185 return CRYPT_OK;
186 }
187
188 #endif
189
190
191 /* $Source$ */
192 /* $Revision$ */
193 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_integer.c
14 ASN.1 DER, decode an integer, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Read a mp_int integer
22 @param in The DER encoded data
23 @param inlen Size of DER encoded data
24 @param num The first mp_int to decode
25 @return CRYPT_OK if successful
26 */
27 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num)
28 {
29 unsigned long x, y, z;
30 int err;
31
32 LTC_ARGCHK(num != NULL);
33 LTC_ARGCHK(in != NULL);
34
35 /* min DER INTEGER is 0x02 01 00 == 0 */
36 if (inlen < (1 + 1 + 1)) {
37 return CRYPT_INVALID_PACKET;
38 }
39
40 /* ok expect 0x02 when we AND with 0001 1111 [1F] */
41 x = 0;
42 if ((in[x++] & 0x1F) != 0x02) {
43 return CRYPT_INVALID_PACKET;
44 }
45
46 /* now decode the len stuff */
47 z = in[x++];
48
49 if ((z & 0x80) == 0x00) {
50 /* short form */
51
52 /* will it overflow? */
53 if (x + z > inlen) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* no so read it */
58 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) {
59 return err;
60 }
61 } else {
62 /* long form */
63 z &= 0x7F;
64
65 /* will number of length bytes overflow? (or > 4) */
66 if (((x + z) > inlen) || (z > 4) || (z == 0)) {
67 return CRYPT_INVALID_PACKET;
68 }
69
70 /* now read it in */
71 y = 0;
72 while (z--) {
73 y = ((unsigned long)(in[x++])) | (y << 8);
74 }
75
76 /* now will reading y bytes overrun? */
77 if ((x + y) > inlen) {
78 return CRYPT_INVALID_PACKET;
79 }
80
81 /* no so read it */
82 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) {
83 return err;
84 }
85 }
86
87 /* see if it's negative */
88 if (in[x] & 0x80) {
89 void *tmp;
90 if (mp_init(&tmp) != CRYPT_OK) {
91 return CRYPT_MEM;
92 }
93
94 if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) {
95 mp_clear(tmp);
96 return CRYPT_MEM;
97 }
98 mp_clear(tmp);
99 }
100
101 return CRYPT_OK;
102
103 }
104
105 #endif
106
107 /* $Source$ */
108 /* $Revision$ */
109 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_integer.c
14 ASN.1 DER, encode an integer, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /* Exports a positive bignum as DER format (upto 2^32 bytes in size) */
21 /**
22 Store a mp_int integer
23 @param num The first mp_int to encode
24 @param out [out] The destination for the DER encoded integers
25 @param outlen [in/out] The max size and resulting size of the DER encoded integers
26 @return CRYPT_OK if successful
27 */
28 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen)
29 {
30 unsigned long tmplen, y;
31 int err, leading_zero;
32
33 LTC_ARGCHK(num != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* find out how big this will be */
38 if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) {
39 return err;
40 }
41
42 if (*outlen < tmplen) {
43 *outlen = tmplen;
44 return CRYPT_BUFFER_OVERFLOW;
45 }
46
47 if (mp_cmp_d(num, 0) != LTC_MP_LT) {
48 /* we only need a leading zero if the msb of the first byte is one */
49 if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
50 leading_zero = 1;
51 } else {
52 leading_zero = 0;
53 }
54
55 /* get length of num in bytes (plus 1 since we force the msbyte to zero) */
56 y = mp_unsigned_bin_size(num) + leading_zero;
57 } else {
58 leading_zero = 0;
59 y = mp_count_bits(num);
60 y = y + (8 - (y & 7));
61 y = y >> 3;
62 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y;
63 }
64
65 /* now store initial data */
66 *out++ = 0x02;
67 if (y < 128) {
68 /* short form */
69 *out++ = (unsigned char)y;
70 } else if (y < 256) {
71 *out++ = 0x81;
72 *out++ = (unsigned char)y;
73 } else if (y < 65536UL) {
74 *out++ = 0x82;
75 *out++ = (unsigned char)((y>>8)&255);
76 *out++ = (unsigned char)y;
77 } else if (y < 16777216UL) {
78 *out++ = 0x83;
79 *out++ = (unsigned char)((y>>16)&255);
80 *out++ = (unsigned char)((y>>8)&255);
81 *out++ = (unsigned char)y;
82 } else {
83 return CRYPT_INVALID_ARG;
84 }
85
86 /* now store msbyte of zero if num is non-zero */
87 if (leading_zero) {
88 *out++ = 0x00;
89 }
90
91 /* if it's not zero store it as big endian */
92 if (mp_cmp_d(num, 0) == LTC_MP_GT) {
93 /* now store the mpint */
94 if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) {
95 return err;
96 }
97 } else if (mp_iszero(num) != LTC_MP_YES) {
98 void *tmp;
99
100 /* negative */
101 if (mp_init(&tmp) != CRYPT_OK) {
102 return CRYPT_MEM;
103 }
104
105 /* 2^roundup and subtract */
106 y = mp_count_bits(num);
107 y = y + (8 - (y & 7));
108 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8;
109 if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) {
110 mp_clear(tmp);
111 return CRYPT_MEM;
112 }
113 if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) {
114 mp_clear(tmp);
115 return err;
116 }
117 mp_clear(tmp);
118 }
119
120 /* we good */
121 *outlen = tmplen;
122 return CRYPT_OK;
123 }
124
125 #endif
126
127 /* $Source$ */
128 /* $Revision$ */
129 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_integer.c
14 ASN.1 DER, get length of encoding, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19 /**
20 Gets length of DER encoding of num
21 @param num The int to get the size of
22 @param outlen [out] The length of the DER encoding for the given integer
23 @return CRYPT_OK if successful
24 */
25 int der_length_integer(void *num, unsigned long *outlen)
26 {
27 unsigned long z, len;
28 int leading_zero;
29
30 LTC_ARGCHK(num != NULL);
31 LTC_ARGCHK(outlen != NULL);
32
33 if (mp_cmp_d(num, 0) != LTC_MP_LT) {
34 /* positive */
35
36 /* we only need a leading zero if the msb of the first byte is one */
37 if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
38 leading_zero = 1;
39 } else {
40 leading_zero = 0;
41 }
42
43 /* size for bignum */
44 z = len = leading_zero + mp_unsigned_bin_size(num);
45 } else {
46 /* it's negative */
47 /* find power of 2 that is a multiple of eight and greater than count bits */
48 leading_zero = 0;
49 z = mp_count_bits(num);
50 z = z + (8 - (z & 7));
51 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z;
52 len = z = z >> 3;
53 }
54
55 /* now we need a length */
56 if (z < 128) {
57 /* short form */
58 ++len;
59 } else {
60 /* long form (relies on z != 0), assumes length bytes < 128 */
61 ++len;
62
63 while (z) {
64 ++len;
65 z >>= 8;
66 }
67 }
68
69 /* we need a 0x02 to indicate it's INTEGER */
70 ++len;
71
72 /* return length */
73 *outlen = len;
74 return CRYPT_OK;
75 }
76
77 #endif
78
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_object_identifier.c
14 ASN.1 DER, Decode Object Identifier, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Decode OID data and store the array of integers in words
20 @param in The OID DER encoded data
21 @param inlen The length of the OID data
22 @param words [out] The destination of the OID words
23 @param outlen [in/out] The number of OID words
24 @return CRYPT_OK if successful
25 */
26 int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
27 unsigned long *words, unsigned long *outlen)
28 {
29 unsigned long x, y, t, len;
30
31 LTC_ARGCHK(in != NULL);
32 LTC_ARGCHK(words != NULL);
33 LTC_ARGCHK(outlen != NULL);
34
35 /* header is at least 3 bytes */
36 if (inlen < 3) {
37 return CRYPT_INVALID_PACKET;
38 }
39
40 /* must be room for at least two words */
41 if (*outlen < 2) {
42 return CRYPT_BUFFER_OVERFLOW;
43 }
44
45 /* decode the packet header */
46 x = 0;
47 if ((in[x++] & 0x1F) != 0x06) {
48 return CRYPT_INVALID_PACKET;
49 }
50
51 /* get the length */
52 if (in[x] < 128) {
53 len = in[x++];
54 } else {
55 if (in[x] < 0x81 || in[x] > 0x82) {
56 return CRYPT_INVALID_PACKET;
57 }
58 y = in[x++] & 0x7F;
59 len = 0;
60 while (y--) {
61 len = (len << 8) | (unsigned long)in[x++];
62 }
63 }
64
65 if (len < 1 || (len + x) > inlen) {
66 return CRYPT_INVALID_PACKET;
67 }
68
69 /* decode words */
70 y = 0;
71 t = 0;
72 while (len--) {
73 t = (t << 7) | (in[x] & 0x7F);
74 if (!(in[x++] & 0x80)) {
75 /* store t */
76 if (y >= *outlen) {
77 return CRYPT_BUFFER_OVERFLOW;
78 }
79 if (y == 0) {
80 words[0] = t / 40;
81 words[1] = t % 40;
82 y = 2;
83 } else {
84 words[y++] = t;
85 }
86 t = 0;
87 }
88 }
89
90 *outlen = y;
91 return CRYPT_OK;
92 }
93
94 #endif
95
96 /* $Source$ */
97 /* $Revision$ */
98 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_object_identifier.c
14 ASN.1 DER, Encode Object Identifier, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Encode an OID
20 @param words The words to encode (upto 32-bits each)
21 @param nwords The number of words in the OID
22 @param out [out] Destination of OID data
23 @param outlen [in/out] The max and resulting size of the OID
24 @return CRYPT_OK if successful
25 */
26 int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
27 unsigned char *out, unsigned long *outlen)
28 {
29 unsigned long i, x, y, z, t, mask, wordbuf;
30 int err;
31
32 LTC_ARGCHK(words != NULL);
33 LTC_ARGCHK(out != NULL);
34 LTC_ARGCHK(outlen != NULL);
35
36 /* check length */
37 if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) {
38 return err;
39 }
40 if (x > *outlen) {
41 *outlen = x;
42 return CRYPT_BUFFER_OVERFLOW;
43 }
44
45 /* compute length to store OID data */
46 z = 0;
47 wordbuf = words[0] * 40 + words[1];
48 for (y = 1; y < nwords; y++) {
49 t = der_object_identifier_bits(wordbuf);
50 z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
51 if (y < nwords - 1) {
52 wordbuf = words[y + 1];
53 }
54 }
55
56 /* store header + length */
57 x = 0;
58 out[x++] = 0x06;
59 if (z < 128) {
60 out[x++] = (unsigned char)z;
61 } else if (z < 256) {
62 out[x++] = 0x81;
63 out[x++] = (unsigned char)z;
64 } else if (z < 65536UL) {
65 out[x++] = 0x82;
66 out[x++] = (unsigned char)((z>>8)&255);
67 out[x++] = (unsigned char)(z&255);
68 } else {
69 return CRYPT_INVALID_ARG;
70 }
71
72 /* store first byte */
73 wordbuf = words[0] * 40 + words[1];
74 for (i = 1; i < nwords; i++) {
75 /* store 7 bit words in little endian */
76 t = wordbuf & 0xFFFFFFFF;
77 if (t) {
78 y = x;
79 mask = 0;
80 while (t) {
81 out[x++] = (unsigned char)((t & 0x7F) | mask);
82 t >>= 7;
83 mask |= 0x80; /* upper bit is set on all but the last byte */
84 }
85 /* now swap bytes y...x-1 */
86 z = x - 1;
87 while (y < z) {
88 t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t;
89 ++y;
90 --z;
91 }
92 } else {
93 /* zero word */
94 out[x++] = 0x00;
95 }
96
97 if (i < nwords - 1) {
98 wordbuf = words[i + 1];
99 }
100 }
101
102 *outlen = x;
103 return CRYPT_OK;
104 }
105
106 #endif
107
108 /* $Source$ */
109 /* $Revision$ */
110 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_object_identifier.c
14 ASN.1 DER, get length of Object Identifier, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 unsigned long der_object_identifier_bits(unsigned long x)
20 {
21 unsigned long c;
22 x &= 0xFFFFFFFF;
23 c = 0;
24 while (x) {
25 ++c;
26 x >>= 1;
27 }
28 return c;
29 }
30
31
32 /**
33 Gets length of DER encoding of Object Identifier
34 @param nwords The number of OID words
35 @param words The actual OID words to get the size of
36 @param outlen [out] The length of the DER encoding for the given string
37 @return CRYPT_OK if successful
38 */
39 int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen)
40 {
41 unsigned long y, z, t, wordbuf;
42
43 LTC_ARGCHK(words != NULL);
44 LTC_ARGCHK(outlen != NULL);
45
46
47 /* must be >= 2 words */
48 if (nwords < 2) {
49 return CRYPT_INVALID_ARG;
50 }
51
52 /* word1 = 0,1,2,3 and word2 0..39 */
53 if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) {
54 return CRYPT_INVALID_ARG;
55 }
56
57 /* leading word is the first two */
58 z = 0;
59 wordbuf = words[0] * 40 + words[1];
60 for (y = 1; y < nwords; y++) {
61 t = der_object_identifier_bits(wordbuf);
62 z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
63 if (y < nwords - 1) {
64 /* grab next word */
65 wordbuf = words[y+1];
66 }
67 }
68
69 /* now depending on the length our length encoding changes */
70 if (z < 128) {
71 z += 2;
72 } else if (z < 256) {
73 z += 3;
74 } else if (z < 65536UL) {
75 z += 4;
76 } else {
77 return CRYPT_INVALID_ARG;
78 }
79
80 *outlen = z;
81 return CRYPT_OK;
82 }
83
84 #endif
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_octet_string.c
14 ASN.1 DER, encode a OCTET STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a OCTET STRING
22 @param in The DER encoded OCTET STRING
23 @param inlen The size of the DER OCTET STRING
24 @param out [out] The array of octets stored (one per char)
25 @param outlen [in/out] The number of octets stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* must have header at least */
38 if (inlen < 2) {
39 return CRYPT_INVALID_PACKET;
40 }
41
42 /* check for 0x04 */
43 if ((in[0] & 0x1F) != 0x04) {
44 return CRYPT_INVALID_PACKET;
45 }
46 x = 1;
47
48 /* decode the length */
49 if (in[x] & 0x80) {
50 /* valid # of bytes in length are 1,2,3 */
51 y = in[x] & 0x7F;
52 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
53 return CRYPT_INVALID_PACKET;
54 }
55
56 /* read the length in */
57 len = 0;
58 ++x;
59 while (y--) {
60 len = (len << 8) | in[x++];
61 }
62 } else {
63 len = in[x++] & 0x7F;
64 }
65
66 /* is it too long? */
67 if (len > *outlen) {
68 *outlen = len;
69 return CRYPT_BUFFER_OVERFLOW;
70 }
71
72 if (len + x > inlen) {
73 return CRYPT_INVALID_PACKET;
74 }
75
76 /* read the data */
77 for (y = 0; y < len; y++) {
78 out[y] = in[x++];
79 }
80
81 *outlen = y;
82
83 return CRYPT_OK;
84 }
85
86 #endif
87
88 /* $Source$ */
89 /* $Revision$ */
90 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_octet_string.c
14 ASN.1 DER, encode a OCTET STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store an OCTET STRING
22 @param in The array of OCTETS to store (one per char)
23 @param inlen The number of OCTETS to store
24 @param out [out] The destination for the DER encoded OCTET STRING
25 @param outlen [in/out] The max size and resulting size of the DER OCTET STRING
26 @return CRYPT_OK if successful
27 */
28 int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32 int err;
33
34 LTC_ARGCHK(in != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* get the size */
39 if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* too big? */
44 if (len > *outlen) {
45 *outlen = len;
46 return CRYPT_BUFFER_OVERFLOW;
47 }
48
49 /* encode the header+len */
50 x = 0;
51 out[x++] = 0x04;
52 if (inlen < 128) {
53 out[x++] = (unsigned char)inlen;
54 } else if (inlen < 256) {
55 out[x++] = 0x81;
56 out[x++] = (unsigned char)inlen;
57 } else if (inlen < 65536UL) {
58 out[x++] = 0x82;
59 out[x++] = (unsigned char)((inlen>>8)&255);
60 out[x++] = (unsigned char)(inlen&255);
61 } else if (inlen < 16777216UL) {
62 out[x++] = 0x83;
63 out[x++] = (unsigned char)((inlen>>16)&255);
64 out[x++] = (unsigned char)((inlen>>8)&255);
65 out[x++] = (unsigned char)(inlen&255);
66 } else {
67 return CRYPT_INVALID_ARG;
68 }
69
70 /* store octets */
71 for (y = 0; y < inlen; y++) {
72 out[x++] = in[y];
73 }
74
75 /* retun length */
76 *outlen = x;
77
78 return CRYPT_OK;
79 }
80
81 #endif
82
83 /* $Source$ */
84 /* $Revision$ */
85 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_octet_string.c
14 ASN.1 DER, get length of OCTET STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18 /**
19 Gets length of DER encoding of OCTET STRING
20 @param noctets The number of octets in the string to encode
21 @param outlen [out] The length of the DER encoding for the given string
22 @return CRYPT_OK if successful
23 */
24 int der_length_octet_string(unsigned long noctets, unsigned long *outlen)
25 {
26 LTC_ARGCHK(outlen != NULL);
27
28 if (noctets < 128) {
29 /* 04 LL DD DD DD ... */
30 *outlen = 2 + noctets;
31 } else if (noctets < 256) {
32 /* 04 81 LL DD DD DD ... */
33 *outlen = 3 + noctets;
34 } else if (noctets < 65536UL) {
35 /* 04 82 LL LL DD DD DD ... */
36 *outlen = 4 + noctets;
37 } else if (noctets < 16777216UL) {
38 /* 04 83 LL LL LL DD DD DD ... */
39 *outlen = 5 + noctets;
40 } else {
41 return CRYPT_INVALID_ARG;
42 }
43
44 return CRYPT_OK;
45 }
46
47 #endif
48
49
50 /* $Source$ */
51 /* $Revision$ */
52 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_printable_string.c
14 ASN.1 DER, encode a printable STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a printable STRING
22 @param in The DER encoded printable STRING
23 @param inlen The size of the DER printable STRING
24 @param out [out] The array of octets stored (one per char)
25 @param outlen [in/out] The number of octets stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32 int t;
33
34 LTC_ARGCHK(in != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* must have header at least */
39 if (inlen < 2) {
40 return CRYPT_INVALID_PACKET;
41 }
42
43 /* check for 0x13 */
44 if ((in[0] & 0x1F) != 0x13) {
45 return CRYPT_INVALID_PACKET;
46 }
47 x = 1;
48
49 /* decode the length */
50 if (in[x] & 0x80) {
51 /* valid # of bytes in length are 1,2,3 */
52 y = in[x] & 0x7F;
53 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* read the length in */
58 len = 0;
59 ++x;
60 while (y--) {
61 len = (len << 8) | in[x++];
62 }
63 } else {
64 len = in[x++] & 0x7F;
65 }
66
67 /* is it too long? */
68 if (len > *outlen) {
69 *outlen = len;
70 return CRYPT_BUFFER_OVERFLOW;
71 }
72
73 if (len + x > inlen) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* read the data */
78 for (y = 0; y < len; y++) {
79 t = der_printable_value_decode(in[x++]);
80 if (t == -1) {
81 return CRYPT_INVALID_ARG;
82 }
83 out[y] = t;
84 }
85
86 *outlen = y;
87
88 return CRYPT_OK;
89 }
90
91 #endif
92
93 /* $Source$ */
94 /* $Revision$ */
95 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_printable_string.c
14 ASN.1 DER, encode a printable STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Store an printable STRING
21 @param in The array of printable to store (one per char)
22 @param inlen The number of printable to store
23 @param out [out] The destination for the DER encoded printable STRING
24 @param outlen [in/out] The max size and resulting size of the DER printable STRING
25 @return CRYPT_OK if successful
26 */
27 int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
28 unsigned char *out, unsigned long *outlen)
29 {
30 unsigned long x, y, len;
31 int err;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* get the size */
38 if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* too big? */
43 if (len > *outlen) {
44 *outlen = len;
45 return CRYPT_BUFFER_OVERFLOW;
46 }
47
48 /* encode the header+len */
49 x = 0;
50 out[x++] = 0x13;
51 if (inlen < 128) {
52 out[x++] = (unsigned char)inlen;
53 } else if (inlen < 256) {
54 out[x++] = 0x81;
55 out[x++] = (unsigned char)inlen;
56 } else if (inlen < 65536UL) {
57 out[x++] = 0x82;
58 out[x++] = (unsigned char)((inlen>>8)&255);
59 out[x++] = (unsigned char)(inlen&255);
60 } else if (inlen < 16777216UL) {
61 out[x++] = 0x83;
62 out[x++] = (unsigned char)((inlen>>16)&255);
63 out[x++] = (unsigned char)((inlen>>8)&255);
64 out[x++] = (unsigned char)(inlen&255);
65 } else {
66 return CRYPT_INVALID_ARG;
67 }
68
69 /* store octets */
70 for (y = 0; y < inlen; y++) {
71 out[x++] = der_printable_char_encode(in[y]);
72 }
73
74 /* retun length */
75 *outlen = x;
76
77 return CRYPT_OK;
78 }
79
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_printable_string.c
14 ASN.1 DER, get length of Printable STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static const struct {
20 int code, value;
21 } printable_table[] = {
22 { ' ', 32 },
23 { '\'', 39 },
24 { '(', 40 },
25 { ')', 41 },
26 { '+', 43 },
27 { ',', 44 },
28 { '-', 45 },
29 { '.', 46 },
30 { '/', 47 },
31 { '0', 48 },
32 { '1', 49 },
33 { '2', 50 },
34 { '3', 51 },
35 { '4', 52 },
36 { '5', 53 },
37 { '6', 54 },
38 { '7', 55 },
39 { '8', 56 },
40 { '9', 57 },
41 { ':', 58 },
42 { '=', 61 },
43 { '?', 63 },
44 { 'A', 65 },
45 { 'B', 66 },
46 { 'C', 67 },
47 { 'D', 68 },
48 { 'E', 69 },
49 { 'F', 70 },
50 { 'G', 71 },
51 { 'H', 72 },
52 { 'I', 73 },
53 { 'J', 74 },
54 { 'K', 75 },
55 { 'L', 76 },
56 { 'M', 77 },
57 { 'N', 78 },
58 { 'O', 79 },
59 { 'P', 80 },
60 { 'Q', 81 },
61 { 'R', 82 },
62 { 'S', 83 },
63 { 'T', 84 },
64 { 'U', 85 },
65 { 'V', 86 },
66 { 'W', 87 },
67 { 'X', 88 },
68 { 'Y', 89 },
69 { 'Z', 90 },
70 { 'a', 97 },
71 { 'b', 98 },
72 { 'c', 99 },
73 { 'd', 100 },
74 { 'e', 101 },
75 { 'f', 102 },
76 { 'g', 103 },
77 { 'h', 104 },
78 { 'i', 105 },
79 { 'j', 106 },
80 { 'k', 107 },
81 { 'l', 108 },
82 { 'm', 109 },
83 { 'n', 110 },
84 { 'o', 111 },
85 { 'p', 112 },
86 { 'q', 113 },
87 { 'r', 114 },
88 { 's', 115 },
89 { 't', 116 },
90 { 'u', 117 },
91 { 'v', 118 },
92 { 'w', 119 },
93 { 'x', 120 },
94 { 'y', 121 },
95 { 'z', 122 },
96 };
97
98 int der_printable_char_encode(int c)
99 {
100 int x;
101 for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
102 if (printable_table[x].code == c) {
103 return printable_table[x].value;
104 }
105 }
106 return -1;
107 }
108
109 int der_printable_value_decode(int v)
110 {
111 int x;
112 for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
113 if (printable_table[x].value == v) {
114 return printable_table[x].code;
115 }
116 }
117 return -1;
118 }
119
120 /**
121 Gets length of DER encoding of Printable STRING
122 @param octets The values you want to encode
123 @param noctets The number of octets in the string to encode
124 @param outlen [out] The length of the DER encoding for the given string
125 @return CRYPT_OK if successful
126 */
127 int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
128 {
129 unsigned long x;
130
131 LTC_ARGCHK(outlen != NULL);
132 LTC_ARGCHK(octets != NULL);
133
134 /* scan string for validity */
135 for (x = 0; x < noctets; x++) {
136 if (der_printable_char_encode(octets[x]) == -1) {
137 return CRYPT_INVALID_ARG;
138 }
139 }
140
141 if (noctets < 128) {
142 /* 16 LL DD DD DD ... */
143 *outlen = 2 + noctets;
144 } else if (noctets < 256) {
145 /* 16 81 LL DD DD DD ... */
146 *outlen = 3 + noctets;
147 } else if (noctets < 65536UL) {
148 /* 16 82 LL LL DD DD DD ... */
149 *outlen = 4 + noctets;
150 } else if (noctets < 16777216UL) {
151 /* 16 83 LL LL LL DD DD DD ... */
152 *outlen = 5 + noctets;
153 } else {
154 return CRYPT_INVALID_ARG;
155 }
156
157 return CRYPT_OK;
158 }
159
160 #endif
161
162
163 /* $Source$ */
164 /* $Revision$ */
165 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13
14 /**
15 @file der_decode_sequence_ex.c
16 ASN.1 DER, decode a SEQUENCE, Tom St Denis
17 */
18
19 #ifdef LTC_DER
20
21 /**
22 Decode a SEQUENCE
23 @param in The DER encoded input
24 @param inlen The size of the input
25 @param list The list of items to decode
26 @param outlen The number of items in the list
27 @param ordered Search an unordeded or ordered list
28 @return CRYPT_OK on success
29 */
30 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
31 ltc_asn1_list *list, unsigned long outlen, int ordered)
32 {
33 int err, type, i;
34 unsigned long size, x, y, z, blksize;
35 void *data;
36
37 LTC_ARGCHK(in != NULL);
38 LTC_ARGCHK(list != NULL);
39
40 /* get blk size */
41 if (inlen < 2) {
42 return CRYPT_INVALID_PACKET;
43 }
44
45 /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
46 x = 0;
47 if (in[x] != 0x30 && in[x] != 0x31) {
48 return CRYPT_INVALID_PACKET;
49 }
50 ++x;
51
52 if (in[x] < 128) {
53 blksize = in[x++];
54 } else if (in[x] & 0x80) {
55 if (in[x] < 0x81 || in[x] > 0x83) {
56 return CRYPT_INVALID_PACKET;
57 }
58 y = in[x++] & 0x7F;
59
60 /* would reading the len bytes overrun? */
61 if (x + y > inlen) {
62 return CRYPT_INVALID_PACKET;
63 }
64
65 /* read len */
66 blksize = 0;
67 while (y--) {
68 blksize = (blksize << 8) | (unsigned long)in[x++];
69 }
70 }
71
72 /* would this blksize overflow? */
73 if (x + blksize > inlen) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* mark all as unused */
78 for (i = 0; i < (int)outlen; i++) {
79 list[i].used = 0;
80 }
81
82 /* ok read data */
83 inlen = blksize;
84 for (i = 0; i < (int)outlen; i++) {
85 z = 0;
86 type = list[i].type;
87 size = list[i].size;
88 data = list[i].data;
89 if (!ordered && list[i].used == 1) { continue; }
90
91 if (type == LTC_ASN1_EOL) {
92 break;
93 }
94
95 switch (type) {
96 case LTC_ASN1_BOOLEAN:
97 z = inlen;
98 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
99 goto LBL_ERR;
100 }
101 if ((err = der_length_boolean(&z)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104 break;
105
106 case LTC_ASN1_INTEGER:
107 z = inlen;
108 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
109 if (!ordered) { continue; }
110 goto LBL_ERR;
111 }
112 if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
113 goto LBL_ERR;
114 }
115 break;
116
117 case LTC_ASN1_SHORT_INTEGER:
118 z = inlen;
119 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
120 if (!ordered) { continue; }
121 goto LBL_ERR;
122 }
123 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
124 goto LBL_ERR;
125 }
126
127 break;
128
129 case LTC_ASN1_BIT_STRING:
130 z = inlen;
131 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
132 if (!ordered) { continue; }
133 goto LBL_ERR;
134 }
135 list[i].size = size;
136 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
137 goto LBL_ERR;
138 }
139 break;
140
141 case LTC_ASN1_RAW_BIT_STRING:
142 z = inlen;
143 if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
144 if (!ordered) { continue; }
145 goto LBL_ERR;
146 }
147 list[i].size = size;
148 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
149 goto LBL_ERR;
150 }
151 break;
152
153 case LTC_ASN1_OCTET_STRING:
154 z = inlen;
155 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
156 if (!ordered) { continue; }
157 goto LBL_ERR;
158 }
159 list[i].size = size;
160 if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
161 goto LBL_ERR;
162 }
163 break;
164
165 case LTC_ASN1_NULL:
166 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
167 if (!ordered) { continue; }
168 err = CRYPT_INVALID_PACKET;
169 goto LBL_ERR;
170 }
171 z = 2;
172 break;
173
174 case LTC_ASN1_OBJECT_IDENTIFIER:
175 z = inlen;
176 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
177 if (!ordered) { continue; }
178 goto LBL_ERR;
179 }
180 list[i].size = size;
181 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
182 goto LBL_ERR;
183 }
184 break;
185
186 case LTC_ASN1_IA5_STRING:
187 z = inlen;
188 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
189 if (!ordered) { continue; }
190 goto LBL_ERR;
191 }
192 list[i].size = size;
193 if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
194 goto LBL_ERR;
195 }
196 break;
197
198
199 case LTC_ASN1_PRINTABLE_STRING:
200 z = inlen;
201 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
202 if (!ordered) { continue; }
203 goto LBL_ERR;
204 }
205 list[i].size = size;
206 if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
207 goto LBL_ERR;
208 }
209 break;
210
211 case LTC_ASN1_UTF8_STRING:
212 z = inlen;
213 if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
214 if (!ordered) { continue; }
215 goto LBL_ERR;
216 }
217 list[i].size = size;
218 if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
219 goto LBL_ERR;
220 }
221 break;
222
223 case LTC_ASN1_UTCTIME:
224 z = inlen;
225 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
226 if (!ordered) { continue; }
227 goto LBL_ERR;
228 }
229 break;
230
231 case LTC_ASN1_SET:
232 z = inlen;
233 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
234 if (!ordered) { continue; }
235 goto LBL_ERR;
236 }
237 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
238 goto LBL_ERR;
239 }
240 break;
241
242 case LTC_ASN1_SETOF:
243 case LTC_ASN1_SEQUENCE:
244 /* detect if we have the right type */
245 if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) {
246 err = CRYPT_INVALID_PACKET;
247 goto LBL_ERR;
248 }
249
250 z = inlen;
251 if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
252 if (!ordered) { continue; }
253 goto LBL_ERR;
254 }
255 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
256 goto LBL_ERR;
257 }
258 break;
259
260
261 case LTC_ASN1_CHOICE:
262 z = inlen;
263 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
264 if (!ordered) { continue; }
265 goto LBL_ERR;
266 }
267 break;
268
269 default:
270 err = CRYPT_INVALID_ARG;
271 goto LBL_ERR;
272 }
273 x += z;
274 inlen -= z;
275 list[i].used = 1;
276 if (!ordered) {
277 /* restart the decoder */
278 i = -1;
279 }
280 }
281
282 for (i = 0; i < (int)outlen; i++) {
283 if (list[i].used == 0) {
284 err = CRYPT_INVALID_PACKET;
285 goto LBL_ERR;
286 }
287 }
288 err = CRYPT_OK;
289
290 LBL_ERR:
291 return err;
292 }
293
294 #endif
295
296 /* $Source$ */
297 /* $Revision$ */
298 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_sequence_flexi.c
14 ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static unsigned long fetch_length(const unsigned char *in, unsigned long inlen)
20 {
21 unsigned long x, y, z;
22
23 y = 0;
24
25 /* skip type and read len */
26 if (inlen < 2) {
27 return 0xFFFFFFFF;
28 }
29 ++in; ++y;
30
31 /* read len */
32 x = *in++; ++y;
33
34 /* <128 means literal */
35 if (x < 128) {
36 return x+y;
37 }
38 x &= 0x7F; /* the lower 7 bits are the length of the length */
39 inlen -= 2;
40
41 /* len means len of len! */
42 if (x == 0 || x > 4 || x > inlen) {
43 return 0xFFFFFFFF;
44 }
45
46 y += x;
47 z = 0;
48 while (x--) {
49 z = (z<<8) | ((unsigned long)*in);
50 ++in;
51 }
52 return z+y;
53 }
54
55 /**
56 ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
57 @param in The input buffer
58 @param inlen [in/out] The length of the input buffer and on output the amount of decoded data
59 @param out [out] A pointer to the linked list
60 @return CRYPT_OK on success.
61 */
62 int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
63 {
64 ltc_asn1_list *l;
65 unsigned long err, type, len, totlen, x, y;
66 void *realloc_tmp;
67 int isConstructed;
68
69 LTC_ARGCHK(in != NULL);
70 LTC_ARGCHK(inlen != NULL);
71 LTC_ARGCHK(out != NULL);
72
73 l = NULL;
74 totlen = 0;
75
76 /* scan the input and and get lengths and what not */
77 while (*inlen) {
78 /* read the type byte */
79 type = *in;
80
81 /* fetch length */
82 len = fetch_length(in, *inlen);
83 if (len > *inlen) {
84 err = CRYPT_INVALID_PACKET;
85 goto error;
86 }
87
88 /* alloc new link */
89 if (l == NULL) {
90 l = XCALLOC(1, sizeof(*l));
91 if (l == NULL) {
92 err = CRYPT_MEM;
93 goto error;
94 }
95 } else {
96 l->next = XCALLOC(1, sizeof(*l));
97 if (l->next == NULL) {
98 err = CRYPT_MEM;
99 goto error;
100 }
101 l->next->prev = l;
102 l = l->next;
103 }
104
105 if ((isConstructed = ((type & 0xE0) == 0xA0 ? 1 : 0))) {
106 /* constructed, use the 'used' field to store the original tag number */
107 l->used = (type & 0x1F);
108 /* treat constructed elements like SETs */
109 type = 0x31;
110 }
111
112 /* now switch on type */
113 switch (type) {
114 case 0x01: /* BOOLEAN */
115 l->type = LTC_ASN1_BOOLEAN;
116 l->size = 1;
117 l->data = XCALLOC(1, sizeof(int));
118
119 if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) {
120 goto error;
121 }
122
123 if ((err = der_length_boolean(&len)) != CRYPT_OK) {
124 goto error;
125 }
126 break;
127
128 case 0x02: /* INTEGER */
129 /* init field */
130 l->type = LTC_ASN1_INTEGER;
131 l->size = 1;
132 if ((err = mp_init(&l->data)) != CRYPT_OK) {
133 goto error;
134 }
135
136 /* decode field */
137 if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) {
138 goto error;
139 }
140
141 /* calc length of object */
142 if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) {
143 goto error;
144 }
145 break;
146
147 case 0x03: /* BIT */
148 /* init field */
149 l->type = LTC_ASN1_BIT_STRING;
150 l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */
151
152 if ((l->data = XCALLOC(1, l->size)) == NULL) {
153 err = CRYPT_MEM;
154 goto error;
155 }
156
157 if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
158 goto error;
159 }
160
161 if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) {
162 goto error;
163 }
164 break;
165
166 case 0x04: /* OCTET */
167
168 /* init field */
169 l->type = LTC_ASN1_OCTET_STRING;
170 l->size = len;
171
172 if ((l->data = XCALLOC(1, l->size)) == NULL) {
173 err = CRYPT_MEM;
174 goto error;
175 }
176
177 if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
178 goto error;
179 }
180
181 if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) {
182 goto error;
183 }
184 break;
185
186 case 0x05: /* NULL */
187
188 /* valid NULL is 0x05 0x00 */
189 if (in[0] != 0x05 || in[1] != 0x00) {
190 err = CRYPT_INVALID_PACKET;
191 goto error;
192 }
193
194 /* simple to store ;-) */
195 l->type = LTC_ASN1_NULL;
196 l->data = NULL;
197 l->size = 0;
198 len = 2;
199
200 break;
201
202 case 0x06: /* OID */
203
204 /* init field */
205 l->type = LTC_ASN1_OBJECT_IDENTIFIER;
206 l->size = len;
207
208 if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) {
209 err = CRYPT_MEM;
210 goto error;
211 }
212
213 if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
214 goto error;
215 }
216
217 if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) {
218 goto error;
219 }
220
221 /* resize it to save a bunch of mem */
222 if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) {
223 /* out of heap but this is not an error */
224 break;
225 }
226 l->data = realloc_tmp;
227 break;
228
229 case 0x0C: /* UTF8 */
230
231 /* init field */
232 l->type = LTC_ASN1_UTF8_STRING;
233 l->size = len;
234
235 if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) {
236 err = CRYPT_MEM;
237 goto error;
238 }
239
240 if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
241 goto error;
242 }
243
244 if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) {
245 goto error;
246 }
247 break;
248
249 case 0x13: /* PRINTABLE */
250
251 /* init field */
252 l->type = LTC_ASN1_PRINTABLE_STRING;
253 l->size = len;
254
255 if ((l->data = XCALLOC(1, l->size)) == NULL) {
256 err = CRYPT_MEM;
257 goto error;
258 }
259
260 if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
261 goto error;
262 }
263
264 if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) {
265 goto error;
266 }
267 break;
268
269 case 0x14: /* TELETEXT */
270
271 /* init field */
272 l->type = LTC_ASN1_TELETEX_STRING;
273 l->size = len;
274
275 if ((l->data = XCALLOC(1, l->size)) == NULL) {
276 err = CRYPT_MEM;
277 goto error;
278 }
279
280 if ((err = der_decode_teletex_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
281 goto error;
282 }
283
284 if ((err = der_length_teletex_string(l->data, l->size, &len)) != CRYPT_OK) {
285 goto error;
286 }
287 break;
288
289 case 0x16: /* IA5 */
290
291 /* init field */
292 l->type = LTC_ASN1_IA5_STRING;
293 l->size = len;
294
295 if ((l->data = XCALLOC(1, l->size)) == NULL) {
296 err = CRYPT_MEM;
297 goto error;
298 }
299
300 if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
301 goto error;
302 }
303
304 if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) {
305 goto error;
306 }
307 break;
308
309 case 0x17: /* UTC TIME */
310
311 /* init field */
312 l->type = LTC_ASN1_UTCTIME;
313 l->size = 1;
314
315 if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) {
316 err = CRYPT_MEM;
317 goto error;
318 }
319
320 len = *inlen;
321 if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) {
322 goto error;
323 }
324
325 if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) {
326 goto error;
327 }
328 break;
329
330 case 0x30: /* SEQUENCE */
331 case 0x31: /* SET */
332
333 /* init field */
334 l->type = (isConstructed ? LTC_ASN1_CONSTRUCTED : ((type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET));
335
336 /* we have to decode the SEQUENCE header and get it's length */
337
338 /* move past type */
339 ++in; --(*inlen);
340
341 /* read length byte */
342 x = *in++; --(*inlen);
343
344 /* smallest SEQUENCE/SET header */
345 y = 2;
346
347 /* now if it's > 127 the next bytes are the length of the length */
348 if (x > 128) {
349 x &= 0x7F;
350 in += x;
351 *inlen -= x;
352
353 /* update sequence header len */
354 y += x;
355 }
356
357 /* Sequence elements go as child */
358 len = len - y;
359 if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) {
360 goto error;
361 }
362
363 /* len update */
364 totlen += y;
365
366 /* link them up y0 */
367 l->child->parent = l;
368
369 break;
370 default:
371 /* invalid byte ... this is a soft error */
372 /* remove link */
373 if (l->prev) {
374 l = l->prev;
375 XFREE(l->next);
376 l->next = NULL;
377 }
378 goto outside;
379 }
380
381 /* advance pointers */
382 totlen += len;
383 in += len;
384 *inlen -= len;
385 }
386
387 outside:
388
389 /* rewind l please */
390 while (l->prev != NULL || l->parent != NULL) {
391 if (l->parent != NULL) {
392 l = l->parent;
393 } else {
394 l = l->prev;
395 }
396 }
397
398 /* return */
399 *out = l;
400 *inlen = totlen;
401 return CRYPT_OK;
402
403 error:
404 /* free list */
405 der_sequence_free(l);
406
407 return err;
408 }
409
410 #endif
411
412
413 /* $Source$ */
414 /* $Revision$ */
415 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13
14 /**
15 @file der_decode_sequence_multi.c
16 ASN.1 DER, decode a SEQUENCE, Tom St Denis
17 */
18
19 #ifdef LTC_DER
20
21 /**
22 Decode a SEQUENCE type using a VA list
23 @param in Input buffer
24 @param inlen Length of input in octets
25 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
26 @return CRYPT_OK on success
27 */
28 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
29 {
30 int err, type;
31 unsigned long size, x;
32 void *data;
33 va_list args;
34 ltc_asn1_list *list;
35
36 LTC_ARGCHK(in != NULL);
37
38 /* get size of output that will be required */
39 va_start(args, inlen);
40 x = 0;
41 for (;;) {
42 type = va_arg(args, int);
43 size = va_arg(args, unsigned long);
44 data = va_arg(args, void*);
45
46 if (type == LTC_ASN1_EOL) {
47 break;
48 }
49
50 switch (type) {
51 case LTC_ASN1_BOOLEAN:
52 case LTC_ASN1_INTEGER:
53 case LTC_ASN1_SHORT_INTEGER:
54 case LTC_ASN1_BIT_STRING:
55 case LTC_ASN1_OCTET_STRING:
56 case LTC_ASN1_NULL:
57 case LTC_ASN1_OBJECT_IDENTIFIER:
58 case LTC_ASN1_IA5_STRING:
59 case LTC_ASN1_PRINTABLE_STRING:
60 case LTC_ASN1_UTF8_STRING:
61 case LTC_ASN1_UTCTIME:
62 case LTC_ASN1_SET:
63 case LTC_ASN1_SETOF:
64 case LTC_ASN1_SEQUENCE:
65 case LTC_ASN1_CHOICE:
66 ++x;
67 break;
68
69 default:
70 va_end(args);
71 return CRYPT_INVALID_ARG;
72 }
73 }
74 va_end(args);
75
76 /* allocate structure for x elements */
77 if (x == 0) {
78 return CRYPT_NOP;
79 }
80
81 list = XCALLOC(sizeof(*list), x);
82 if (list == NULL) {
83 return CRYPT_MEM;
84 }
85
86 /* fill in the structure */
87 va_start(args, inlen);
88 x = 0;
89 for (;;) {
90 type = va_arg(args, int);
91 size = va_arg(args, unsigned long);
92 data = va_arg(args, void*);
93
94 if (type == LTC_ASN1_EOL) {
95 break;
96 }
97
98 switch (type) {
99 case LTC_ASN1_BOOLEAN:
100 case LTC_ASN1_INTEGER:
101 case LTC_ASN1_SHORT_INTEGER:
102 case LTC_ASN1_BIT_STRING:
103 case LTC_ASN1_OCTET_STRING:
104 case LTC_ASN1_NULL:
105 case LTC_ASN1_OBJECT_IDENTIFIER:
106 case LTC_ASN1_IA5_STRING:
107 case LTC_ASN1_PRINTABLE_STRING:
108 case LTC_ASN1_UTF8_STRING:
109 case LTC_ASN1_UTCTIME:
110 case LTC_ASN1_SEQUENCE:
111 case LTC_ASN1_SET:
112 case LTC_ASN1_SETOF:
113 case LTC_ASN1_CHOICE:
114 list[x].type = type;
115 list[x].size = size;
116 list[x++].data = data;
117 break;
118
119 default:
120 va_end(args);
121 err = CRYPT_INVALID_ARG;
122 goto LBL_ERR;
123 }
124 }
125 va_end(args);
126
127 err = der_decode_sequence(in, inlen, list, x);
128 LBL_ERR:
129 XFREE(list);
130 return err;
131 }
132
133 #endif
134
135
136 /* $Source$ */
137 /* $Revision$ */
138 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9 #include "tomcrypt.h"
10 /**
11 @file der_encode_sequence_multi.c
12 ASN.1 DER, encode a Subject Public Key structure --nmav
13 */
14
15 #ifdef LTC_DER
16
17 /* AlgorithmIdentifier := SEQUENCE {
18 * algorithm OBJECT IDENTIFIER,
19 * parameters ANY DEFINED BY algorithm
20 * }
21 *
22 * SubjectPublicKeyInfo := SEQUENCE {
23 * algorithm AlgorithmIdentifier,
24 * subjectPublicKey BIT STRING
25 * }
26 */
27 /**
28 Encode a SEQUENCE type using a VA list
29 @param out [out] Destination for data
30 @param outlen [in/out] Length of buffer and resulting length of output
31 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
32 @return CRYPT_OK on success
33 */
34 int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
35 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
36 unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len)
37 {
38 int err;
39 unsigned long len;
40 oid_st oid;
41 unsigned char *tmpbuf;
42 unsigned long tmpoid[16];
43 ltc_asn1_list alg_id[2];
44 ltc_asn1_list subject_pubkey[2];
45
46 LTC_ARGCHK(in != NULL);
47 LTC_ARGCHK(inlen != 0);
48
49 err = pk_get_oid(algorithm, &oid);
50 if (err != CRYPT_OK) {
51 return err;
52 }
53
54 /* see if the OpenSSL DER format RSA public key will work */
55 tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8);
56 if (tmpbuf == NULL) {
57 err = CRYPT_MEM;
58 goto LBL_ERR;
59 }
60
61 /* this includes the internal hash ID and optional params (NULL in this case) */
62 LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
63 LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len);
64
65 /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it
66 then proceed to convert bit to octet
67 */
68 LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2);
69 LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8);
70
71 err=der_decode_sequence(in, inlen, subject_pubkey, 2UL);
72 if (err != CRYPT_OK) {
73 goto LBL_ERR;
74 }
75
76 len = subject_pubkey[1].size/8;
77 if (*public_key_len > len) {
78 memcpy(public_key, subject_pubkey[1].data, len);
79 *public_key_len = len;
80 } else {
81 *public_key_len = len;
82 err = CRYPT_BUFFER_OVERFLOW;
83 goto LBL_ERR;
84 }
85
86 err = CRYPT_OK;
87
88 LBL_ERR:
89
90 XFREE(tmpbuf);
91
92 return err;
93 }
94
95 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13
14 /**
15 @file der_encode_sequence_ex.c
16 ASN.1 DER, encode a SEQUENCE, Tom St Denis
17 */
18
19 #ifdef LTC_DER
20
21 /**
22 Encode a SEQUENCE
23 @param list The list of items to encode
24 @param inlen The number of items in the list
25 @param out [out] The destination
26 @param outlen [in/out] The size of the output
27 @param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF
28 @return CRYPT_OK on success
29 */
30 int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
31 unsigned char *out, unsigned long *outlen, int type_of)
32 {
33 int err, type;
34 unsigned long size, x, y, z, i;
35 void *data;
36
37 LTC_ARGCHK(list != NULL);
38 LTC_ARGCHK(out != NULL);
39 LTC_ARGCHK(outlen != NULL);
40
41 /* get size of output that will be required */
42 y = 0;
43 for (i = 0; i < inlen; i++) {
44 type = list[i].type;
45 size = list[i].size;
46 data = list[i].data;
47
48 if (type == LTC_ASN1_EOL) {
49 break;
50 }
51
52 switch (type) {
53 case LTC_ASN1_BOOLEAN:
54 if ((err = der_length_boolean(&x)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57 y += x;
58 break;
59
60 case LTC_ASN1_INTEGER:
61 if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
62 goto LBL_ERR;
63 }
64 y += x;
65 break;
66
67 case LTC_ASN1_SHORT_INTEGER:
68 if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) {
69 goto LBL_ERR;
70 }
71 y += x;
72 break;
73
74 case LTC_ASN1_BIT_STRING:
75 case LTC_ASN1_RAW_BIT_STRING:
76 if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79 y += x;
80 break;
81
82 case LTC_ASN1_OCTET_STRING:
83 if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
84 goto LBL_ERR;
85 }
86 y += x;
87 break;
88
89 case LTC_ASN1_NULL:
90 y += 2;
91 break;
92
93 case LTC_ASN1_OBJECT_IDENTIFIER:
94 if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
95 goto LBL_ERR;
96 }
97 y += x;
98 break;
99
100 case LTC_ASN1_IA5_STRING:
101 if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104 y += x;
105 break;
106
107 case LTC_ASN1_PRINTABLE_STRING:
108 if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
109 goto LBL_ERR;
110 }
111 y += x;
112 break;
113
114 case LTC_ASN1_UTF8_STRING:
115 if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
116 goto LBL_ERR;
117 }
118 y += x;
119 break;
120
121 case LTC_ASN1_UTCTIME:
122 if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
123 goto LBL_ERR;
124 }
125 y += x;
126 break;
127
128 case LTC_ASN1_SET:
129 case LTC_ASN1_SETOF:
130 case LTC_ASN1_SEQUENCE:
131 if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
132 goto LBL_ERR;
133 }
134 y += x;
135 break;
136
137 default:
138 err = CRYPT_INVALID_ARG;
139 goto LBL_ERR;
140 }
141 }
142
143 /* calc header size */
144 z = y;
145 if (y < 128) {
146 y += 2;
147 } else if (y < 256) {
148 /* 0x30 0x81 LL */
149 y += 3;
150 } else if (y < 65536UL) {
151 /* 0x30 0x82 LL LL */
152 y += 4;
153 } else if (y < 16777216UL) {
154 /* 0x30 0x83 LL LL LL */
155 y += 5;
156 } else {
157 err = CRYPT_INVALID_ARG;
158 goto LBL_ERR;
159 }
160
161 /* too big ? */
162 if (*outlen < y) {
163 *outlen = y;
164 err = CRYPT_BUFFER_OVERFLOW;
165 goto LBL_ERR;
166 }
167
168 /* store header */
169 x = 0;
170 out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
171
172 if (z < 128) {
173 out[x++] = (unsigned char)z;
174 } else if (z < 256) {
175 out[x++] = 0x81;
176 out[x++] = (unsigned char)z;
177 } else if (z < 65536UL) {
178 out[x++] = 0x82;
179 out[x++] = (unsigned char)((z>>8UL)&255);
180 out[x++] = (unsigned char)(z&255);
181 } else if (z < 16777216UL) {
182 out[x++] = 0x83;
183 out[x++] = (unsigned char)((z>>16UL)&255);
184 out[x++] = (unsigned char)((z>>8UL)&255);
185 out[x++] = (unsigned char)(z&255);
186 }
187
188 /* store data */
189 *outlen -= x;
190 for (i = 0; i < inlen; i++) {
191 type = list[i].type;
192 size = list[i].size;
193 data = list[i].data;
194
195 if (type == LTC_ASN1_EOL) {
196 break;
197 }
198
199 switch (type) {
200 case LTC_ASN1_BOOLEAN:
201 z = *outlen;
202 if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
203 goto LBL_ERR;
204 }
205 x += z;
206 *outlen -= z;
207 break;
208
209 case LTC_ASN1_INTEGER:
210 z = *outlen;
211 if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
212 goto LBL_ERR;
213 }
214 x += z;
215 *outlen -= z;
216 break;
217
218 case LTC_ASN1_SHORT_INTEGER:
219 z = *outlen;
220 if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
221 goto LBL_ERR;
222 }
223 x += z;
224 *outlen -= z;
225 break;
226
227 case LTC_ASN1_BIT_STRING:
228 z = *outlen;
229 if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
230 goto LBL_ERR;
231 }
232 x += z;
233 *outlen -= z;
234 break;
235
236 case LTC_ASN1_RAW_BIT_STRING:
237 z = *outlen;
238 if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
239 goto LBL_ERR;
240 }
241 x += z;
242 *outlen -= z;
243 break;
244
245 case LTC_ASN1_OCTET_STRING:
246 z = *outlen;
247 if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
248 goto LBL_ERR;
249 }
250 x += z;
251 *outlen -= z;
252 break;
253
254 case LTC_ASN1_NULL:
255 out[x++] = 0x05;
256 out[x++] = 0x00;
257 *outlen -= 2;
258 break;
259
260 case LTC_ASN1_OBJECT_IDENTIFIER:
261 z = *outlen;
262 if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
263 goto LBL_ERR;
264 }
265 x += z;
266 *outlen -= z;
267 break;
268
269 case LTC_ASN1_IA5_STRING:
270 z = *outlen;
271 if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
272 goto LBL_ERR;
273 }
274 x += z;
275 *outlen -= z;
276 break;
277
278 case LTC_ASN1_PRINTABLE_STRING:
279 z = *outlen;
280 if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
281 goto LBL_ERR;
282 }
283 x += z;
284 *outlen -= z;
285 break;
286
287 case LTC_ASN1_UTF8_STRING:
288 z = *outlen;
289 if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
290 goto LBL_ERR;
291 }
292 x += z;
293 *outlen -= z;
294 break;
295
296 case LTC_ASN1_UTCTIME:
297 z = *outlen;
298 if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
299 goto LBL_ERR;
300 }
301 x += z;
302 *outlen -= z;
303 break;
304
305 case LTC_ASN1_SET:
306 z = *outlen;
307 if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
308 goto LBL_ERR;
309 }
310 x += z;
311 *outlen -= z;
312 break;
313
314 case LTC_ASN1_SETOF:
315 z = *outlen;
316 if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
317 goto LBL_ERR;
318 }
319 x += z;
320 *outlen -= z;
321 break;
322
323 case LTC_ASN1_SEQUENCE:
324 z = *outlen;
325 if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
326 goto LBL_ERR;
327 }
328 x += z;
329 *outlen -= z;
330 break;
331
332 default:
333 err = CRYPT_INVALID_ARG;
334 goto LBL_ERR;
335 }
336 }
337 *outlen = x;
338 err = CRYPT_OK;
339
340 LBL_ERR:
341 return err;
342 }
343
344 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11 #include <stdarg.h>
12
13
14 /**
15 @file der_encode_sequence_multi.c
16 ASN.1 DER, encode a SEQUENCE, Tom St Denis
17 */
18
19 #ifdef LTC_DER
20
21 /**
22 Encode a SEQUENCE type using a VA list
23 @param out [out] Destination for data
24 @param outlen [in/out] Length of buffer and resulting length of output
25 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
26 @return CRYPT_OK on success
27 */
28 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
29 {
30 int err, type;
31 unsigned long size, x;
32 void *data;
33 va_list args;
34 ltc_asn1_list *list;
35
36 LTC_ARGCHK(out != NULL);
37 LTC_ARGCHK(outlen != NULL);
38
39 /* get size of output that will be required */
40 va_start(args, outlen);
41 x = 0;
42 for (;;) {
43 type = va_arg(args, int);
44 size = va_arg(args, unsigned long);
45 data = va_arg(args, void*);
46
47 if (type == LTC_ASN1_EOL) {
48 break;
49 }
50
51 switch (type) {
52 case LTC_ASN1_BOOLEAN:
53 case LTC_ASN1_INTEGER:
54 case LTC_ASN1_SHORT_INTEGER:
55 case LTC_ASN1_BIT_STRING:
56 case LTC_ASN1_OCTET_STRING:
57 case LTC_ASN1_NULL:
58 case LTC_ASN1_OBJECT_IDENTIFIER:
59 case LTC_ASN1_IA5_STRING:
60 case LTC_ASN1_PRINTABLE_STRING:
61 case LTC_ASN1_UTF8_STRING:
62 case LTC_ASN1_UTCTIME:
63 case LTC_ASN1_SEQUENCE:
64 case LTC_ASN1_SET:
65 case LTC_ASN1_SETOF:
66 case LTC_ASN1_RAW_BIT_STRING:
67 ++x;
68 break;
69
70 default:
71 va_end(args);
72 return CRYPT_INVALID_ARG;
73 }
74 }
75 va_end(args);
76
77 /* allocate structure for x elements */
78 if (x == 0) {
79 return CRYPT_NOP;
80 }
81
82 list = XCALLOC(sizeof(*list), x);
83 if (list == NULL) {
84 return CRYPT_MEM;
85 }
86
87 /* fill in the structure */
88 va_start(args, outlen);
89 x = 0;
90 for (;;) {
91 type = va_arg(args, int);
92 size = va_arg(args, unsigned long);
93 data = va_arg(args, void*);
94
95 if (type == LTC_ASN1_EOL) {
96 break;
97 }
98
99 switch (type) {
100 case LTC_ASN1_BOOLEAN:
101 case LTC_ASN1_INTEGER:
102 case LTC_ASN1_SHORT_INTEGER:
103 case LTC_ASN1_BIT_STRING:
104 case LTC_ASN1_OCTET_STRING:
105 case LTC_ASN1_NULL:
106 case LTC_ASN1_OBJECT_IDENTIFIER:
107 case LTC_ASN1_IA5_STRING:
108 case LTC_ASN1_PRINTABLE_STRING:
109 case LTC_ASN1_UTF8_STRING:
110 case LTC_ASN1_UTCTIME:
111 case LTC_ASN1_SEQUENCE:
112 case LTC_ASN1_SET:
113 case LTC_ASN1_SETOF:
114 case LTC_ASN1_RAW_BIT_STRING:
115 list[x].type = type;
116 list[x].size = size;
117 list[x++].data = data;
118 break;
119
120 default:
121 va_end(args);
122 err = CRYPT_INVALID_ARG;
123 goto LBL_ERR;
124 }
125 }
126 va_end(args);
127
128 err = der_encode_sequence(list, x, out, outlen);
129 LBL_ERR:
130 XFREE(list);
131 return err;
132 }
133
134 #endif
135
136
137 /* $Source$ */
138 /* $Revision$ */
139 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9 #include "tomcrypt.h"
10
11 /**
12 @file der_encode_sequence_multi.c
13 ASN.1 DER, encode a Subject Public Key structure --nmav
14 */
15
16 #ifdef LTC_DER
17
18 /* AlgorithmIdentifier := SEQUENCE {
19 * algorithm OBJECT IDENTIFIER,
20 * parameters ANY DEFINED BY algorithm
21 * }
22 *
23 * SubjectPublicKeyInfo := SEQUENCE {
24 * algorithm AlgorithmIdentifier,
25 * subjectPublicKey BIT STRING
26 * }
27 */
28 /**
29 Encode a SEQUENCE type using a VA list
30 @param out [out] Destination for data
31 @param outlen [in/out] Length of buffer and resulting length of output
32 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
33 @return CRYPT_OK on success
34 */
35 int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
36 unsigned int algorithm, void* public_key, unsigned long public_key_len,
37 unsigned long parameters_type, void* parameters, unsigned long parameters_len)
38 {
39 int err;
40 ltc_asn1_list alg_id[2];
41 oid_st oid;
42
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45
46 err = pk_get_oid(algorithm, &oid);
47 if (err != CRYPT_OK) {
48 return err;
49 }
50
51 alg_id[0].data = oid.OID;
52 alg_id[0].size = oid.OIDlen;
53 alg_id[0].type = LTC_ASN1_OBJECT_IDENTIFIER;
54
55 alg_id[1].data = parameters;
56 alg_id[1].size = parameters_len;
57 alg_id[1].type = parameters_type;
58
59 return der_encode_sequence_multi(out, outlen,
60 LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
61 LTC_ASN1_RAW_BIT_STRING, (unsigned long)(public_key_len*8), public_key,
62 LTC_ASN1_EOL, 0UL, NULL);
63
64 }
65
66 #endif
67
68
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_sequence.c
14 ASN.1 DER, length a SEQUENCE, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Get the length of a DER sequence
21 @param list The sequences of items in the SEQUENCE
22 @param inlen The number of items
23 @param outlen [out] The length required in octets to store it
24 @return CRYPT_OK on success
25 */
26 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
27 unsigned long *outlen)
28 {
29 int err, type;
30 unsigned long size, x, y, i;
31 void *data;
32
33 LTC_ARGCHK(list != NULL);
34 LTC_ARGCHK(outlen != NULL);
35
36 /* get size of output that will be required */
37 y = 0;
38 for (i = 0; i < inlen; i++) {
39 type = list[i].type;
40 size = list[i].size;
41 data = list[i].data;
42
43 if (type == LTC_ASN1_EOL) {
44 break;
45 }
46
47 switch (type) {
48 case LTC_ASN1_BOOLEAN:
49 if ((err = der_length_boolean(&x)) != CRYPT_OK) {
50 goto LBL_ERR;
51 }
52 y += x;
53 break;
54
55 case LTC_ASN1_INTEGER:
56 if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
57 goto LBL_ERR;
58 }
59 y += x;
60 break;
61
62 case LTC_ASN1_SHORT_INTEGER:
63 if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) {
64 goto LBL_ERR;
65 }
66 y += x;
67 break;
68
69 case LTC_ASN1_BIT_STRING:
70 if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
71 goto LBL_ERR;
72 }
73 y += x;
74 break;
75
76 case LTC_ASN1_OCTET_STRING:
77 if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80 y += x;
81 break;
82
83 case LTC_ASN1_NULL:
84 y += 2;
85 break;
86
87 case LTC_ASN1_OBJECT_IDENTIFIER:
88 if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
89 goto LBL_ERR;
90 }
91 y += x;
92 break;
93
94 case LTC_ASN1_IA5_STRING:
95 if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
96 goto LBL_ERR;
97 }
98 y += x;
99 break;
100
101 case LTC_ASN1_PRINTABLE_STRING:
102 if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
103 goto LBL_ERR;
104 }
105 y += x;
106 break;
107
108 case LTC_ASN1_UTCTIME:
109 if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
110 goto LBL_ERR;
111 }
112 y += x;
113 break;
114
115 case LTC_ASN1_UTF8_STRING:
116 if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
117 goto LBL_ERR;
118 }
119 y += x;
120 break;
121
122 case LTC_ASN1_SET:
123 case LTC_ASN1_SETOF:
124 case LTC_ASN1_SEQUENCE:
125 if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
126 goto LBL_ERR;
127 }
128 y += x;
129 break;
130
131
132 default:
133 err = CRYPT_INVALID_ARG;
134 goto LBL_ERR;
135 }
136 }
137
138 /* calc header size */
139 if (y < 128) {
140 y += 2;
141 } else if (y < 256) {
142 /* 0x30 0x81 LL */
143 y += 3;
144 } else if (y < 65536UL) {
145 /* 0x30 0x82 LL LL */
146 y += 4;
147 } else if (y < 16777216UL) {
148 /* 0x30 0x83 LL LL LL */
149 y += 5;
150 } else {
151 err = CRYPT_INVALID_ARG;
152 goto LBL_ERR;
153 }
154
155 /* store size */
156 *outlen = y;
157 err = CRYPT_OK;
158
159 LBL_ERR:
160 return err;
161 }
162
163 #endif
164
165 /* $Source$ */
166 /* $Revision$ */
167 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_sequence_free.c
14 ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Free memory allocated by der_decode_sequence_flexi()
21 @param in The list to free
22 */
23 void der_sequence_free(ltc_asn1_list *in)
24 {
25 ltc_asn1_list *l;
26
27 if (!in) return;
28
29 /* walk to the start of the chain */
30 while (in->prev != NULL || in->parent != NULL) {
31 if (in->parent != NULL) {
32 in = in->parent;
33 } else {
34 in = in->prev;
35 }
36 }
37
38 /* now walk the list and free stuff */
39 while (in != NULL) {
40 /* is there a child? */
41 if (in->child) {
42 /* disconnect */
43 in->child->parent = NULL;
44 der_sequence_free(in->child);
45 }
46
47 switch (in->type) {
48 case LTC_ASN1_SET:
49 case LTC_ASN1_SETOF:
50 case LTC_ASN1_SEQUENCE: break;
51 case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break;
52 default : if (in->data != NULL) { XFREE(in->data); }
53 }
54
55 /* move to next and free current */
56 l = in->next;
57 XFREE(in);
58 in = l;
59 }
60 }
61
62 #endif
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_set.c
14 ASN.1 DER, Encode a SET, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /* LTC define to ASN.1 TAG */
20 static int ltc_to_asn1(int v)
21 {
22 switch (v) {
23 case LTC_ASN1_BOOLEAN: return 0x01;
24 case LTC_ASN1_INTEGER:
25 case LTC_ASN1_SHORT_INTEGER: return 0x02;
26 case LTC_ASN1_BIT_STRING: return 0x03;
27 case LTC_ASN1_OCTET_STRING: return 0x04;
28 case LTC_ASN1_NULL: return 0x05;
29 case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06;
30 case LTC_ASN1_UTF8_STRING: return 0x0C;
31 case LTC_ASN1_PRINTABLE_STRING: return 0x13;
32 case LTC_ASN1_IA5_STRING: return 0x16;
33 case LTC_ASN1_UTCTIME: return 0x17;
34 case LTC_ASN1_SEQUENCE: return 0x30;
35 case LTC_ASN1_SET:
36 case LTC_ASN1_SETOF: return 0x31;
37 default: return -1;
38 }
39 }
40
41
42 static int qsort_helper(const void *a, const void *b)
43 {
44 ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
45 int r;
46
47 r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type);
48
49 /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */
50 if (r == 0) {
51 /* their order in the original list now determines the position */
52 return A->used - B->used;
53 } else {
54 return r;
55 }
56 }
57
58 /*
59 Encode a SET type
60 @param list The list of items to encode
61 @param inlen The number of items in the list
62 @param out [out] The destination
63 @param outlen [in/out] The size of the output
64 @return CRYPT_OK on success
65 */
66 int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
67 unsigned char *out, unsigned long *outlen)
68 {
69 ltc_asn1_list *copy;
70 unsigned long x;
71 int err;
72
73 /* make copy of list */
74 copy = XCALLOC(inlen, sizeof(*copy));
75 if (copy == NULL) {
76 return CRYPT_MEM;
77 }
78
79 /* fill in used member with index so we can fully sort it */
80 for (x = 0; x < inlen; x++) {
81 copy[x] = list[x];
82 copy[x].used = x;
83 }
84
85 /* sort it by the "type" field */
86 XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);
87
88 /* call der_encode_sequence_ex() */
89 err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);
90
91 /* free list */
92 XFREE(copy);
93
94 return err;
95 }
96
97
98 #endif
99
100 /* $Source$ */
101 /* $Revision$ */
102 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_setof.c
14 ASN.1 DER, Encode SET OF, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 struct edge {
20 unsigned char *start;
21 unsigned long size;
22 };
23
24 static int qsort_helper(const void *a, const void *b)
25 {
26 struct edge *A = (struct edge *)a, *B = (struct edge *)b;
27 int r;
28 unsigned long x;
29
30 /* compare min length */
31 r = XMEMCMP(A->start, B->start, MIN(A->size, B->size));
32
33 if (r == 0 && A->size != B->size) {
34 if (A->size > B->size) {
35 for (x = B->size; x < A->size; x++) {
36 if (A->start[x]) {
37 return 1;
38 }
39 }
40 } else {
41 for (x = A->size; x < B->size; x++) {
42 if (B->start[x]) {
43 return -1;
44 }
45 }
46 }
47 }
48
49 return r;
50 }
51
52 /**
53 Encode a SETOF stucture
54 @param list The list of items to encode
55 @param inlen The number of items in the list
56 @param out [out] The destination
57 @param outlen [in/out] The size of the output
58 @return CRYPT_OK on success
59 */
60 int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
61 unsigned char *out, unsigned long *outlen)
62 {
63 unsigned long x, y, z, hdrlen;
64 int err;
65 struct edge *edges;
66 unsigned char *ptr, *buf;
67
68 /* check that they're all the same type */
69 for (x = 1; x < inlen; x++) {
70 if (list[x].type != list[x-1].type) {
71 return CRYPT_INVALID_ARG;
72 }
73 }
74
75 /* alloc buffer to store copy of output */
76 buf = XCALLOC(1, *outlen);
77 if (buf == NULL) {
78 return CRYPT_MEM;
79 }
80
81 /* encode list */
82 if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) {
83 XFREE(buf);
84 return err;
85 }
86
87 /* allocate edges */
88 edges = XCALLOC(inlen, sizeof(*edges));
89 if (edges == NULL) {
90 XFREE(buf);
91 return CRYPT_MEM;
92 }
93
94 /* skip header */
95 ptr = buf + 1;
96
97 /* now skip length data */
98 x = *ptr++;
99 if (x >= 0x80) {
100 ptr += (x & 0x7F);
101 }
102
103 /* get the size of the static header */
104 hdrlen = (unsigned long)(ptr - buf);
105
106
107 /* scan for edges */
108 x = 0;
109 while (ptr < (buf + *outlen)) {
110 /* store start */
111 edges[x].start = ptr;
112
113 /* skip type */
114 z = 1;
115
116 /* parse length */
117 y = ptr[z++];
118 if (y < 128) {
119 edges[x].size = y;
120 } else {
121 y &= 0x7F;
122 edges[x].size = 0;
123 while (y--) {
124 edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]);
125 }
126 }
127
128 /* skip content */
129 edges[x].size += z;
130 ptr += edges[x].size;
131 ++x;
132 }
133
134 /* sort based on contents (using edges) */
135 XQSORT(edges, inlen, sizeof(*edges), &qsort_helper);
136
137 /* copy static header */
138 XMEMCPY(out, buf, hdrlen);
139
140 /* copy+sort using edges+indecies to output from buffer */
141 for (y = hdrlen, x = 0; x < inlen; x++) {
142 XMEMCPY(out+y, edges[x].start, edges[x].size);
143 y += edges[x].size;
144 }
145
146 #ifdef LTC_CLEAN_STACK
147 zeromem(buf, *outlen);
148 #endif
149
150 /* free buffers */
151 XFREE(edges);
152 XFREE(buf);
153
154 return CRYPT_OK;
155 }
156
157 #endif
158
159 /* $Source$ */
160 /* $Revision$ */
161 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_short_integer.c
14 ASN.1 DER, decode an integer, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Read a short integer
22 @param in The DER encoded data
23 @param inlen Size of data
24 @param num [out] The integer to decode
25 @return CRYPT_OK if successful
26 */
27 int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num)
28 {
29 unsigned long len, x, y;
30
31 LTC_ARGCHK(num != NULL);
32 LTC_ARGCHK(in != NULL);
33
34 /* check length */
35 if (inlen < 2) {
36 return CRYPT_INVALID_PACKET;
37 }
38
39 /* check header */
40 x = 0;
41 if ((in[x++] & 0x1F) != 0x02) {
42 return CRYPT_INVALID_PACKET;
43 }
44
45 /* get the packet len */
46 len = in[x++];
47
48 if (x + len > inlen) {
49 return CRYPT_INVALID_PACKET;
50 }
51
52 /* read number */
53 y = 0;
54 while (len--) {
55 y = (y<<8) | (unsigned long)in[x++];
56 }
57 *num = y;
58
59 return CRYPT_OK;
60
61 }
62
63 #endif
64
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_short_integer.c
14 ASN.1 DER, encode an integer, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a short integer in the range (0,2^32-1)
22 @param num The integer to encode
23 @param out [out] The destination for the DER encoded integers
24 @param outlen [in/out] The max size and resulting size of the DER encoded integers
25 @return CRYPT_OK if successful
26 */
27 int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen)
28 {
29 unsigned long len, x, y, z;
30 int err;
31
32 LTC_ARGCHK(out != NULL);
33 LTC_ARGCHK(outlen != NULL);
34
35 /* force to 32 bits */
36 num &= 0xFFFFFFFFUL;
37
38 /* find out how big this will be */
39 if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) {
40 return err;
41 }
42
43 if (*outlen < len) {
44 *outlen = len;
45 return CRYPT_BUFFER_OVERFLOW;
46 }
47
48 /* get len of output */
49 z = 0;
50 y = num;
51 while (y) {
52 ++z;
53 y >>= 8;
54 }
55
56 /* handle zero */
57 if (z == 0) {
58 z = 1;
59 }
60
61 /* see if msb is set */
62 z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
63
64 /* adjust the number so the msB is non-zero */
65 for (x = 0; (z <= 4) && (x < (4 - z)); x++) {
66 num <<= 8;
67 }
68
69 /* store header */
70 x = 0;
71 out[x++] = 0x02;
72 out[x++] = (unsigned char)z;
73
74 /* if 31st bit is set output a leading zero and decrement count */
75 if (z == 5) {
76 out[x++] = 0;
77 --z;
78 }
79
80 /* store values */
81 for (y = 0; y < z; y++) {
82 out[x++] = (unsigned char)((num >> 24) & 0xFF);
83 num <<= 8;
84 }
85
86 /* we good */
87 *outlen = x;
88
89 return CRYPT_OK;
90 }
91
92 #endif
93
94 /* $Source$ */
95 /* $Revision$ */
96 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_short_integer.c
14 ASN.1 DER, get length of encoding, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19 /**
20 Gets length of DER encoding of num
21 @param num The integer to get the size of
22 @param outlen [out] The length of the DER encoding for the given integer
23 @return CRYPT_OK if successful
24 */
25 int der_length_short_integer(unsigned long num, unsigned long *outlen)
26 {
27 unsigned long z, y, len;
28
29 LTC_ARGCHK(outlen != NULL);
30
31 /* force to 32 bits */
32 num &= 0xFFFFFFFFUL;
33
34 /* get the number of bytes */
35 z = 0;
36 y = num;
37 while (y) {
38 ++z;
39 y >>= 8;
40 }
41
42 /* handle zero */
43 if (z == 0) {
44 z = 1;
45 }
46
47 /* we need a 0x02 to indicate it's INTEGER */
48 len = 1;
49
50 /* length byte */
51 ++len;
52
53 /* bytes in value */
54 len += z;
55
56 /* see if msb is set */
57 len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
58
59 /* return length */
60 *outlen = len;
61
62 return CRYPT_OK;
63 }
64
65 #endif
66
67 /* $Source$ */
68 /* $Revision$ */
69 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_teletex_string.c
14 ASN.1 DER, encode a teletex STRING
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Store a teletex STRING
21 @param in The DER encoded teletex STRING
22 @param inlen The size of the DER teletex STRING
23 @param out [out] The array of octets stored (one per char)
24 @param outlen [in/out] The number of octets stored
25 @return CRYPT_OK if successful
26 */
27 int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
28 unsigned char *out, unsigned long *outlen)
29 {
30 unsigned long x, y, len;
31 int t;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* must have header at least */
38 if (inlen < 2) {
39 return CRYPT_INVALID_PACKET;
40 }
41
42 /* check for 0x13 */
43 if ((in[0] & 0x1F) != 0x14) {
44 return CRYPT_INVALID_PACKET;
45 }
46 x = 1;
47
48 /* decode the length */
49 if (in[x] & 0x80) {
50 /* valid # of bytes in length are 1,2,3 */
51 y = in[x] & 0x7F;
52 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
53 return CRYPT_INVALID_PACKET;
54 }
55
56 /* read the length in */
57 len = 0;
58 ++x;
59 while (y--) {
60 len = (len << 8) | in[x++];
61 }
62 } else {
63 len = in[x++] & 0x7F;
64 }
65
66 /* is it too long? */
67 if (len > *outlen) {
68 *outlen = len;
69 return CRYPT_BUFFER_OVERFLOW;
70 }
71
72 if (len + x > inlen) {
73 return CRYPT_INVALID_PACKET;
74 }
75
76 /* read the data */
77 for (y = 0; y < len; y++) {
78 t = der_teletex_value_decode(in[x++]);
79 if (t == -1) {
80 return CRYPT_INVALID_ARG;
81 }
82 out[y] = t;
83 }
84
85 *outlen = y;
86
87 return CRYPT_OK;
88 }
89
90 #endif
91
92 /* $Source$ */
93 /* $Revision$ */
94 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_teletex_string.c
14 ASN.1 DER, get length of teletex STRING
15 */
16
17 #ifdef LTC_DER
18
19 static const struct {
20 int code, value;
21 } teletex_table[] = {
22 { '\0', 0 },
23 { '\a', 7 },
24 { '\b', 8 },
25 { '\t', 9 },
26 { '\n', 10 },
27 { '\v', 11 },
28 { '\f', 12 },
29 { '\r', 13 },
30 { ' ', 32 },
31 { '!', 33 },
32 { '"', 34 },
33 { '%', 37 },
34 { '&', 38 },
35 { '\'', 39 },
36 { '(', 40 },
37 { ')', 41 },
38 { '+', 43 },
39 { ',', 44 },
40 { '-', 45 },
41 { '.', 46 },
42 { '/', 47 },
43 { '0', 48 },
44 { '1', 49 },
45 { '2', 50 },
46 { '3', 51 },
47 { '4', 52 },
48 { '5', 53 },
49 { '6', 54 },
50 { '7', 55 },
51 { '8', 56 },
52 { '9', 57 },
53 { ':', 58 },
54 { ';', 59 },
55 { '<', 60 },
56 { '=', 61 },
57 { '>', 62 },
58 { '?', 63 },
59 { '@', 64 },
60 { 'A', 65 },
61 { 'B', 66 },
62 { 'C', 67 },
63 { 'D', 68 },
64 { 'E', 69 },
65 { 'F', 70 },
66 { 'G', 71 },
67 { 'H', 72 },
68 { 'I', 73 },
69 { 'J', 74 },
70 { 'K', 75 },
71 { 'L', 76 },
72 { 'M', 77 },
73 { 'N', 78 },
74 { 'O', 79 },
75 { 'P', 80 },
76 { 'Q', 81 },
77 { 'R', 82 },
78 { 'S', 83 },
79 { 'T', 84 },
80 { 'U', 85 },
81 { 'V', 86 },
82 { 'W', 87 },
83 { 'X', 88 },
84 { 'Y', 89 },
85 { 'Z', 90 },
86 { '[', 91 },
87 { ']', 93 },
88 { '_', 95 },
89 { 'a', 97 },
90 { 'b', 98 },
91 { 'c', 99 },
92 { 'd', 100 },
93 { 'e', 101 },
94 { 'f', 102 },
95 { 'g', 103 },
96 { 'h', 104 },
97 { 'i', 105 },
98 { 'j', 106 },
99 { 'k', 107 },
100 { 'l', 108 },
101 { 'm', 109 },
102 { 'n', 110 },
103 { 'o', 111 },
104 { 'p', 112 },
105 { 'q', 113 },
106 { 'r', 114 },
107 { 's', 115 },
108 { 't', 116 },
109 { 'u', 117 },
110 { 'v', 118 },
111 { 'w', 119 },
112 { 'x', 120 },
113 { 'y', 121 },
114 { 'z', 122 },
115 { '|', 124 },
116 { ' ', 160 },
117 { 0xa1, 161 },
118 { 0xa2, 162 },
119 { 0xa3, 163 },
120 { '$', 164 },
121 { 0xa5, 165 },
122 { '#', 166 },
123 { 0xa7, 167 },
124 { 0xa4, 168 },
125 { 0xab, 171 },
126 { 0xb0, 176 },
127 { 0xb1, 177 },
128 { 0xb2, 178 },
129 { 0xb3, 179 },
130 { 0xd7, 180 },
131 { 0xb5, 181 },
132 { 0xb6, 182 },
133 { 0xb7, 183 },
134 { 0xf7, 184 },
135 { 0xbb, 187 },
136 { 0xbc, 188 },
137 { 0xbd, 189 },
138 { 0xbe, 190 },
139 { 0xbf, 191 },
140 };
141
142 int der_teletex_char_encode(int c)
143 {
144 int x;
145 for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) {
146 if (teletex_table[x].code == c) {
147 return teletex_table[x].value;
148 }
149 }
150 return -1;
151 }
152
153 int der_teletex_value_decode(int v)
154 {
155 int x;
156 for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) {
157 if (teletex_table[x].value == v) {
158 return teletex_table[x].code;
159 }
160 }
161 return -1;
162 }
163
164 /**
165 Gets length of DER encoding of teletex STRING
166 @param octets The values you want to encode
167 @param noctets The number of octets in the string to encode
168 @param outlen [out] The length of the DER encoding for the given string
169 @return CRYPT_OK if successful
170 */
171 int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
172 {
173 unsigned long x;
174
175 LTC_ARGCHK(outlen != NULL);
176 LTC_ARGCHK(octets != NULL);
177
178 /* scan string for validity */
179 for (x = 0; x < noctets; x++) {
180 if (der_teletex_char_encode(octets[x]) == -1) {
181 return CRYPT_INVALID_ARG;
182 }
183 }
184
185 if (noctets < 128) {
186 /* 16 LL DD DD DD ... */
187 *outlen = 2 + noctets;
188 } else if (noctets < 256) {
189 /* 16 81 LL DD DD DD ... */
190 *outlen = 3 + noctets;
191 } else if (noctets < 65536UL) {
192 /* 16 82 LL LL DD DD DD ... */
193 *outlen = 4 + noctets;
194 } else if (noctets < 16777216UL) {
195 /* 16 83 LL LL LL DD DD DD ... */
196 *outlen = 5 + noctets;
197 } else {
198 return CRYPT_INVALID_ARG;
199 }
200
201 return CRYPT_OK;
202 }
203
204 #endif
205
206
207 /* $Source$ */
208 /* $Revision$ */
209 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_utctime.c
14 ASN.1 DER, decode a UTCTIME, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static int char_to_int(unsigned char x)
20 {
21 switch (x) {
22 case '0': return 0;
23 case '1': return 1;
24 case '2': return 2;
25 case '3': return 3;
26 case '4': return 4;
27 case '5': return 5;
28 case '6': return 6;
29 case '7': return 7;
30 case '8': return 8;
31 case '9': return 9;
32 }
33 return 100;
34 }
35
36 #define DECODE_V(y, max) \
37 y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \
38 if (y >= max) return CRYPT_INVALID_PACKET; \
39 x += 2;
40
41 /**
42 Decodes a UTC time structure in DER format (reads all 6 valid encoding formats)
43 @param in Input buffer
44 @param inlen Length of input buffer in octets
45 @param out [out] Destination of UTC time structure
46 @return CRYPT_OK if successful
47 */
48 int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
49 ltc_utctime *out)
50 {
51 unsigned char buf[32];
52 unsigned long x;
53 int y;
54
55 LTC_ARGCHK(in != NULL);
56 LTC_ARGCHK(inlen != NULL);
57 LTC_ARGCHK(out != NULL);
58
59 /* check header */
60 if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) {
61 return CRYPT_INVALID_PACKET;
62 }
63
64 /* decode the string */
65 for (x = 0; x < in[1]; x++) {
66 y = der_ia5_value_decode(in[x+2]);
67 if (y == -1) {
68 return CRYPT_INVALID_PACKET;
69 }
70 buf[x] = y;
71 }
72 *inlen = 2 + x;
73
74
75 /* possible encodings are
76 YYMMDDhhmmZ
77 YYMMDDhhmm+hh'mm'
78 YYMMDDhhmm-hh'mm'
79 YYMMDDhhmmssZ
80 YYMMDDhhmmss+hh'mm'
81 YYMMDDhhmmss-hh'mm'
82
83 So let's do a trivial decode upto [including] mm
84 */
85
86 x = 0;
87 DECODE_V(out->YY, 100);
88 DECODE_V(out->MM, 13);
89 DECODE_V(out->DD, 32);
90 DECODE_V(out->hh, 24);
91 DECODE_V(out->mm, 60);
92
93 /* clear timezone and seconds info */
94 out->off_dir = out->off_hh = out->off_mm = out->ss = 0;
95
96 /* now is it Z, +, - or 0-9 */
97 if (buf[x] == 'Z') {
98 return CRYPT_OK;
99 } else if (buf[x] == '+' || buf[x] == '-') {
100 out->off_dir = (buf[x++] == '+') ? 0 : 1;
101 DECODE_V(out->off_hh, 24);
102 DECODE_V(out->off_mm, 60);
103 return CRYPT_OK;
104 }
105
106 /* decode seconds */
107 DECODE_V(out->ss, 60);
108
109 /* now is it Z, +, - */
110 if (buf[x] == 'Z') {
111 return CRYPT_OK;
112 } else if (buf[x] == '+' || buf[x] == '-') {
113 out->off_dir = (buf[x++] == '+') ? 0 : 1;
114 DECODE_V(out->off_hh, 24);
115 DECODE_V(out->off_mm, 60);
116 return CRYPT_OK;
117 } else {
118 return CRYPT_INVALID_PACKET;
119 }
120 }
121
122 #endif
123
124 /* $Source$ */
125 /* $Revision$ */
126 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_utctime.c
14 ASN.1 DER, encode a UTCTIME, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 static const char *baseten = "0123456789";
20
21 #define STORE_V(y) \
22 out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
23 out[x++] = der_ia5_char_encode(baseten[y % 10]);
24
25 /**
26 Encodes a UTC time structure in DER format
27 @param utctime The UTC time structure to encode
28 @param out The destination of the DER encoding of the UTC time structure
29 @param outlen [in/out] The length of the DER encoding
30 @return CRYPT_OK if successful
31 */
32 int der_encode_utctime(ltc_utctime *utctime,
33 unsigned char *out, unsigned long *outlen)
34 {
35 unsigned long x, tmplen;
36 int err;
37
38 LTC_ARGCHK(utctime != NULL);
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41
42 if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) {
43 return err;
44 }
45 if (tmplen > *outlen) {
46 *outlen = tmplen;
47 return CRYPT_BUFFER_OVERFLOW;
48 }
49
50 /* store header */
51 out[0] = 0x17;
52
53 /* store values */
54 x = 2;
55 STORE_V(utctime->YY);
56 STORE_V(utctime->MM);
57 STORE_V(utctime->DD);
58 STORE_V(utctime->hh);
59 STORE_V(utctime->mm);
60 STORE_V(utctime->ss);
61
62 if (utctime->off_mm || utctime->off_hh) {
63 out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+');
64 STORE_V(utctime->off_hh);
65 STORE_V(utctime->off_mm);
66 } else {
67 out[x++] = der_ia5_char_encode('Z');
68 }
69
70 /* store length */
71 out[1] = (unsigned char)(x - 2);
72
73 /* all good let's return */
74 *outlen = x;
75 return CRYPT_OK;
76 }
77
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_utctime.c
14 ASN.1 DER, get length of UTCTIME, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20 Gets length of DER encoding of UTCTIME
21 @param utctime The UTC time structure to get the size of
22 @param outlen [out] The length of the DER encoding
23 @return CRYPT_OK if successful
24 */
25 int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen)
26 {
27 LTC_ARGCHK(outlen != NULL);
28 LTC_ARGCHK(utctime != NULL);
29
30 if (utctime->off_hh == 0 && utctime->off_mm == 0) {
31 /* we encode as YYMMDDhhmmssZ */
32 *outlen = 2 + 13;
33 } else {
34 /* we encode as YYMMDDhhmmss{+|-}hh'mm' */
35 *outlen = 2 + 17;
36 }
37
38 return CRYPT_OK;
39 }
40
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_decode_utf8_string.c
14 ASN.1 DER, encode a UTF8 STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store a UTF8 STRING
22 @param in The DER encoded UTF8 STRING
23 @param inlen The size of the DER UTF8 STRING
24 @param out [out] The array of utf8s stored (one per char)
25 @param outlen [in/out] The number of utf8s stored
26 @return CRYPT_OK if successful
27 */
28 int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
29 wchar_t *out, unsigned long *outlen)
30 {
31 wchar_t tmp;
32 unsigned long x, y, z, len;
33
34 LTC_ARGCHK(in != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* must have header at least */
39 if (inlen < 2) {
40 return CRYPT_INVALID_PACKET;
41 }
42
43 /* check for 0x0C */
44 if ((in[0] & 0x1F) != 0x0C) {
45 return CRYPT_INVALID_PACKET;
46 }
47 x = 1;
48
49 /* decode the length */
50 if (in[x] & 0x80) {
51 /* valid # of bytes in length are 1,2,3 */
52 y = in[x] & 0x7F;
53 if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* read the length in */
58 len = 0;
59 ++x;
60 while (y--) {
61 len = (len << 8) | in[x++];
62 }
63 } else {
64 len = in[x++] & 0x7F;
65 }
66
67 if (len + x > inlen) {
68 return CRYPT_INVALID_PACKET;
69 }
70
71 /* proceed to decode */
72 for (y = 0; x < inlen; ) {
73 /* get first byte */
74 tmp = in[x++];
75
76 /* count number of bytes */
77 for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF);
78
79 if (z > 4 || (x + (z - 1) > inlen)) {
80 return CRYPT_INVALID_PACKET;
81 }
82
83 /* decode, grab upper bits */
84 tmp >>= z;
85
86 /* grab remaining bytes */
87 if (z > 1) { --z; }
88 while (z-- != 0) {
89 if ((in[x] & 0xC0) != 0x80) {
90 return CRYPT_INVALID_PACKET;
91 }
92 tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F);
93 }
94
95 if (y > *outlen) {
96 *outlen = y;
97 return CRYPT_BUFFER_OVERFLOW;
98 }
99 out[y++] = tmp;
100 }
101 *outlen = y;
102
103 return CRYPT_OK;
104 }
105
106 #endif
107
108 /* $Source$ */
109 /* $Revision$ */
110 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_encode_utf8_string.c
14 ASN.1 DER, encode a UTF8 STRING, Tom St Denis
15 */
16
17
18 #ifdef LTC_DER
19
20 /**
21 Store an UTF8 STRING
22 @param in The array of UTF8 to store (one per wchar_t)
23 @param inlen The number of UTF8 to store
24 @param out [out] The destination for the DER encoded UTF8 STRING
25 @param outlen [in/out] The max size and resulting size of the DER UTF8 STRING
26 @return CRYPT_OK if successful
27 */
28 int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long x, y, len;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(out != NULL);
35 LTC_ARGCHK(outlen != NULL);
36
37 /* get the size */
38 for (x = len = 0; x < inlen; x++) {
39 if (in[x] < 0 || in[x] > 0x1FFFF) {
40 return CRYPT_INVALID_ARG;
41 }
42 len += der_utf8_charsize(in[x]);
43 }
44
45 if (len < 128) {
46 y = 2 + len;
47 } else if (len < 256) {
48 y = 3 + len;
49 } else if (len < 65536UL) {
50 y = 4 + len;
51 } else if (len < 16777216UL) {
52 y = 5 + len;
53 } else {
54 return CRYPT_INVALID_ARG;
55 }
56
57 /* too big? */
58 if (y > *outlen) {
59 *outlen = len;
60 return CRYPT_BUFFER_OVERFLOW;
61 }
62
63 /* encode the header+len */
64 x = 0;
65 out[x++] = 0x0C;
66 if (len < 128) {
67 out[x++] = (unsigned char)len;
68 } else if (len < 256) {
69 out[x++] = 0x81;
70 out[x++] = (unsigned char)len;
71 } else if (len < 65536UL) {
72 out[x++] = 0x82;
73 out[x++] = (unsigned char)((len>>8)&255);
74 out[x++] = (unsigned char)(len&255);
75 } else if (len < 16777216UL) {
76 out[x++] = 0x83;
77 out[x++] = (unsigned char)((len>>16)&255);
78 out[x++] = (unsigned char)((len>>8)&255);
79 out[x++] = (unsigned char)(len&255);
80 } else {
81 return CRYPT_INVALID_ARG;
82 }
83
84 /* store UTF8 */
85 for (y = 0; y < inlen; y++) {
86 switch (der_utf8_charsize(in[y])) {
87 case 1: out[x++] = (unsigned char)in[y]; break;
88 case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break;
89 case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
90 case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
91 }
92 }
93
94 /* retun length */
95 *outlen = x;
96
97 return CRYPT_OK;
98 }
99
100 #endif
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file der_length_utf8_string.c
14 ASN.1 DER, get length of UTF8 STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /** Return the size in bytes of a UTF-8 character
20 @param c The UTF-8 character to measure
21 @return The size in bytes
22 */
23 unsigned long der_utf8_charsize(const wchar_t c)
24 {
25 if (c <= 0x7F) {
26 return 1;
27 } else if (c <= 0x7FF) {
28 return 2;
29 } else if (c <= 0xFFFF) {
30 return 3;
31 } else {
32 return 4;
33 }
34 }
35
36 /**
37 Gets length of DER encoding of UTF8 STRING
38 @param in The characters to measure the length of
39 @param noctets The number of octets in the string to encode
40 @param outlen [out] The length of the DER encoding for the given string
41 @return CRYPT_OK if successful
42 */
43 int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen)
44 {
45 unsigned long x, len;
46
47 LTC_ARGCHK(in != NULL);
48 LTC_ARGCHK(outlen != NULL);
49
50 len = 0;
51 for (x = 0; x < noctets; x++) {
52 if (in[x] < 0 || in[x] > 0x10FFFF) {
53 return CRYPT_INVALID_ARG;
54 }
55 len += der_utf8_charsize(in[x]);
56 }
57
58 if (len < 128) {
59 /* 0C LL DD DD DD ... */
60 *outlen = 2 + len;
61 } else if (len < 256) {
62 /* 0C 81 LL DD DD DD ... */
63 *outlen = 3 + len;
64 } else if (len < 65536UL) {
65 /* 0C 82 LL LL DD DD DD ... */
66 *outlen = 4 + len;
67 } else if (len < 16777216UL) {
68 /* 0C 83 LL LL LL DD DD DD ... */
69 *outlen = 5 + len;
70 } else {
71 return CRYPT_INVALID_ARG;
72 }
73
74 return CRYPT_OK;
75 }
76
77 #endif
78
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dh.c
14 DH crypto, Tom St Denis
15 */
16
17 #ifdef MDH
18
19 /* size of a packet header in bytes */
20 #define PACKET_SIZE 4
21
22 /* Section tags */
23 #define PACKET_SECT_DH 1
24
25 /* Subsection Tags for the first three sections */
26 #define PACKET_SUB_KEY 0
27 #define PACKET_SUB_ENCRYPTED 1
28 #define PACKET_SUB_SIGNED 2
29 #define PACKET_SUB_ENC_KEY 3
30
31 #define OUTPUT_BIGNUM(num, out, y, z) \
32 { \
33 if ((y + 4) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \
34 z = (unsigned long)mp_unsigned_bin_size(num); \
35 STORE32L(z, out+y); \
36 y += 4; \
37 if ((y + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \
38 if ((err = mp_to_unsigned_bin(num, out+y)) != CRYPT_OK) { return err; } \
39 y += z; \
40 }
41
42 #define INPUT_BIGNUM(num, in, x, y, inlen) \
43 { \
44 /* load value */ \
45 if ((y + 4) > inlen) { \
46 err = CRYPT_INVALID_PACKET; \
47 goto error; \
48 } \
49 LOAD32L(x, in+y); \
50 y += 4; \
51 \
52 /* sanity check... */ \
53 if ((x+y) > inlen) { \
54 err = CRYPT_INVALID_PACKET; \
55 goto error; \
56 } \
57 \
58 /* load it */ \
59 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != CRYPT_OK) {\
60 goto error; \
61 } \
62 y += x; \
63 }
64
65 static void packet_store_header(unsigned char *dst, int section, int subsection)
66 {
67 LTC_ARGCHK(dst != NULL);
68
69 /* store version number */
70 dst[0] = (unsigned char)(CRYPT&255);
71 dst[1] = (unsigned char)((CRYPT>>8)&255);
72
73 /* store section and subsection */
74 dst[2] = (unsigned char)(section & 255);
75 dst[3] = (unsigned char)(subsection & 255);
76
77 }
78
79 static int packet_valid_header(unsigned char *src, int section, int subsection)
80 {
81 unsigned long ver;
82
83 LTC_ARGCHK(src != NULL);
84
85 /* check version */
86 ver = ((unsigned long)src[0]) | ((unsigned long)src[1] << 8U);
87 if (CRYPT < ver) {
88 return CRYPT_INVALID_PACKET;
89 }
90
91 /* check section and subsection */
92 if (section != (int)src[2] || subsection != (int)src[3]) {
93 return CRYPT_INVALID_PACKET;
94 }
95
96 return CRYPT_OK;
97 }
98
99
100 /* max export size we'll encounter (smaller than this but lets round up a bit) */
101 #define DH_BUF_SIZE 1200
102
103 /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
104 static const struct {
105 int size;
106 char *name, *base, *prime;
107 } sets[] = {
108 #ifdef DH768
109 {
110 96,
111 "DH-768",
112 "4",
113 "F///////////////////////////////////////////////////////////"
114 "////////////////////////////////////////////////////////////"
115 "//////m3wvV"
116 },
117 #endif
118 #ifdef DH1024
119 {
120 128,
121 "DH-1024",
122 "4",
123 "F///////////////////////////////////////////////////////////"
124 "////////////////////////////////////////////////////////////"
125 "////////////////////////////////////////////////m3C47"
126 },
127 #endif
128 #ifdef DH1280
129 {
130 160,
131 "DH-1280",
132 "4",
133 "F///////////////////////////////////////////////////////////"
134 "////////////////////////////////////////////////////////////"
135 "////////////////////////////////////////////////////////////"
136 "//////////////////////////////m4kSN"
137 },
138 #endif
139 #ifdef DH1536
140 {
141 192,
142 "DH-1536",
143 "4",
144 "F///////////////////////////////////////////////////////////"
145 "////////////////////////////////////////////////////////////"
146 "////////////////////////////////////////////////////////////"
147 "////////////////////////////////////////////////////////////"
148 "////////////m5uqd"
149 },
150 #endif
151 #ifdef DH1792
152 {
153 224,
154 "DH-1792",
155 "4",
156 "F///////////////////////////////////////////////////////////"
157 "////////////////////////////////////////////////////////////"
158 "////////////////////////////////////////////////////////////"
159 "////////////////////////////////////////////////////////////"
160 "//////////////////////////////////////////////////////mT/sd"
161 },
162 #endif
163 #ifdef DH2048
164 {
165 256,
166 "DH-2048",
167 "4",
168 "3///////////////////////////////////////////////////////////"
169 "////////////////////////////////////////////////////////////"
170 "////////////////////////////////////////////////////////////"
171 "////////////////////////////////////////////////////////////"
172 "////////////////////////////////////////////////////////////"
173 "/////////////////////////////////////////m8MPh"
174 },
175 #endif
176 #ifdef DH2560
177 {
178 320,
179 "DH-2560",
180 "4",
181 "3///////////////////////////////////////////////////////////"
182 "////////////////////////////////////////////////////////////"
183 "////////////////////////////////////////////////////////////"
184 "////////////////////////////////////////////////////////////"
185 "////////////////////////////////////////////////////////////"
186 "////////////////////////////////////////////////////////////"
187 "////////////////////////////////////////////////////////////"
188 "/////mKFpF"
189 },
190 #endif
191 #ifdef DH3072
192 {
193 384,
194 "DH-3072",
195 "4",
196 "3///////////////////////////////////////////////////////////"
197 "////////////////////////////////////////////////////////////"
198 "////////////////////////////////////////////////////////////"
199 "////////////////////////////////////////////////////////////"
200 "////////////////////////////////////////////////////////////"
201 "////////////////////////////////////////////////////////////"
202 "////////////////////////////////////////////////////////////"
203 "////////////////////////////////////////////////////////////"
204 "/////////////////////////////m32nN"
205 },
206 #endif
207 #ifdef DH4096
208 {
209 512,
210 "DH-4096",
211 "4",
212 "////////////////////////////////////////////////////////////"
213 "////////////////////////////////////////////////////////////"
214 "////////////////////////////////////////////////////////////"
215 "////////////////////////////////////////////////////////////"
216 "////////////////////////////////////////////////////////////"
217 "////////////////////////////////////////////////////////////"
218 "////////////////////////////////////////////////////////////"
219 "////////////////////////////////////////////////////////////"
220 "////////////////////////////////////////////////////////////"
221 "////////////////////////////////////////////////////////////"
222 "////////////////////////////////////////////////////////////"
223 "/////////////////////m8pOF"
224 },
225 #endif
226 {
227 0,
228 NULL,
229 NULL,
230 NULL
231 }
232 };
233
234 static int is_valid_idx(int n)
235 {
236 int x;
237
238 for (x = 0; sets[x].size; x++);
239 if ((n < 0) || (n >= x)) {
240 return 0;
241 }
242 return 1;
243 }
244
245 /**
246 Test the DH sub-system (can take a while)
247 @return CRYPT_OK if successful
248 */
249 int dh_compat_test(void)
250 {
251 void *p, *g, *tmp;
252 int x, err, primality;
253
254 if ((err = mp_init_multi(&p, &g, &tmp, NULL)) != CRYPT_OK) { goto error; }
255
256 for (x = 0; sets[x].size != 0; x++) {
257 #if 0
258 printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
259 #endif
260 if ((err = mp_read_radix(g,(char *)sets[x].base, 64)) != CRYPT_OK) { goto error; }
261 if ((err = mp_read_radix(p,(char *)sets[x].prime, 64)) != CRYPT_OK) { goto error; }
262
263 /* ensure p is prime */
264 if ((err = mp_prime_is_prime(p, 8, &primality)) != CRYPT_OK) { goto done; }
265 if (primality != LTC_MP_YES ) {
266 err = CRYPT_FAIL_TESTVECTOR;
267 goto done;
268 }
269
270 if ((err = mp_sub_d(p, 1, tmp)) != CRYPT_OK) { goto error; }
271 if ((err = mp_div_2(tmp, tmp)) != CRYPT_OK) { goto error; }
272
273 /* ensure (p-1)/2 is prime */
274 if ((err = mp_prime_is_prime(tmp, 8, &primality)) != CRYPT_OK) { goto done; }
275 if (primality == 0) {
276 err = CRYPT_FAIL_TESTVECTOR;
277 goto done;
278 }
279
280 /* now see if g^((p-1)/2) mod p is in fact 1 */
281 if ((err = mp_exptmod(g, tmp, p, tmp)) != CRYPT_OK) { goto error; }
282 if (mp_cmp_d(tmp, 1)) {
283 err = CRYPT_FAIL_TESTVECTOR;
284 goto done;
285 }
286 }
287 err = CRYPT_OK;
288 error:
289 done:
290 mp_clear_multi(tmp, g, p, NULL);
291 return err;
292 }
293
294 /**
295 Get the min and max DH key sizes (octets)
296 @param low [out] The smallest key size supported
297 @param high [out] The largest key size supported
298 */
299 void dh_sizes(int *low, int *high)
300 {
301 int x;
302 LTC_ARGCHK(low != NULL);
303 LTC_ARGCHK(high != NULL);
304 *low = INT_MAX;
305 *high = 0;
306 for (x = 0; sets[x].size != 0; x++) {
307 if (*low > sets[x].size) *low = sets[x].size;
308 if (*high < sets[x].size) *high = sets[x].size;
309 }
310 }
311
312 /**
313 Returns the key size of a given DH key (octets)
314 @param key The DH key to get the size of
315 @return The size if valid or INT_MAX if not
316 */
317 int dh_get_size(dh_key *key)
318 {
319 LTC_ARGCHK(key != NULL);
320 if (is_valid_idx(key->idx) == 1) {
321 return sets[key->idx].size;
322 } else {
323 return INT_MAX; /* large value that would cause dh_make_key() to fail */
324 }
325 }
326
327 /**
328 Make a DH key [private key pair]
329 @param prng An active PRNG state
330 @param wprng The index for the PRNG you desire to use
331 @param keysize The key size (octets) desired
332 @param key [out] Where the newly created DH key will be stored
333 @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically.
334 */
335 int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
336 {
337 unsigned char *buf;
338 unsigned long x;
339 void *p, *g;
340 int err;
341
342 LTC_ARGCHK(key != NULL);
343
344 /* good prng? */
345 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
346 return err;
347 }
348
349 /* find key size */
350 for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
351 #ifdef FAST_PK
352 keysize = MIN(sets[x].size, 32);
353 #else
354 keysize = sets[x].size;
355 #endif
356 if (sets[x].size == 0) {
357 return CRYPT_INVALID_KEYSIZE;
358 }
359 key->idx = x;
360
361 /* allocate buffer */
362 buf = XMALLOC(keysize);
363 if (buf == NULL) {
364 return CRYPT_MEM;
365 }
366
367 /* make up random string */
368 if ( rng_make_prng( keysize, wprng, prng, NULL) != CRYPT_OK) {
369 err = CRYPT_ERROR_READPRNG;
370 goto error2;
371 }
372
373 if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) {
374 err = CRYPT_ERROR_READPRNG;
375 goto error2;
376 }
377
378 /* init parameters */
379 if ((err = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != CRYPT_OK) {
380 goto error;
381 }
382
383 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; }
384 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
385
386 /* load the x value */
387 if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; }
388 if ((err = mp_exptmod(g, key->x, p, key->y)) != CRYPT_OK) { goto error; }
389 key->type = PK_PRIVATE;
390
391 /* free up ram */
392 err = CRYPT_OK;
393 goto done;
394 error:
395 mp_clear_multi(key->x, key->y, NULL);
396 done:
397 mp_clear_multi(p, g, NULL);
398 error2:
399 #ifdef LTC_CLEAN_STACK
400 zeromem(buf, keysize);
401 #endif
402 XFREE(buf);
403 return err;
404 }
405
406 /**
407 Free the allocated ram for a DH key
408 @param key The key which you wish to free
409 */
410 void dh_free(dh_key *key)
411 {
412 LTC_ARGCHK(key != NULL);
413 if ( key->x ) {
414 mp_clear( key->x );
415 key->x = NULL;
416 }
417 if ( key->y ) {
418 mp_clear( key->y );
419 key->y = NULL;
420 }
421 }
422
423 /**
424 Export a DH key to a binary packet
425 @param out [out] The destination for the key
426 @param outlen [in/out] The max size and resulting size of the DH key
427 @param type Which type of key (PK_PRIVATE or PK_PUBLIC)
428 @param key The key you wish to export
429 @return CRYPT_OK if successful
430 */
431 int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
432 {
433 unsigned long y, z;
434 int err;
435
436 LTC_ARGCHK(out != NULL);
437 LTC_ARGCHK(outlen != NULL);
438 LTC_ARGCHK(key != NULL);
439
440 /* can we store the static header? */
441 if (*outlen < (PACKET_SIZE + 2)) {
442 return CRYPT_BUFFER_OVERFLOW;
443 }
444
445 if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
446 return CRYPT_PK_NOT_PRIVATE;
447 }
448
449 /* header */
450 y = PACKET_SIZE;
451
452 /* header */
453 out[y++] = type;
454 out[y++] = (unsigned char)(sets[key->idx].size / 8);
455
456 /* export y */
457 OUTPUT_BIGNUM(key->y, out, y, z);
458
459 if (type == PK_PRIVATE) {
460 /* export x */
461 OUTPUT_BIGNUM(key->x, out, y, z);
462 }
463
464 /* store header */
465 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_KEY);
466
467 /* store len */
468 *outlen = y;
469 return CRYPT_OK;
470 }
471
472 /**
473 Import a DH key from a binary packet
474 @param in The packet to read
475 @param inlen The length of the input packet
476 @param key [out] Where to import the key to
477 @return CRYPT_OK if successful, on error all allocated memory is freed automatically
478 */
479 int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
480 {
481 unsigned long x, y, s;
482 int err;
483
484 LTC_ARGCHK(in != NULL);
485 LTC_ARGCHK(key != NULL);
486
487 /* make sure valid length */
488 if ((2+PACKET_SIZE) > inlen) {
489 return CRYPT_INVALID_PACKET;
490 }
491
492 /* check type byte */
493 if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
494 return err;
495 }
496
497 /* init */
498 if ((err = mp_init_multi(&key->x, &key->y, NULL)) != CRYPT_OK) {
499 return err;
500 }
501
502 /* advance past packet header */
503 y = PACKET_SIZE;
504
505 /* key type, e.g. private, public */
506 key->type = (int)in[y++];
507
508 /* key size in bytes */
509 s = (unsigned long)in[y++] * 8;
510
511 for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
512 if (sets[x].size == 0) {
513 err = CRYPT_INVALID_KEYSIZE;
514 goto error;
515 }
516 key->idx = (int)x;
517
518 /* type check both values */
519 if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
520 err = CRYPT_PK_TYPE_MISMATCH;
521 goto error;
522 }
523
524 /* is the key idx valid? */
525 if (is_valid_idx(key->idx) != 1) {
526 err = CRYPT_PK_TYPE_MISMATCH;
527 goto error;
528 }
529
530 /* load public value g^x mod p*/
531 INPUT_BIGNUM(key->y, in, x, y, inlen);
532
533 if (key->type == PK_PRIVATE) {
534 INPUT_BIGNUM(key->x, in, x, y, inlen);
535 }
536
537 /* eliminate private key if public */
538 if (key->type == PK_PUBLIC) {
539 mp_clear(key->x);
540 key->x = NULL;
541 }
542
543 return CRYPT_OK;
544 error:
545 mp_clear_multi(key->y, key->x, NULL);
546 return err;
547 }
548
549 /**
550 Create a DH shared secret.
551 @param private_key The private DH key in the pair
552 @param public_key The public DH key in the pair
553 @param out [out] The destination of the shared data
554 @param outlen [in/out] The max size and resulting size of the shared data.
555 @return CRYPT_OK if successful
556 */
557 int dh_shared_secret(dh_key *private_key, dh_key *public_key,
558 unsigned char *out, unsigned long *outlen)
559 {
560 void *tmp, *p;
561 unsigned long x;
562 int err;
563
564 LTC_ARGCHK(private_key != NULL);
565 LTC_ARGCHK(public_key != NULL);
566 LTC_ARGCHK(out != NULL);
567 LTC_ARGCHK(outlen != NULL);
568
569 /* types valid? */
570 if (private_key->type != PK_PRIVATE) {
571 return CRYPT_PK_NOT_PRIVATE;
572 }
573
574 /* same idx? */
575 if (private_key->idx != public_key->idx) {
576 return CRYPT_PK_TYPE_MISMATCH;
577 }
578
579 /* compute y^x mod p */
580 if ((err = mp_init_multi(&tmp, &p, NULL)) != CRYPT_OK) {
581 return err;
582 }
583
584 if ((err = mp_read_radix(p, (char *)sets[private_key->idx].prime, 64)) != CRYPT_OK) { goto error; }
585 if ((err = mp_exptmod(public_key->y, private_key->x, p, tmp)) != CRYPT_OK) { goto error; }
586
587 /* enough space for output? */
588 x = (unsigned long)mp_unsigned_bin_size(tmp);
589 if (*outlen < x) {
590 err = CRYPT_BUFFER_OVERFLOW;
591 goto done;
592 }
593 if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { goto error; }
594 *outlen = x;
595 err = CRYPT_OK;
596 goto done;
597 error:
598 done:
599 mp_clear_multi(p, tmp, NULL);
600 return err;
601 }
602
603 #include "dh_sys.c.inc"
604
605 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
9 */
10
11 /**
12 @file dh_sys.c
13 DH Crypto, Tom St Denis
14 */
15
16 /**
17 Encrypt a short symmetric key with a public DH key
18 @param in The symmetric key to encrypt
19 @param inlen The length of the key (octets)
20 @param out [out] The ciphertext
21 @param outlen [in/out] The max size and resulting size of the ciphertext
22 @param prng An active PRNG state
23 @param wprng The index of the PRNG desired
24 @param hash The index of the hash desired (must produce a digest of size >= the size of the plaintext)
25 @param key The public key you wish to encrypt with.
26 @return CRYPT_OK if successful
27 */
28 int dh_encrypt_key(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen,
30 prng_state *prng, int wprng, int hash,
31 dh_key *key)
32 {
33 unsigned char *pub_expt, *dh_shared, *skey;
34 dh_key pubkey;
35 unsigned long x, y, z, pubkeysize;
36 int err;
37
38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41 LTC_ARGCHK(key != NULL);
42
43 /* check that wprng/hash are not invalid */
44 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
45 return err;
46 }
47
48 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
49 return err;
50 }
51
52 if (inlen > hash_descriptor[hash].hashsize) {
53 return CRYPT_INVALID_HASH;
54 }
55
56 /* allocate memory */
57 pub_expt = XMALLOC(DH_BUF_SIZE);
58 dh_shared = XMALLOC(DH_BUF_SIZE);
59 skey = XMALLOC(MAXBLOCKSIZE);
60 if (pub_expt == NULL || dh_shared == NULL || skey == NULL) {
61 if (pub_expt != NULL) {
62 XFREE(pub_expt);
63 }
64 if (dh_shared != NULL) {
65 XFREE(dh_shared);
66 }
67 if (skey != NULL) {
68 XFREE(skey);
69 }
70 return CRYPT_MEM;
71 }
72
73 /* make a random key and export the public copy */
74 if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77
78 pubkeysize = DH_BUF_SIZE;
79 if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
80 dh_free(&pubkey);
81 goto LBL_ERR;
82 }
83
84 /* now check if the out buffer is big enough */
85 if (*outlen < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + inlen)) {
86 dh_free(&pubkey);
87 err = CRYPT_BUFFER_OVERFLOW;
88 goto LBL_ERR;
89 }
90
91 /* make random key */
92
93 x = DH_BUF_SIZE;
94 if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) {
95 dh_free(&pubkey);
96 goto LBL_ERR;
97 }
98 dh_free(&pubkey);
99
100 z = MAXBLOCKSIZE;
101 if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104
105 /* store header */
106 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
107
108 /* output header */
109 y = PACKET_SIZE;
110
111 /* size of hash name and the name itself */
112 out[y++] = hash_descriptor[hash].ID;
113
114 /* length of DH pubkey and the key itself */
115 STORE32L(pubkeysize, out+y);
116 y += 4;
117 for (x = 0; x < pubkeysize; x++, y++) {
118 out[y] = pub_expt[x];
119 }
120
121 /* Store the encrypted key */
122 STORE32L(inlen, out+y);
123 y += 4;
124
125 for (x = 0; x < inlen; x++, y++) {
126 out[y] = skey[x] ^ in[x];
127 }
128 *outlen = y;
129
130 err = CRYPT_OK;
131 LBL_ERR:
132 #ifdef LTC_CLEAN_STACK
133 /* clean up */
134 zeromem(pub_expt, DH_BUF_SIZE);
135 zeromem(dh_shared, DH_BUF_SIZE);
136 zeromem(skey, MAXBLOCKSIZE);
137 #endif
138 XFREE(skey);
139 XFREE(dh_shared);
140 XFREE(pub_expt);
141
142 return err;
143 }
144
145 /**
146 Decrypt a DH encrypted symmetric key
147 @param in The DH encrypted packet
148 @param inlen The length of the DH encrypted packet
149 @param out The plaintext
150 @param outlen [in/out] The max size and resulting size of the plaintext
151 @param key The private DH key corresponding to the public key that encrypted the plaintext
152 @return CRYPT_OK if successful
153 */
154 int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
155 unsigned char *out, unsigned long *outlen,
156 dh_key *key)
157 {
158 unsigned char *shared_secret, *skey;
159 unsigned long x, y, z, keysize;
160 int hash, err;
161 dh_key pubkey;
162
163 LTC_ARGCHK(in != NULL);
164 LTC_ARGCHK(out != NULL);
165 LTC_ARGCHK(outlen != NULL);
166 LTC_ARGCHK(key != NULL);
167
168 /* right key type? */
169 if (key->type != PK_PRIVATE) {
170 return CRYPT_PK_NOT_PRIVATE;
171 }
172
173 /* allocate ram */
174 shared_secret = XMALLOC(DH_BUF_SIZE);
175 skey = XMALLOC(MAXBLOCKSIZE);
176 if (shared_secret == NULL || skey == NULL) {
177 if (shared_secret != NULL) {
178 XFREE(shared_secret);
179 }
180 if (skey != NULL) {
181 XFREE(skey);
182 }
183 return CRYPT_MEM;
184 }
185
186 /* check if initial header should fit */
187 if (inlen < PACKET_SIZE+1+4+4) {
188 err = CRYPT_INVALID_PACKET;
189 goto LBL_ERR;
190 } else {
191 inlen -= PACKET_SIZE+1+4+4;
192 }
193
194 /* is header correct? */
195 if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
196 goto LBL_ERR;
197 }
198
199 /* now lets get the hash name */
200 y = PACKET_SIZE;
201 hash = find_hash_id(in[y++]);
202 if (hash == -1) {
203 err = CRYPT_INVALID_HASH;
204 goto LBL_ERR;
205 }
206
207 /* get public key */
208 LOAD32L(x, in+y);
209
210 /* now check if the imported key will fit */
211 if (inlen < x) {
212 err = CRYPT_INVALID_PACKET;
213 goto LBL_ERR;
214 } else {
215 inlen -= x;
216 }
217
218 y += 4;
219 if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) {
220 goto LBL_ERR;
221 }
222 y += x;
223
224 /* make shared key */
225 x = DH_BUF_SIZE;
226 if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
227 dh_free(&pubkey);
228 goto LBL_ERR;
229 }
230 dh_free(&pubkey);
231
232 z = MAXBLOCKSIZE;
233 if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
234 goto LBL_ERR;
235 }
236
237 /* load in the encrypted key */
238 LOAD32L(keysize, in+y);
239
240 /* will the out fit as part of the input */
241 if (inlen < keysize) {
242 err = CRYPT_INVALID_PACKET;
243 goto LBL_ERR;
244 } else {
245 inlen -= keysize;
246 }
247
248 if (keysize > *outlen) {
249 err = CRYPT_BUFFER_OVERFLOW;
250 goto LBL_ERR;
251 }
252 y += 4;
253
254 *outlen = keysize;
255
256 for (x = 0; x < keysize; x++, y++) {
257 out[x] = skey[x] ^ in[y];
258 }
259
260 err = CRYPT_OK;
261 LBL_ERR:
262 #ifdef LTC_CLEAN_STACK
263 zeromem(shared_secret, DH_BUF_SIZE);
264 zeromem(skey, MAXBLOCKSIZE);
265 #endif
266
267 XFREE(skey);
268 XFREE(shared_secret);
269
270 return err;
271 }
272
273 /* perform an ElGamal Signature of a hash
274 *
275 * The math works as follows. x is the private key, M is the message to sign
276
277 1. pick a random k
278 2. compute a = g^k mod p
279 3. compute b = (M - xa)/k mod p
280 4. Send (a,b)
281
282 Now to verify with y=g^x mod p, a and b
283
284 1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k)
285 = g^(xa + (M - xa))
286 = g^M [all mod p]
287
288 2. Compare against g^M mod p [based on input hash].
289 3. If result of #2 == result of #1 then signature valid
290 */
291
292 /**
293 Sign a message digest using a DH private key
294 @param in The data to sign
295 @param inlen The length of the input (octets)
296 @param out [out] The destination of the signature
297 @param outlen [in/out] The max size and resulting size of the output
298 @param prng An active PRNG state
299 @param wprng The index of the PRNG desired
300 @param key A private DH key
301 @return CRYPT_OK if successful
302 */
303 int dh_sign_hash(const unsigned char *in, unsigned long inlen,
304 unsigned char *out, unsigned long *outlen,
305 prng_state *prng, int wprng, dh_key *key)
306 {
307 void *a, *b, *k, *m, *g, *p, *p1, *tmp;
308 unsigned char *buf;
309 unsigned long x, y;
310 int err;
311
312 LTC_ARGCHK(in != NULL);
313 LTC_ARGCHK(out != NULL);
314 LTC_ARGCHK(outlen != NULL);
315 LTC_ARGCHK(key != NULL);
316
317 /* check parameters */
318 if (key->type != PK_PRIVATE) {
319 return CRYPT_PK_NOT_PRIVATE;
320 }
321
322 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
323 return err;
324 }
325
326 /* is the IDX valid ? */
327 if (is_valid_idx(key->idx) != 1) {
328 return CRYPT_PK_INVALID_TYPE;
329 }
330
331 /* allocate ram for buf */
332 buf = XMALLOC(520);
333
334 /* make up a random value k,
335 * since the order of the group is prime
336 * we need not check if gcd(k, r) is 1
337 */
338 if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) !=
339 (unsigned long)(sets[key->idx].size)) {
340 err = CRYPT_ERROR_READPRNG;
341 goto LBL_ERR;
342 }
343
344 /* init bignums */
345 if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != CRYPT_OK) {
346 goto LBL_ERR;
347 }
348
349 /* load k and m */
350 if ((err = mp_read_unsigned_bin(m, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; }
351 if ((err = mp_read_unsigned_bin(k, buf, sets[key->idx].size)) != CRYPT_OK) { goto error; }
352
353 /* load g, p and p1 */
354 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; }
355 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
356 if ((err = mp_sub_d(p, 1, p1)) != CRYPT_OK) { goto error; }
357 if ((err = mp_div_2(p1, p1)) != CRYPT_OK) { goto error; } /* p1 = (p-1)/2 */
358
359 /* now get a = g^k mod p */
360 if ((err = mp_exptmod(g, k, p, a)) != CRYPT_OK) { goto error; }
361
362 /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */
363 if ((err = mp_invmod(k, p1, k)) != CRYPT_OK) { goto error; } /* k = 1/k mod p1 */
364 if ((err = mp_mulmod(a, key->x, p1, tmp)) != CRYPT_OK) { goto error; } /* tmp = xa */
365 if ((err = mp_submod(m, tmp, p1, tmp)) != CRYPT_OK) { goto error; } /* tmp = M - xa */
366 if ((err = mp_mulmod(k, tmp, p1, b)) != CRYPT_OK) { goto error; } /* b = (M - xa)/k */
367
368 /* check for overflow */
369 if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(a) + mp_unsigned_bin_size(b)) > *outlen) {
370 err = CRYPT_BUFFER_OVERFLOW;
371 goto LBL_ERR;
372 }
373
374 /* store header */
375 y = PACKET_SIZE;
376
377 /* now store them both (a,b) */
378 x = (unsigned long)mp_unsigned_bin_size(a);
379 STORE32L(x, out+y); y += 4;
380 if ((err = mp_to_unsigned_bin(a, out+y)) != CRYPT_OK) { goto error; }
381 y += x;
382
383 x = (unsigned long)mp_unsigned_bin_size(b);
384 STORE32L(x, out+y); y += 4;
385 if ((err = mp_to_unsigned_bin(b, out+y)) != CRYPT_OK) { goto error; }
386 y += x;
387
388 /* check if size too big */
389 if (*outlen < y) {
390 err = CRYPT_BUFFER_OVERFLOW;
391 goto LBL_ERR;
392 }
393
394 /* store header */
395 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED);
396 *outlen = y;
397
398 err = CRYPT_OK;
399 goto LBL_ERR;
400 error:
401 LBL_ERR:
402 mp_clear_multi(tmp, p1, g, p, m, k, b, a, NULL);
403
404 XFREE(buf);
405
406 return err;
407 }
408
409
410 /**
411 Verify the signature given
412 @param sig The signature
413 @param siglen The length of the signature (octets)
414 @param hash The hash that was signed
415 @param hashlen The length of the hash (octets)
416 @param stat [out] Result of signature comparison, 1==valid, 0==invalid
417 @param key The public DH key that signed the hash
418 @return CRYPT_OK if succsessful (even if signature is invalid)
419 */
420 int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
421 const unsigned char *hash, unsigned long hashlen,
422 int *stat, dh_key *key)
423 {
424 void *a, *b, *p, *g, *m, *tmp;
425 unsigned long x, y;
426 int err;
427
428 LTC_ARGCHK(sig != NULL);
429 LTC_ARGCHK(hash != NULL);
430 LTC_ARGCHK(stat != NULL);
431 LTC_ARGCHK(key != NULL);
432
433 /* default to invalid */
434 *stat = 0;
435
436 /* check initial input length */
437 if (siglen < PACKET_SIZE+4+4) {
438 return CRYPT_INVALID_PACKET;
439 }
440
441 /* header ok? */
442 if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) {
443 return err;
444 }
445
446 /* get hash out of packet */
447 y = PACKET_SIZE;
448
449 /* init all bignums */
450 if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != CRYPT_OK) {
451 return err;
452 }
453
454 /* load a and b */
455 INPUT_BIGNUM(a, sig, x, y, siglen);
456 INPUT_BIGNUM(b, sig, x, y, siglen);
457
458 /* load p and g */
459 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error1; }
460 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error1; }
461
462 /* load m */
463 if ((err = mp_read_unsigned_bin(m, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error1; }
464
465 /* find g^m mod p */
466 if ((err = mp_exptmod(g, m, p, m)) != CRYPT_OK) { goto error1; } /* m = g^m mod p */
467
468 /* find y^a * a^b */
469 if ((err = mp_exptmod(key->y, a, p, tmp)) != CRYPT_OK) { goto error1; } /* tmp = y^a mod p */
470 if ((err = mp_exptmod(a, b, p, a)) != CRYPT_OK) { goto error1; } /* a = a^b mod p */
471 if ((err = mp_mulmod(a, tmp, p, a)) != CRYPT_OK) { goto error1; } /* a = y^a * a^b mod p */
472
473 /* y^a * a^b == g^m ??? */
474 if (mp_cmp(a, m) == 0) {
475 *stat = 1;
476 }
477
478 /* clean up */
479 err = CRYPT_OK;
480 goto done;
481 error1:
482 error:
483 done:
484 mp_clear_multi(tmp, m, g, p, b, a, NULL);
485 return err;
486 }
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_decrypt_key.c
14 DSA Crypto, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Decrypt an DSA encrypted key
21 @param in The ciphertext
22 @param inlen The length of the ciphertext (octets)
23 @param out [out] The plaintext
24 @param outlen [in/out] The max size and resulting size of the plaintext
25 @param key The corresponding private DSA key
26 @return CRYPT_OK if successful
27 */
28 int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
29 unsigned char *out, unsigned long *outlen,
30 dsa_key *key)
31 {
32 unsigned char *skey, *expt;
33 void *g_pub;
34 unsigned long x, y, hashOID[32];
35 int hash, err;
36 ltc_asn1_list decode[3];
37
38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41 LTC_ARGCHK(key != NULL);
42
43 /* right key type? */
44 if (key->type != PK_PRIVATE) {
45 return CRYPT_PK_NOT_PRIVATE;
46 }
47
48 /* decode to find out hash */
49 LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
50
51 if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
52 return err;
53 }
54
55 hash = find_hash_oid(hashOID, decode[0].size);
56 if (hash_is_valid(hash) != CRYPT_OK) {
57 return CRYPT_INVALID_PACKET;
58 }
59
60 /* we now have the hash! */
61
62 if ((err = mp_init(&g_pub)) != CRYPT_OK) {
63 return err;
64 }
65
66 /* allocate memory */
67 expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
68 skey = XMALLOC(MAXBLOCKSIZE);
69 if (expt == NULL || skey == NULL) {
70 if (expt != NULL) {
71 XFREE(expt);
72 }
73 if (skey != NULL) {
74 XFREE(skey);
75 }
76 mp_clear(g_pub);
77 return CRYPT_MEM;
78 }
79
80 LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL);
81 LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
82
83 /* read the structure in now */
84 if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
85 goto LBL_ERR;
86 }
87
88 /* make shared key */
89 x = mp_unsigned_bin_size(key->p) + 1;
90 if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) {
91 goto LBL_ERR;
92 }
93
94 y = MIN(mp_unsigned_bin_size(key->p) + 1, MAXBLOCKSIZE);
95 if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) {
96 goto LBL_ERR;
97 }
98
99 /* ensure the hash of the shared secret is at least as big as the encrypt itself */
100 if (decode[2].size > y) {
101 err = CRYPT_INVALID_PACKET;
102 goto LBL_ERR;
103 }
104
105 /* avoid buffer overflow */
106 if (*outlen < decode[2].size) {
107 *outlen = decode[2].size;
108 err = CRYPT_BUFFER_OVERFLOW;
109 goto LBL_ERR;
110 }
111
112 /* Decrypt the key */
113 for (x = 0; x < decode[2].size; x++) {
114 out[x] = expt[x] ^ skey[x];
115 }
116 *outlen = x;
117
118 err = CRYPT_OK;
119 LBL_ERR:
120 #ifdef LTC_CLEAN_STACK
121 zeromem(expt, mp_unsigned_bin_size(key->p) + 1);
122 zeromem(skey, MAXBLOCKSIZE);
123 #endif
124
125 XFREE(expt);
126 XFREE(skey);
127
128 mp_clear(g_pub);
129
130 return err;
131 }
132
133 #endif
134
135 /* $Source$ */
136 /* $Revision$ */
137 /* $Date$ */
138
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_encrypt_key.c
14 DSA Crypto, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Encrypt a symmetric key with DSA
21 @param in The symmetric key you want to encrypt
22 @param inlen The length of the key to encrypt (octets)
23 @param out [out] The destination for the ciphertext
24 @param outlen [in/out] The max size and resulting size of the ciphertext
25 @param prng An active PRNG state
26 @param wprng The index of the PRNG you wish to use
27 @param hash The index of the hash you want to use
28 @param key The DSA key you want to encrypt to
29 @return CRYPT_OK if successful
30 */
31 int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long *outlen,
33 prng_state *prng, int wprng, int hash,
34 dsa_key *key)
35 {
36 unsigned char *expt, *skey;
37 void *g_pub, *g_priv;
38 unsigned long x, y;
39 int err;
40
41 LTC_ARGCHK(in != NULL);
42 LTC_ARGCHK(out != NULL);
43 LTC_ARGCHK(outlen != NULL);
44 LTC_ARGCHK(key != NULL);
45
46 /* check that wprng/cipher/hash are not invalid */
47 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
48 return err;
49 }
50
51 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
52 return err;
53 }
54
55 if (inlen > hash_descriptor[hash].hashsize) {
56 return CRYPT_INVALID_HASH;
57 }
58
59 /* make a random key and export the public copy */
60 if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) {
61 return err;
62 }
63
64 expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
65 skey = XMALLOC(MAXBLOCKSIZE);
66 if (expt == NULL || skey == NULL) {
67 if (expt != NULL) {
68 XFREE(expt);
69 }
70 if (skey != NULL) {
71 XFREE(skey);
72 }
73 mp_clear_multi(g_pub, g_priv, NULL);
74 return CRYPT_MEM;
75 }
76
77 /* make a random x, g^x pair */
78 x = mp_unsigned_bin_size(key->q);
79 if (prng_descriptor[wprng].read(expt, x, prng) != x) {
80 err = CRYPT_ERROR_READPRNG;
81 goto LBL_ERR;
82 }
83
84 /* load x */
85 if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) {
86 goto LBL_ERR;
87 }
88
89 /* compute y */
90 if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) {
91 goto LBL_ERR;
92 }
93
94 /* make random key */
95 x = mp_unsigned_bin_size(key->p) + 1;
96 if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) {
97 goto LBL_ERR;
98 }
99
100 y = MAXBLOCKSIZE;
101 if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104
105 /* Encrypt key */
106 for (x = 0; x < inlen; x++) {
107 skey[x] ^= in[x];
108 }
109
110 err = der_encode_sequence_multi(out, outlen,
111 LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
112 LTC_ASN1_INTEGER, 1UL, g_pub,
113 LTC_ASN1_OCTET_STRING, inlen, skey,
114 LTC_ASN1_EOL, 0UL, NULL);
115
116 LBL_ERR:
117 #ifdef LTC_CLEAN_STACK
118 /* clean up */
119 zeromem(expt, mp_unsigned_bin_size(key->p) + 1);
120 zeromem(skey, MAXBLOCKSIZE);
121 #endif
122
123 XFREE(skey);
124 XFREE(expt);
125
126 mp_clear_multi(g_pub, g_priv, NULL);
127 return err;
128 }
129
130 #endif
131 /* $Source$ */
132 /* $Revision$ */
133 /* $Date$ */
134
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_export.c
14 DSA implementation, export key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Export a DSA key to a binary packet
21 @param out [out] Where to store the packet
22 @param outlen [in/out] The max size and resulting size of the packet
23 @param type The type of key to export (PK_PRIVATE or PK_PUBLIC)
24 @param key The key to export
25 @return CRYPT_OK if successful
26 */
27 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key)
28 {
29 unsigned long zero=0;
30 int err;
31
32 LTC_ARGCHK(out != NULL);
33 LTC_ARGCHK(outlen != NULL);
34 LTC_ARGCHK(key != NULL);
35
36 /* can we store the static header? */
37 if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
38 return CRYPT_PK_TYPE_MISMATCH;
39 }
40
41 if (type != PK_PUBLIC && type != PK_PRIVATE) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 /* This encoding is different from the one in original
46 * libtomcrypt. It uses a compatible encoding with gnutls
47 * and openssl
48 */
49
50 if (type == PK_PRIVATE) {
51 return der_encode_sequence_multi(out, outlen,
52 LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
53 LTC_ASN1_INTEGER, 1UL, key->p,
54 LTC_ASN1_INTEGER, 1UL, key->q,
55 LTC_ASN1_INTEGER, 1UL, key->g,
56 LTC_ASN1_INTEGER, 1UL, key->y,
57 LTC_ASN1_INTEGER, 1UL, key->x,
58 LTC_ASN1_EOL, 0UL, NULL);
59 } else {
60 unsigned long tmplen = (mp_count_bits(key->y)/8)+8;
61 unsigned char* tmp = XMALLOC(tmplen);
62 ltc_asn1_list int_list[3];
63
64 if (tmp == NULL) {
65 return CRYPT_MEM;
66 }
67
68 err = der_encode_integer(key->y, tmp, &tmplen);
69 if (err != CRYPT_OK) {
70 goto error;
71 }
72
73 int_list[0].data = key->p;
74 int_list[0].size = 1UL;
75 int_list[0].type = LTC_ASN1_INTEGER;
76 int_list[1].data = key->q;
77 int_list[1].size = 1UL;
78 int_list[1].type = LTC_ASN1_INTEGER;
79 int_list[2].data = key->g;
80 int_list[2].size = 1UL;
81 int_list[2].type = LTC_ASN1_INTEGER;
82
83 err = der_encode_subject_public_key_info(out, outlen,
84 PKA_DSA, tmp, tmplen,
85 LTC_ASN1_SEQUENCE, int_list, sizeof(int_list)/sizeof(int_list[0]));
86
87 error:
88 XFREE(tmp);
89 return err;
90 }
91 }
92
93 #endif
94
95
96 /* $Source$ */
97 /* $Revision$ */
98 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_free.c
14 DSA implementation, free a DSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Free a DSA key
21 @param key The key to free from memory
22 */
23 void dsa_free(dsa_key *key)
24 {
25 LTC_ARGCHKVD(key != NULL);
26 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
27 }
28
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_import.c
14 DSA implementation, import a DSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Import a DSA key
21 @param in The binary packet to import from
22 @param inlen The length of the binary packet
23 @param key [out] Where to store the imported key
24 @return CRYPT_OK if successful, upon error this function will free all allocated memory
25 */
26 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
27 {
28 int err;
29 unsigned long zero = 0;
30 unsigned char* tmpbuf = NULL;
31
32 LTC_ARGCHK(in != NULL);
33 LTC_ARGCHK(key != NULL);
34 LTC_ARGCHK(ltc_mp.name != NULL);
35
36 /* init key */
37 if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {
38 return CRYPT_MEM;
39 }
40
41 /* get key type */
42 if ((err = der_decode_sequence_multi(in, inlen,
43 LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
44 LTC_ASN1_INTEGER, 1UL, key->p,
45 LTC_ASN1_INTEGER, 1UL, key->q,
46 LTC_ASN1_INTEGER, 1UL, key->g,
47 LTC_ASN1_INTEGER, 1UL, key->y,
48 LTC_ASN1_INTEGER, 1UL, key->x,
49 LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
50
51 key->type = PK_PRIVATE;
52 } else { /* public */
53 ltc_asn1_list params[3];
54 unsigned long tmpbuf_len = MAX_RSA_SIZE*8;
55
56 LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
57 LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
58 LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);
59
60 tmpbuf = XCALLOC(1, tmpbuf_len);
61 if (tmpbuf == NULL) {
62 err = CRYPT_MEM;
63 goto LBL_ERR;
64 }
65
66 err = der_decode_subject_public_key_info(in, inlen,
67 PKA_DSA, tmpbuf, &tmpbuf_len,
68 LTC_ASN1_SEQUENCE, params, 3);
69 if (err != CRYPT_OK) {
70 goto LBL_ERR;
71 }
72
73 if ((err=der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76
77 XFREE(tmpbuf);
78 key->type = PK_PUBLIC;
79 }
80 key->qord = mp_unsigned_bin_size(key->q);
81
82 if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 ||
83 (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) {
84 err = CRYPT_INVALID_PACKET;
85 goto LBL_ERR;
86 }
87
88 return CRYPT_OK;
89 LBL_ERR:
90 XFREE(tmpbuf);
91 mp_clear_multi(key->p, key->g, key->q, key->x, key->y, NULL);
92 return err;
93 }
94
95 #endif
96
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_make_key.c
14 DSA implementation, generate a DSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Create a DSA key
21 @param prng An active PRNG state
22 @param wprng The index of the PRNG desired
23 @param group_size Size of the multiplicative group (octets)
24 @param modulus_size Size of the modulus (octets)
25 @param key [out] Where to store the created key
26 @return CRYPT_OK if successful, upon error this function will free all allocated memory
27 */
28 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
29 {
30 void *tmp, *tmp2;
31 int err, res;
32 unsigned char *buf;
33
34 LTC_ARGCHK(key != NULL);
35 LTC_ARGCHK(ltc_mp.name != NULL);
36
37 /* check prng */
38 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
39 return err;
40 }
41
42 /* check size */
43 if (group_size >= LTC_MDSA_MAX_GROUP || group_size <= 15 ||
44 group_size >= modulus_size || (modulus_size - group_size) >= LTC_MDSA_DELTA) {
45 return CRYPT_INVALID_ARG;
46 }
47
48 /* allocate ram */
49 buf = XMALLOC(LTC_MDSA_DELTA);
50 if (buf == NULL) {
51 return CRYPT_MEM;
52 }
53
54 /* init mp_ints */
55 if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) {
56 XFREE(buf);
57 return err;
58 }
59
60 /* make our prime q */
61 if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK) { goto error; }
62
63 /* double q */
64 if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK) { goto error; }
65
66 /* now make a random string and multply it against q */
67 if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) {
68 err = CRYPT_ERROR_READPRNG;
69 goto error;
70 }
71
72 /* force magnitude */
73 buf[0] |= 0xC0;
74
75 /* force even */
76 buf[modulus_size - group_size - 1] &= ~1;
77
78 if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; }
79 if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK) { goto error; }
80 if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK) { goto error; }
81
82 /* now loop until p is prime */
83 for (;;) {
84 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { goto error; }
85 if (res == LTC_MP_YES) break;
86
87 /* add 2q to p and 2 to tmp2 */
88 if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK) { goto error; }
89 if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK) { goto error; }
90 }
91
92 /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */
93 mp_set(key->g, 1);
94
95 do {
96 if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK) { goto error; }
97 if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK) { goto error; }
98 } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ);
99
100 /* at this point tmp generates a group of order q mod p */
101 mp_exch(tmp, key->g);
102
103 /* so now we have our DH structure, generator g, order q, modulus p
104 Now we need a random exponent [mod q] and it's power g^x mod p
105 */
106 do {
107 if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) {
108 err = CRYPT_ERROR_READPRNG;
109 goto error;
110 }
111 if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK) { goto error; }
112 } while (mp_cmp_d(key->x, 1) != LTC_MP_GT);
113 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto error; }
114
115 key->type = PK_PRIVATE;
116 key->qord = group_size;
117
118 #ifdef LTC_CLEAN_STACK
119 zeromem(buf, LTC_MDSA_DELTA);
120 #endif
121
122 err = CRYPT_OK;
123 goto done;
124 error:
125 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
126 done:
127 mp_clear_multi(tmp, tmp2, NULL);
128 XFREE(buf);
129 return err;
130 }
131
132 #endif
133
134 /* $Source$ */
135 /* $Revision$ */
136 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_shared_secret.c
14 DSA Crypto, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Create a DSA shared secret between two keys
21 @param private_key The private DSA key (the exponent)
22 @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt)
23 @param public_key The public key
24 @param out [out] Destination of the shared secret
25 @param outlen [in/out] The max size and resulting size of the shared secret
26 @return CRYPT_OK if successful
27 */
28 int dsa_shared_secret(void *private_key, void *base,
29 dsa_key *public_key,
30 unsigned char *out, unsigned long *outlen)
31 {
32 unsigned long x;
33 void *res;
34 int err;
35
36 LTC_ARGCHK(private_key != NULL);
37 LTC_ARGCHK(public_key != NULL);
38 LTC_ARGCHK(out != NULL);
39 LTC_ARGCHK(outlen != NULL);
40
41 /* make new point */
42 if ((err = mp_init(&res)) != CRYPT_OK) {
43 return err;
44 }
45
46 if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) {
47 mp_clear(res);
48 return err;
49 }
50
51 x = (unsigned long)mp_unsigned_bin_size(res);
52 if (*outlen < x) {
53 *outlen = x;
54 err = CRYPT_BUFFER_OVERFLOW;
55 goto done;
56 }
57 zeromem(out, x);
58 if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; }
59
60 err = CRYPT_OK;
61 *outlen = x;
62 done:
63 mp_clear(res);
64 return err;
65 }
66
67 #endif
68 /* $Source$ */
69 /* $Revision$ */
70 /* $Date$ */
71
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_sign_hash.c
14 DSA implementation, sign a hash, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Sign a hash with DSA
21 @param in The hash to sign
22 @param inlen The length of the hash to sign
23 @param r The "r" integer of the signature (caller must initialize with mp_init() first)
24 @param s The "s" integer of the signature (caller must initialize with mp_init() first)
25 @param prng An active PRNG state
26 @param wprng The index of the PRNG desired
27 @param key A private DSA key
28 @return CRYPT_OK if successful
29 */
30 int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
31 void *r, void *s,
32 prng_state *prng, int wprng, dsa_key *key)
33 {
34 void *k, *kinv, *tmp;
35 unsigned char *buf;
36 int err;
37
38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(r != NULL);
40 LTC_ARGCHK(s != NULL);
41 LTC_ARGCHK(key != NULL);
42
43 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
44 return err;
45 }
46 if (key->type != PK_PRIVATE) {
47 return CRYPT_PK_NOT_PRIVATE;
48 }
49
50 /* check group order size */
51 if (key->qord >= LTC_MDSA_MAX_GROUP) {
52 return CRYPT_INVALID_ARG;
53 }
54
55 buf = XMALLOC(LTC_MDSA_MAX_GROUP);
56 if (buf == NULL) {
57 return CRYPT_MEM;
58 }
59
60 /* Init our temps */
61 if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; }
62
63 retry:
64
65 do {
66 /* gen random k */
67 if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
68 err = CRYPT_ERROR_READPRNG;
69 goto error;
70 }
71
72 /* read k */
73 if ((err = mp_read_unsigned_bin(k, buf, key->qord)) != CRYPT_OK) { goto error; }
74
75 /* k > 1 ? */
76 if (mp_cmp_d(k, 1) != LTC_MP_GT) { goto retry; }
77
78 /* test gcd */
79 if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; }
80 } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ);
81
82 /* now find 1/k mod q */
83 if ((err = mp_invmod(k, key->q, kinv)) != CRYPT_OK) { goto error; }
84
85 /* now find r = g^k mod p mod q */
86 if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; }
87 if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; }
88
89 if (mp_iszero(r) == LTC_MP_YES) { goto retry; }
90
91 /* now find s = (in + xr)/k mod q */
92 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; }
93 if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; }
94 if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { goto error; }
95 if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; }
96
97 if (mp_iszero(s) == LTC_MP_YES) { goto retry; }
98
99 err = CRYPT_OK;
100 error:
101 mp_clear_multi(k, kinv, tmp, NULL);
102 ERRBUF:
103 #ifdef LTC_CLEAN_STACK
104 zeromem(buf, LTC_MDSA_MAX_GROUP);
105 #endif
106 XFREE(buf);
107 return err;
108 }
109
110 /**
111 Sign a hash with DSA
112 @param in The hash to sign
113 @param inlen The length of the hash to sign
114 @param out [out] Where to store the signature
115 @param outlen [in/out] The max size and resulting size of the signature
116 @param prng An active PRNG state
117 @param wprng The index of the PRNG desired
118 @param key A private DSA key
119 @return CRYPT_OK if successful
120 */
121 int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
122 unsigned char *out, unsigned long *outlen,
123 prng_state *prng, int wprng, dsa_key *key)
124 {
125 void *r, *s;
126 int err;
127
128 LTC_ARGCHK(in != NULL);
129 LTC_ARGCHK(out != NULL);
130 LTC_ARGCHK(outlen != NULL);
131 LTC_ARGCHK(key != NULL);
132
133 if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) {
134 return CRYPT_MEM;
135 }
136
137 if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) {
138 goto error;
139 }
140
141 err = der_encode_sequence_multi(out, outlen,
142 LTC_ASN1_INTEGER, 1UL, r,
143 LTC_ASN1_INTEGER, 1UL, s,
144 LTC_ASN1_EOL, 0UL, NULL);
145
146 error:
147 mp_clear_multi(r, s, NULL);
148 return err;
149 }
150
151 #endif
152
153 /* $Source$ */
154 /* $Revision$ */
155 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_verify_hash.c
14 DSA implementation, verify a signature, Tom St Denis
15 */
16
17
18 #ifdef LTC_MDSA
19
20 /**
21 Verify a DSA signature
22 @param r DSA "r" parameter
23 @param s DSA "s" parameter
24 @param hash The hash that was signed
25 @param hashlen The length of the hash that was signed
26 @param stat [out] The result of the signature verification, 1==valid, 0==invalid
27 @param key The corresponding public DH key
28 @return CRYPT_OK if successful (even if the signature is invalid)
29 */
30 int dsa_verify_hash_raw( void *r, void *s,
31 const unsigned char *hash, unsigned long hashlen,
32 int *stat, dsa_key *key)
33 {
34 void *w, *v, *u1, *u2;
35 int err;
36
37 LTC_ARGCHK(r != NULL);
38 LTC_ARGCHK(s != NULL);
39 LTC_ARGCHK(stat != NULL);
40 LTC_ARGCHK(key != NULL);
41
42 /* default to invalid signature */
43 *stat = 0;
44
45 /* init our variables */
46 if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != CRYPT_OK) {
47 return err;
48 }
49
50 /* neither r or s can be null or >q*/
51 if (mp_iszero(r) == LTC_MP_YES || mp_iszero(s) == LTC_MP_YES || mp_cmp(r, key->q) != LTC_MP_LT || mp_cmp(s, key->q) != LTC_MP_LT) {
52 err = CRYPT_INVALID_PACKET;
53 goto error;
54 }
55
56 /* w = 1/s mod q */
57 if ((err = mp_invmod(s, key->q, w)) != CRYPT_OK) { goto error; }
58
59 /* u1 = m * w mod q */
60 if ((err = mp_read_unsigned_bin(u1, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; }
61 if ((err = mp_mulmod(u1, w, key->q, u1)) != CRYPT_OK) { goto error; }
62
63 /* u2 = r*w mod q */
64 if ((err = mp_mulmod(r, w, key->q, u2)) != CRYPT_OK) { goto error; }
65
66 /* v = g^u1 * y^u2 mod p mod q */
67 if ((err = mp_exptmod(key->g, u1, key->p, u1)) != CRYPT_OK) { goto error; }
68 if ((err = mp_exptmod(key->y, u2, key->p, u2)) != CRYPT_OK) { goto error; }
69 if ((err = mp_mulmod(u1, u2, key->p, v)) != CRYPT_OK) { goto error; }
70 if ((err = mp_mod(v, key->q, v)) != CRYPT_OK) { goto error; }
71
72 /* if r = v then we're set */
73 if (mp_cmp(r, v) == LTC_MP_EQ) {
74 *stat = 1;
75 }
76
77 err = CRYPT_OK;
78 error:
79 mp_clear_multi(w, v, u1, u2, NULL);
80 return err;
81 }
82
83 /**
84 Verify a DSA signature
85 @param sig The signature
86 @param siglen The length of the signature (octets)
87 @param hash The hash that was signed
88 @param hashlen The length of the hash that was signed
89 @param stat [out] The result of the signature verification, 1==valid, 0==invalid
90 @param key The corresponding public DH key
91 @return CRYPT_OK if successful (even if the signature is invalid)
92 */
93 int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
94 const unsigned char *hash, unsigned long hashlen,
95 int *stat, dsa_key *key)
96 {
97 int err;
98 void *r, *s;
99
100 if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) {
101 return CRYPT_MEM;
102 }
103
104 /* decode the sequence */
105 if ((err = der_decode_sequence_multi(sig, siglen,
106 LTC_ASN1_INTEGER, 1UL, r,
107 LTC_ASN1_INTEGER, 1UL, s,
108 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
109 goto LBL_ERR;
110 }
111
112 /* do the op */
113 err = dsa_verify_hash_raw(r, s, hash, hashlen, stat, key);
114
115 LBL_ERR:
116 mp_clear_multi(r, s, NULL);
117 return err;
118 }
119
120 #endif
121
122
123 /* $Source$ */
124 /* $Revision$ */
125 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file dsa_verify_key.c
14 DSA implementation, verify a key, Tom St Denis
15 */
16
17 #ifdef LTC_MDSA
18
19 /**
20 Verify a DSA key for validity
21 @param key The key to verify
22 @param stat [out] Result of test, 1==valid, 0==invalid
23 @return CRYPT_OK if successful
24 */
25 int dsa_verify_key(dsa_key *key, int *stat)
26 {
27 void *tmp, *tmp2;
28 int res, err;
29
30 LTC_ARGCHK(key != NULL);
31 LTC_ARGCHK(stat != NULL);
32
33 /* default to an invalid key */
34 *stat = 0;
35
36 /* first make sure key->q and key->p are prime */
37 if ((err = mp_prime_is_prime(key->q, 8, &res)) != CRYPT_OK) {
38 return err;
39 }
40 if (res == 0) {
41 return CRYPT_OK;
42 }
43
44 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) {
45 return err;
46 }
47 if (res == 0) {
48 return CRYPT_OK;
49 }
50
51 /* now make sure that g is not -1, 0 or 1 and <p */
52 if (mp_cmp_d(key->g, 0) == LTC_MP_EQ || mp_cmp_d(key->g, 1) == LTC_MP_EQ) {
53 return CRYPT_OK;
54 }
55 if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK) { return err; }
56 if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) { goto error; }
57 if (mp_cmp(tmp, key->g) == LTC_MP_EQ || mp_cmp(key->g, key->p) != LTC_MP_LT) {
58 err = CRYPT_OK;
59 goto error;
60 }
61
62 /* 1 < y < p-1 */
63 if (!(mp_cmp_d(key->y, 1) == LTC_MP_GT && mp_cmp(key->y, tmp) == LTC_MP_LT)) {
64 err = CRYPT_OK;
65 goto error;
66 }
67
68 /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */
69 if ((err = mp_div(tmp, key->q, tmp, tmp2)) != CRYPT_OK) { goto error; }
70 if (mp_iszero(tmp2) != LTC_MP_YES) {
71 err = CRYPT_OK;
72 goto error;
73 }
74
75 if ((err = mp_exptmod(key->g, key->q, key->p, tmp)) != CRYPT_OK) { goto error; }
76 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
77 err = CRYPT_OK;
78 goto error;
79 }
80
81 /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */
82 if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) { goto error; }
83 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
84 err = CRYPT_OK;
85 goto error;
86 }
87
88 /* at this point we are out of tests ;-( */
89 err = CRYPT_OK;
90 *stat = 1;
91 error:
92 mp_clear_multi(tmp, tmp2, NULL);
93 return err;
94 }
95 #endif
96
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
26 const ltc_ecc_set_type ltc_ecc_sets[] = {
27 #ifdef ECC112
28 {
29 14,
30 "SECP112R1",
31 "DB7C2ABF62E35E668076BEAD208B",
32 "659EF8BA043916EEDE8911702B22",
33 "DB7C2ABF62E35E7628DFAC6561C5",
34 "09487239995A5EE76B55F9C2F098",
35 "A89CE5AF8724C0A23E0E0FF77500"
36 },
37 #endif
38 #ifdef ECC128
39 {
40 16,
41 "SECP128R1",
42 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
43 "E87579C11079F43DD824993C2CEE5ED3",
44 "FFFFFFFE0000000075A30D1B9038A115",
45 "161FF7528B899B2D0C28607CA52C5B86",
46 "CF5AC8395BAFEB13C02DA292DDED7A83",
47 },
48 #endif
49 #ifdef ECC160
50 {
51 20,
52 "SECP160R1",
53 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
54 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
55 "0100000000000000000001F4C8F927AED3CA752257",
56 "4A96B5688EF573284664698968C38BB913CBFC82",
57 "23A628553168947D59DCC912042351377AC5FB32",
58 },
59 #endif
60 #ifdef ECC192
61 {
62 24,
63 "ECC-192",
64 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
65 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
66 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
67 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
68 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
69 },
70 #endif
71 #ifdef ECC224
72 {
73 28,
74 "ECC-224",
75 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
76 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
77 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
78 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
79 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
80 },
81 #endif
82 #ifdef ECC256
83 {
84 32,
85 "ECC-256",
86 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
87 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
88 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
89 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
90 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
91 },
92 #endif
93 #ifdef ECC384
94 {
95 48,
96 "ECC-384",
97 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
98 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
99 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
100 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
101 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
102 },
103 #endif
104 #ifdef ECC521
105 {
106 66,
107 "ECC-521",
108 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
109 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
110 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
111 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
112 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
113 },
114 #endif
115 {
116 0,
117 NULL, NULL, NULL, NULL, NULL, NULL
118 }
119 };
120
121 #endif
122
123 /* $Source$ */
124 /* $Revision$ */
125 /* $Date$ */
126
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_ansi_x963_export.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /** ECC X9.63 (Sec. 4.3.6) uncompressed export
26 @param key Key to export
27 @param out [out] destination of export
28 @param outlen [in/out] Length of destination and final output size
29 Return CRYPT_OK on success
30 */
31 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen)
32 {
33 unsigned char buf[ECC_BUF_SIZE];
34 unsigned long numlen;
35
36 LTC_ARGCHK(key != NULL);
37 LTC_ARGCHK(out != NULL);
38 LTC_ARGCHK(outlen != NULL);
39
40 if (ltc_ecc_is_valid_idx(key->idx) == 0) {
41 return CRYPT_INVALID_ARG;
42 }
43 numlen = key->dp->size;
44
45 if (*outlen < (1 + 2*numlen)) {
46 *outlen = 1 + 2*numlen;
47 return CRYPT_BUFFER_OVERFLOW;
48 }
49
50 /* store byte 0x04 */
51 out[0] = 0x04;
52
53 /* pad and store x */
54 zeromem(buf, sizeof(buf));
55 mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
56 XMEMCPY(out+1, buf, numlen);
57
58 /* pad and store y */
59 zeromem(buf, sizeof(buf));
60 mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - mp_unsigned_bin_size(key->pubkey.y)));
61 XMEMCPY(out+1+numlen, buf, numlen);
62
63 *outlen = 1 + 2*numlen;
64 return CRYPT_OK;
65 }
66
67 #endif
68
69 /* $Source$ */
70 /* $Revision$ */
71 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_ansi_x963_import.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /** Import an ANSI X9.63 format public key
26 @param in The input data to read
27 @param inlen The length of the input data
28 @param key [out] destination to store imported key \
29 */
30 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
31 {
32 return ecc_ansi_x963_import_ex(in, inlen, key, NULL);
33 }
34
35 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
36 {
37 int x, err;
38
39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(key != NULL);
41
42 /* must be odd */
43 if ((inlen & 1) == 0) {
44 return CRYPT_INVALID_ARG;
45 }
46
47 /* init key */
48 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) {
49 return CRYPT_MEM;
50 }
51
52 /* check for 4, 6 or 7 */
53 if (in[0] != 4 && in[0] != 6 && in[0] != 7) {
54 err = CRYPT_INVALID_PACKET;
55 goto error;
56 }
57
58 /* read data */
59 if ((err = mp_read_unsigned_bin(key->pubkey.x, (unsigned char *)in+1, (inlen-1)>>1)) != CRYPT_OK) {
60 goto error;
61 }
62
63 if ((err = mp_read_unsigned_bin(key->pubkey.y, (unsigned char *)in+1+((inlen-1)>>1), (inlen-1)>>1)) != CRYPT_OK) {
64 goto error;
65 }
66 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; }
67
68 if (dp == NULL) {
69 /* determine the idx */
70 for (x = 0; ltc_ecc_sets[x].size != 0; x++) {
71 if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) {
72 break;
73 }
74 }
75 if (ltc_ecc_sets[x].size == 0) {
76 err = CRYPT_INVALID_PACKET;
77 goto error;
78 }
79 /* set the idx */
80 key->idx = x;
81 key->dp = &ltc_ecc_sets[x];
82 } else {
83 if (((inlen-1)>>1) != (unsigned long) dp->size) {
84 err = CRYPT_INVALID_PACKET;
85 goto error;
86 }
87 key->idx = -1;
88 key->dp = dp;
89 }
90 key->type = PK_PUBLIC;
91
92 /* we're done */
93 return CRYPT_OK;
94 error:
95 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
96 return err;
97 }
98
99 #endif
100
101 /* $Source$ */
102 /* $Revision$ */
103 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_decrypt_key.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Decrypt an ECC encrypted key
27 @param in The ciphertext
28 @param inlen The length of the ciphertext (octets)
29 @param out [out] The plaintext
30 @param outlen [in/out] The max size and resulting size of the plaintext
31 @param key The corresponding private ECC key
32 @return CRYPT_OK if successful
33 */
34 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
35 unsigned char *out, unsigned long *outlen,
36 ecc_key *key)
37 {
38 unsigned char *ecc_shared, *skey, *pub_expt;
39 unsigned long x, y, hashOID[32];
40 int hash, err;
41 ecc_key pubkey;
42 ltc_asn1_list decode[3];
43
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47 LTC_ARGCHK(key != NULL);
48
49 /* right key type? */
50 if (key->type != PK_PRIVATE) {
51 return CRYPT_PK_NOT_PRIVATE;
52 }
53
54 /* decode to find out hash */
55 LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
56
57 if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
58 return err;
59 }
60
61 hash = find_hash_oid(hashOID, decode[0].size);
62 if (hash_is_valid(hash) != CRYPT_OK) {
63 return CRYPT_INVALID_PACKET;
64 }
65
66 /* we now have the hash! */
67
68 /* allocate memory */
69 pub_expt = XMALLOC(ECC_BUF_SIZE);
70 ecc_shared = XMALLOC(ECC_BUF_SIZE);
71 skey = XMALLOC(MAXBLOCKSIZE);
72 if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
73 if (pub_expt != NULL) {
74 XFREE(pub_expt);
75 }
76 if (ecc_shared != NULL) {
77 XFREE(ecc_shared);
78 }
79 if (skey != NULL) {
80 XFREE(skey);
81 }
82 return CRYPT_MEM;
83 }
84 LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE);
85 LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
86
87 /* read the structure in now */
88 if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
89 goto LBL_ERR;
90 }
91
92 /* import ECC key from packet */
93 if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
94 goto LBL_ERR;
95 }
96
97 /* make shared key */
98 x = ECC_BUF_SIZE;
99 if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {
100 ecc_free(&pubkey);
101 goto LBL_ERR;
102 }
103 ecc_free(&pubkey);
104
105 y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE);
106 if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {
107 goto LBL_ERR;
108 }
109
110 /* ensure the hash of the shared secret is at least as big as the encrypt itself */
111 if (decode[2].size > y) {
112 err = CRYPT_INVALID_PACKET;
113 goto LBL_ERR;
114 }
115
116 /* avoid buffer overflow */
117 if (*outlen < decode[2].size) {
118 *outlen = decode[2].size;
119 err = CRYPT_BUFFER_OVERFLOW;
120 goto LBL_ERR;
121 }
122
123 /* Decrypt the key */
124 for (x = 0; x < decode[2].size; x++) {
125 out[x] = skey[x] ^ ecc_shared[x];
126 }
127 *outlen = x;
128
129 err = CRYPT_OK;
130 LBL_ERR:
131 #ifdef LTC_CLEAN_STACK
132 zeromem(pub_expt, ECC_BUF_SIZE);
133 zeromem(ecc_shared, ECC_BUF_SIZE);
134 zeromem(skey, MAXBLOCKSIZE);
135 #endif
136
137 XFREE(pub_expt);
138 XFREE(ecc_shared);
139 XFREE(skey);
140
141 return err;
142 }
143
144 #endif
145
146 /* $Source$ */
147 /* $Revision$ */
148 /* $Date$ */
149
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_encrypt_key.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Encrypt a symmetric key with ECC
27 @param in The symmetric key you want to encrypt
28 @param inlen The length of the key to encrypt (octets)
29 @param out [out] The destination for the ciphertext
30 @param outlen [in/out] The max size and resulting size of the ciphertext
31 @param prng An active PRNG state
32 @param wprng The index of the PRNG you wish to use
33 @param hash The index of the hash you want to use
34 @param key The ECC key you want to encrypt to
35 @return CRYPT_OK if successful
36 */
37 int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
38 unsigned char *out, unsigned long *outlen,
39 prng_state *prng, int wprng, int hash,
40 ecc_key *key)
41 {
42 unsigned char *pub_expt, *ecc_shared, *skey;
43 ecc_key pubkey;
44 unsigned long x, y, pubkeysize;
45 int err;
46
47 LTC_ARGCHK(in != NULL);
48 LTC_ARGCHK(out != NULL);
49 LTC_ARGCHK(outlen != NULL);
50 LTC_ARGCHK(key != NULL);
51
52 /* check that wprng/cipher/hash are not invalid */
53 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
54 return err;
55 }
56
57 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
58 return err;
59 }
60
61 if (inlen > hash_descriptor[hash].hashsize) {
62 return CRYPT_INVALID_HASH;
63 }
64
65 /* make a random key and export the public copy */
66 if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) {
67 return err;
68 }
69
70 pub_expt = XMALLOC(ECC_BUF_SIZE);
71 ecc_shared = XMALLOC(ECC_BUF_SIZE);
72 skey = XMALLOC(MAXBLOCKSIZE);
73 if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
74 if (pub_expt != NULL) {
75 XFREE(pub_expt);
76 }
77 if (ecc_shared != NULL) {
78 XFREE(ecc_shared);
79 }
80 if (skey != NULL) {
81 XFREE(skey);
82 }
83 ecc_free(&pubkey);
84 return CRYPT_MEM;
85 }
86
87 pubkeysize = ECC_BUF_SIZE;
88 if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
89 ecc_free(&pubkey);
90 goto LBL_ERR;
91 }
92
93 /* make random key */
94 x = ECC_BUF_SIZE;
95 if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
96 ecc_free(&pubkey);
97 goto LBL_ERR;
98 }
99 ecc_free(&pubkey);
100 y = MAXBLOCKSIZE;
101 if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104
105 /* Encrypt key */
106 for (x = 0; x < inlen; x++) {
107 skey[x] ^= in[x];
108 }
109
110 err = der_encode_sequence_multi(out, outlen,
111 LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
112 LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt,
113 LTC_ASN1_OCTET_STRING, inlen, skey,
114 LTC_ASN1_EOL, 0UL, NULL);
115
116 LBL_ERR:
117 #ifdef LTC_CLEAN_STACK
118 /* clean up */
119 zeromem(pub_expt, ECC_BUF_SIZE);
120 zeromem(ecc_shared, ECC_BUF_SIZE);
121 zeromem(skey, MAXBLOCKSIZE);
122 #endif
123
124 XFREE(skey);
125 XFREE(ecc_shared);
126 XFREE(pub_expt);
127
128 return err;
129 }
130
131 #endif
132 /* $Source$ */
133 /* $Revision$ */
134 /* $Date$ */
135
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_export.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Export an ECC key as a binary packet
27 @param out [out] Destination for the key
28 @param outlen [in/out] Max size and resulting size of the exported key
29 @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC)
30 @param key The key to export
31 @return CRYPT_OK if successful
32 */
33 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
34 {
35 int err;
36 unsigned char flags[1];
37 unsigned long key_size;
38
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41 LTC_ARGCHK(key != NULL);
42
43 /* type valid? */
44 if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
45 return CRYPT_PK_TYPE_MISMATCH;
46 }
47
48 if (ltc_ecc_is_valid_idx(key->idx) == 0) {
49 return CRYPT_INVALID_ARG;
50 }
51
52 /* we store the NIST byte size */
53 key_size = key->dp->size;
54
55 if (type == PK_PRIVATE) {
56 flags[0] = 1;
57 err = der_encode_sequence_multi(out, outlen,
58 LTC_ASN1_BIT_STRING, 1UL, flags,
59 LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
60 LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
61 LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
62 LTC_ASN1_INTEGER, 1UL, key->k,
63 LTC_ASN1_EOL, 0UL, NULL);
64 } else {
65 flags[0] = 0;
66 err = der_encode_sequence_multi(out, outlen,
67 LTC_ASN1_BIT_STRING, 1UL, flags,
68 LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
69 LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
70 LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
71 LTC_ASN1_EOL, 0UL, NULL);
72 }
73
74 return err;
75 }
76
77 #endif
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
81
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_free.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Free an ECC key from memory
27 @param key The key you wish to free
28 */
29 void ecc_free(ecc_key *key)
30 {
31 LTC_ARGCHKVD(key != NULL);
32 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
33 }
34
35 #endif
36 /* $Source$ */
37 /* $Revision$ */
38 /* $Date$ */
39
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_get_size.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Get the size of an ECC key
27 @param key The key to get the size of
28 @return The size (octets) of the key or INT_MAX on error
29 */
30 int ecc_get_size(ecc_key *key)
31 {
32 LTC_ARGCHK(key != NULL);
33 if (ltc_ecc_is_valid_idx(key->idx))
34 return key->dp->size;
35 else
36 return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */
37 }
38
39 #endif
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
43
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_import.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 static int is_point(ecc_key *key)
26 {
27 void *prime, *b, *t1, *t2;
28 int err;
29
30 if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) {
31 return err;
32 }
33
34 /* load prime and b */
35 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; }
36 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; }
37
38 /* compute y^2 */
39 if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; }
40
41 /* compute x^3 */
42 if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; }
43 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; }
44 if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; }
45
46 /* compute y^2 - x^3 */
47 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; }
48
49 /* compute y^2 - x^3 + 3x */
50 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
51 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
52 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
53 if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; }
54 while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
55 if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; }
56 }
57 while (mp_cmp(t1, prime) != LTC_MP_LT) {
58 if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; }
59 }
60
61 /* compare to b */
62 if (mp_cmp(t1, b) != LTC_MP_EQ) {
63 err = CRYPT_INVALID_PACKET;
64 } else {
65 err = CRYPT_OK;
66 }
67
68 error:
69 mp_clear_multi(prime, b, t1, t2, NULL);
70 return err;
71 }
72
73 /**
74 Import an ECC key from a binary packet
75 @param in The packet to import
76 @param inlen The length of the packet
77 @param key [out] The destination of the import
78 @return CRYPT_OK if successful, upon error all allocated memory will be freed
79 */
80 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
81 {
82 return ecc_import_ex(in, inlen, key, NULL);
83 }
84
85 /**
86 Import an ECC key from a binary packet, using user supplied domain params rather than one of the NIST ones
87 @param in The packet to import
88 @param inlen The length of the packet
89 @param key [out] The destination of the import
90 @param dp pointer to user supplied params; must be the same as the params used when exporting
91 @return CRYPT_OK if successful, upon error all allocated memory will be freed
92 */
93 int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp)
94 {
95 unsigned long key_size;
96 unsigned char flags[1];
97 int err;
98
99 LTC_ARGCHK(in != NULL);
100 LTC_ARGCHK(key != NULL);
101 LTC_ARGCHK(ltc_mp.name != NULL);
102
103 /* init key */
104 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) {
105 return CRYPT_MEM;
106 }
107
108 /* find out what type of key it is */
109 if ((err = der_decode_sequence_multi(in, inlen,
110 LTC_ASN1_BIT_STRING, 1UL, &flags,
111 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
112 goto done;
113 }
114
115
116 if (flags[0] == 1) {
117 /* private key */
118 key->type = PK_PRIVATE;
119 if ((err = der_decode_sequence_multi(in, inlen,
120 LTC_ASN1_BIT_STRING, 1UL, flags,
121 LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
122 LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
123 LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
124 LTC_ASN1_INTEGER, 1UL, key->k,
125 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
126 goto done;
127 }
128 } else {
129 /* public key */
130 key->type = PK_PUBLIC;
131 if ((err = der_decode_sequence_multi(in, inlen,
132 LTC_ASN1_BIT_STRING, 1UL, flags,
133 LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
134 LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
135 LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
136 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
137 goto done;
138 }
139 }
140
141 if (dp == NULL) {
142 /* find the idx */
143 for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx);
144 if (ltc_ecc_sets[key->idx].size == 0) {
145 err = CRYPT_INVALID_PACKET;
146 goto done;
147 }
148 key->dp = &ltc_ecc_sets[key->idx];
149 } else {
150 key->idx = -1;
151 key->dp = dp;
152 }
153 /* set z */
154 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; }
155
156 /* is it a point on the curve? */
157 if ((err = is_point(key)) != CRYPT_OK) {
158 goto done;
159 }
160
161 /* we're good */
162 return CRYPT_OK;
163 done:
164 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
165 return err;
166 }
167 #endif
168 /* $Source$ */
169 /* $Revision$ */
170 /* $Date$ */
171
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_make_key.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Make a new ECC key
27 @param prng An active PRNG state
28 @param wprng The index of the PRNG you wish to use
29 @param keysize The keysize for the new key (in octets from 20 to 65 bytes)
30 @param key [out] Destination of the newly created key
31 @return CRYPT_OK if successful, upon error all allocated memory will be freed
32 */
33 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
34 {
35 int x, err;
36
37 /* find key size */
38 for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++);
39 keysize = ltc_ecc_sets[x].size;
40
41 if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) {
42 return CRYPT_INVALID_KEYSIZE;
43 }
44 err = ecc_make_key_ex(prng, wprng, key, &ltc_ecc_sets[x]);
45 key->idx = x;
46 return err;
47 }
48
49 int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp)
50 {
51 int err;
52 ecc_point *base;
53 void *prime, *order;
54 unsigned char *buf;
55 int keysize;
56
57 LTC_ARGCHK(key != NULL);
58 LTC_ARGCHK(ltc_mp.name != NULL);
59 LTC_ARGCHK(dp != NULL);
60
61 /* good prng? */
62 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
63 return err;
64 }
65
66 key->idx = -1;
67 key->dp = dp;
68 keysize = dp->size;
69
70 /* allocate ram */
71 base = NULL;
72 buf = XMALLOC(ECC_MAXSIZE);
73 if (buf == NULL) {
74 return CRYPT_MEM;
75 }
76
77 /* make up random string */
78 if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) {
79 err = CRYPT_ERROR_READPRNG;
80 goto ERR_BUF;
81 }
82
83 /* setup the key variables */
84 if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, NULL)) != CRYPT_OK) {
85 goto ERR_BUF;
86 }
87 base = ltc_ecc_new_point();
88 if (base == NULL) {
89 err = CRYPT_MEM;
90 goto errkey;
91 }
92
93 /* read in the specs for this key */
94 if ((err = mp_read_radix(prime, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto errkey; }
95 if ((err = mp_read_radix(order, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errkey; }
96 if ((err = mp_read_radix(base->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto errkey; }
97 if ((err = mp_read_radix(base->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto errkey; }
98 if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; }
99 if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; }
100
101 /* the key should be smaller than the order of base point */
102 if (mp_cmp(key->k, order) != LTC_MP_LT) {
103 if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; }
104 }
105 /* make the public key */
106 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto errkey; }
107 key->type = PK_PRIVATE;
108
109 /* free up ram */
110 err = CRYPT_OK;
111 goto cleanup;
112 errkey:
113 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
114 cleanup:
115 ltc_ecc_del_point(base);
116 mp_clear_multi(prime, order, NULL);
117 ERR_BUF:
118 #ifdef LTC_CLEAN_STACK
119 zeromem(buf, ECC_MAXSIZE);
120 #endif
121 XFREE(buf);
122 return err;
123 }
124
125 #endif
126 /* $Source$ */
127 /* $Revision$ */
128 /* $Date$ */
129
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_shared_secret.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Create an ECC shared secret between two keys
27 @param private_key The private ECC key
28 @param public_key The public key
29 @param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63)
30 @param outlen [in/out] The max size and resulting size of the shared secret
31 @return CRYPT_OK if successful
32 */
33 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
34 unsigned char *out, unsigned long *outlen)
35 {
36 unsigned long x;
37 ecc_point *result;
38 void *prime;
39 int err;
40
41 LTC_ARGCHK(private_key != NULL);
42 LTC_ARGCHK(public_key != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45
46 /* type valid? */
47 if (private_key->type != PK_PRIVATE) {
48 return CRYPT_PK_NOT_PRIVATE;
49 }
50
51 if (ltc_ecc_is_valid_idx(private_key->idx) == 0 || ltc_ecc_is_valid_idx(public_key->idx) == 0) {
52 return CRYPT_INVALID_ARG;
53 }
54
55 if (XSTRCMP(private_key->dp->name, public_key->dp->name) != 0) {
56 return CRYPT_PK_TYPE_MISMATCH;
57 }
58
59 /* make new point */
60 result = ltc_ecc_new_point();
61 if (result == NULL) {
62 return CRYPT_MEM;
63 }
64
65 if ((err = mp_init(&prime)) != CRYPT_OK) {
66 ltc_ecc_del_point(result);
67 return err;
68 }
69
70 if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != CRYPT_OK) { goto done; }
71 if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK) { goto done; }
72
73 x = (unsigned long)mp_unsigned_bin_size(prime);
74 if (*outlen < x) {
75 *outlen = x;
76 err = CRYPT_BUFFER_OVERFLOW;
77 goto done;
78 }
79 zeromem(out, x);
80 if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x)))) != CRYPT_OK) { goto done; }
81
82 err = CRYPT_OK;
83 *outlen = x;
84 done:
85 mp_clear(prime);
86 ltc_ecc_del_point(result);
87 return err;
88 }
89
90 #endif
91 /* $Source$ */
92 /* $Revision$ */
93 /* $Date$ */
94
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_sign_hash.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Sign a message digest
27 @param in The message digest to sign
28 @param inlen The length of the digest
29 @param out [out] The destination for the signature
30 @param outlen [in/out] The max size and resulting size of the signature
31 @param prng An active PRNG state
32 @param wprng The index of the PRNG you wish to use
33 @param key A private ECC key
34 @return CRYPT_OK if successful
35 */
36 int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
37 unsigned char *out, unsigned long *outlen,
38 prng_state *prng, int wprng, ecc_key *key)
39 {
40 ecc_key pubkey;
41 void *r, *s, *e, *p;
42 int err;
43
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(outlen != NULL);
47 LTC_ARGCHK(key != NULL);
48
49 /* is this a private key? */
50 if (key->type != PK_PRIVATE) {
51 return CRYPT_PK_NOT_PRIVATE;
52 }
53
54 /* is the IDX valid ? */
55 if (ltc_ecc_is_valid_idx(key->idx) != 1) {
56 return CRYPT_PK_INVALID_TYPE;
57 }
58
59 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
60 return err;
61 }
62
63 /* get the hash and load it as a bignum into 'e' */
64 /* init the bignums */
65 if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) {
66 return err;
67 }
68 if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; }
69 if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto errnokey; }
70
71 /* make up a key and export the public copy */
72 for (;;) {
73 if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) {
74 goto errnokey;
75 }
76
77 /* find r = x1 mod n */
78 if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; }
79
80 if (mp_iszero(r) == LTC_MP_YES) {
81 ecc_free(&pubkey);
82 } else {
83 /* find s = (e + xr)/k */
84 if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */
85 if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */
86 if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
87 if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
88 if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */
89 ecc_free(&pubkey);
90 if (mp_iszero(s) == LTC_MP_NO) {
91 break;
92 }
93 }
94 }
95
96 /* store as SEQUENCE { r, s -- integer } */
97 err = der_encode_sequence_multi(out, outlen,
98 LTC_ASN1_INTEGER, 1UL, r,
99 LTC_ASN1_INTEGER, 1UL, s,
100 LTC_ASN1_EOL, 0UL, NULL);
101 goto errnokey;
102 error:
103 ecc_free(&pubkey);
104 errnokey:
105 mp_clear_multi(r, s, p, e, NULL);
106 return err;
107 }
108
109 #endif
110 /* $Source$ */
111 /* $Revision$ */
112 /* $Date$ */
113
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_sizes.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 void ecc_sizes(int *low, int *high)
26 {
27 int i;
28 LTC_ARGCHKVD(low != NULL);
29 LTC_ARGCHKVD(high != NULL);
30
31 *low = INT_MAX;
32 *high = 0;
33 for (i = 0; ltc_ecc_sets[i].size != 0; i++) {
34 if (ltc_ecc_sets[i].size < *low) {
35 *low = ltc_ecc_sets[i].size;
36 }
37 if (ltc_ecc_sets[i].size > *high) {
38 *high = ltc_ecc_sets[i].size;
39 }
40 }
41 }
42
43 #endif
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
47
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ecc_verify_hash.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /* verify
26 *
27 * w = s^-1 mod n
28 * u1 = xw
29 * u2 = rw
30 * X = u1*G + u2*Q
31 * v = X_x1 mod n
32 * accept if v == r
33 */
34
35 /**
36 Verify an ECC signature
37 @param sig The signature to verify
38 @param siglen The length of the signature (octets)
39 @param hash The hash (message digest) that was signed
40 @param hashlen The length of the hash (octets)
41 @param stat Result of signature, 1==valid, 0==invalid
42 @param key The corresponding public ECC key
43 @return CRYPT_OK if successful (even if the signature is not valid)
44 */
45 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
46 const unsigned char *hash, unsigned long hashlen,
47 int *stat, ecc_key *key)
48 {
49 ecc_point *mG, *mQ;
50 void *r, *s, *v, *w, *u1, *u2, *e, *p, *m;
51 void *mp;
52 int err;
53
54 LTC_ARGCHK(sig != NULL);
55 LTC_ARGCHK(hash != NULL);
56 LTC_ARGCHK(stat != NULL);
57 LTC_ARGCHK(key != NULL);
58
59 /* default to invalid signature */
60 *stat = 0;
61 mp = NULL;
62
63 /* is the IDX valid ? */
64 if (ltc_ecc_is_valid_idx(key->idx) != 1) {
65 return CRYPT_PK_INVALID_TYPE;
66 }
67
68 /* allocate ints */
69 if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) {
70 return CRYPT_MEM;
71 }
72
73 /* allocate points */
74 mG = ltc_ecc_new_point();
75 mQ = ltc_ecc_new_point();
76 if (mQ == NULL || mG == NULL) {
77 err = CRYPT_MEM;
78 goto error;
79 }
80
81 /* parse header */
82 if ((err = der_decode_sequence_multi(sig, siglen,
83 LTC_ASN1_INTEGER, 1UL, r,
84 LTC_ASN1_INTEGER, 1UL, s,
85 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
86 goto error;
87 }
88
89 /* get the order */
90 if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto error; }
91
92 /* get the modulus */
93 if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; }
94
95 /* check for zero */
96 if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) {
97 err = CRYPT_INVALID_PACKET;
98 goto error;
99 }
100
101 /* read hash */
102 if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; }
103
104 /* w = s^-1 mod n */
105 if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; }
106
107 /* u1 = ew */
108 if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK) { goto error; }
109
110 /* u2 = rw */
111 if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; }
112
113 /* find mG and mQ */
114 if ((err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto error; }
115 if ((err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto error; }
116 if ((err = mp_set(mG->z, 1)) != CRYPT_OK) { goto error; }
117
118 if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; }
119 if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; }
120 if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; }
121
122 /* compute u1*mG + u2*mQ = mG */
123 if (ltc_mp.ecc_mul2add == NULL) {
124 if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK) { goto error; }
125 if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK) { goto error; }
126
127 /* find the montgomery mp */
128 if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; }
129
130 /* add them */
131 if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto error; }
132
133 /* reduce */
134 if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; }
135 } else {
136 /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */
137 if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m)) != CRYPT_OK) { goto error; }
138 }
139
140 /* v = X_x1 mod n */
141 if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK) { goto error; }
142
143 /* does v == r */
144 if (mp_cmp(v, r) == LTC_MP_EQ) {
145 *stat = 1;
146 }
147
148 /* clear up and return */
149 err = CRYPT_OK;
150 error:
151 ltc_ecc_del_point(mG);
152 ltc_ecc_del_point(mQ);
153 mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
154 if (mp != NULL) {
155 mp_montgomery_free(mp);
156 }
157 return err;
158 }
159
160 #endif
161 /* $Source$ */
162 /* $Revision$ */
163 /* $Date$ */
164
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_is_valid_idx.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /** Returns whether an ECC idx is valid or not
26 @param n The idx number to check
27 @return 1 if valid, 0 if not
28 */
29 int ltc_ecc_is_valid_idx(int n)
30 {
31 int x;
32
33 for (x = 0; ltc_ecc_sets[x].size != 0; x++);
34 /* -1 is a valid index --- indicating that the domain params were supplied by the user */
35 if ((n >= -1) && (n < x)) {
36 return 1;
37 }
38 return 0;
39 }
40
41 #endif
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
45
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_map.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Map a projective jacbobian point back to affine space
27 @param P [in/out] The point to map
28 @param modulus The modulus of the field the ECC curve is in
29 @param mp The "b" value from montgomery_setup()
30 @return CRYPT_OK on success
31 */
32 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
33 {
34 void *t1, *t2;
35 int err;
36
37 LTC_ARGCHK(P != NULL);
38 LTC_ARGCHK(modulus != NULL);
39 LTC_ARGCHK(mp != NULL);
40
41 if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
42 return CRYPT_MEM;
43 }
44
45 /* first map z back to normal */
46 if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; }
47
48 /* get 1/z */
49 if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; }
50
51 /* get 1/z^2 and 1/z^3 */
52 if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; }
53 if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; }
54 if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; }
55 if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; }
56
57 /* multiply against x/y */
58 if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; }
59 if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; }
60 if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; }
61 if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; }
62 if ((err = mp_set(P->z, 1)) != CRYPT_OK) { goto done; }
63
64 err = CRYPT_OK;
65 done:
66 mp_clear_multi(t1, t2, NULL);
67 return err;
68 }
69
70 #endif
71
72 /* $Source$ */
73 /* $Revision$ */
74 /* $Date$ */
75
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_mul2add.c
20 ECC Crypto, Shamir's Trick, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 #ifdef LTC_ECC_SHAMIR
26
27 /** Computes kA*A + kB*B = C using Shamir's Trick
28 @param A First point to multiply
29 @param kA What to multiple A by
30 @param B Second point to multiply
31 @param kB What to multiple B by
32 @param C [out] Destination point (can overlap with A or B
33 @param modulus Modulus for curve
34 @return CRYPT_OK on success
35 */
36 int ltc_ecc_mul2add(ecc_point *A, void *kA,
37 ecc_point *B, void *kB,
38 ecc_point *C,
39 void *modulus)
40 {
41 ecc_point *precomp[16];
42 unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble;
43 unsigned char *tA, *tB;
44 int err, first;
45 void *mp, *mu;
46
47 /* argchks */
48 LTC_ARGCHK(A != NULL);
49 LTC_ARGCHK(B != NULL);
50 LTC_ARGCHK(C != NULL);
51 LTC_ARGCHK(kA != NULL);
52 LTC_ARGCHK(kB != NULL);
53 LTC_ARGCHK(modulus != NULL);
54
55 /* allocate memory */
56 tA = XCALLOC(1, ECC_BUF_SIZE);
57 if (tA == NULL) {
58 return CRYPT_MEM;
59 }
60 tB = XCALLOC(1, ECC_BUF_SIZE);
61 if (tB == NULL) {
62 XFREE(tA);
63 return CRYPT_MEM;
64 }
65
66 /* get sizes */
67 lenA = mp_unsigned_bin_size(kA);
68 lenB = mp_unsigned_bin_size(kB);
69 len = MAX(lenA, lenB);
70
71 /* sanity check */
72 if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) {
73 err = CRYPT_INVALID_ARG;
74 goto ERR_T;
75 }
76
77 /* extract and justify kA */
78 mp_to_unsigned_bin(kA, (len - lenA) + tA);
79
80 /* extract and justify kB */
81 mp_to_unsigned_bin(kB, (len - lenB) + tB);
82
83 /* allocate the table */
84 for (x = 0; x < 16; x++) {
85 precomp[x] = ltc_ecc_new_point();
86 if (precomp[x] == NULL) {
87 for (y = 0; y < x; ++y) {
88 ltc_ecc_del_point(precomp[y]);
89 }
90 err = CRYPT_MEM;
91 goto ERR_T;
92 }
93 }
94
95 /* init montgomery reduction */
96 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
97 goto ERR_P;
98 }
99 if ((err = mp_init(&mu)) != CRYPT_OK) {
100 goto ERR_MP;
101 }
102 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
103 goto ERR_MU;
104 }
105
106 /* copy ones ... */
107 if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; }
108 if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; }
109 if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; }
110
111 if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; }
112 if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; }
113 if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; }
114
115 /* precomp [i,0](A + B) table */
116 if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
117 if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
118
119 /* precomp [0,i](A + B) table */
120 if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
121 if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
122
123 /* precomp [i,j](A + B) table (i != 0, j != 0) */
124 for (x = 1; x < 4; x++) {
125 for (y = 1; y < 4; y++) {
126 if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
127 }
128 }
129
130 nibble = 3;
131 first = 1;
132 bitbufA = tA[0];
133 bitbufB = tB[0];
134
135 /* for every byte of the multiplicands */
136 for (x = -1;; ) {
137 /* grab a nibble */
138 if (++nibble == 4) {
139 ++x; if (x == len) break;
140 bitbufA = tA[x];
141 bitbufB = tB[x];
142 nibble = 0;
143 }
144
145 /* extract two bits from both, shift/update */
146 nA = (bitbufA >> 6) & 0x03;
147 nB = (bitbufB >> 6) & 0x03;
148 bitbufA = (bitbufA << 2) & 0xFF;
149 bitbufB = (bitbufB << 2) & 0xFF;
150
151 /* if both zero, if first, continue */
152 if ((nA == 0) && (nB == 0) && (first == 1)) {
153 continue;
154 }
155
156 /* double twice, only if this isn't the first */
157 if (first == 0) {
158 /* double twice */
159 if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
160 if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
161 }
162
163 /* if not both zero */
164 if ((nA != 0) || (nB != 0)) {
165 if (first == 1) {
166 /* if first, copy from table */
167 first = 0;
168 if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; }
169 if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; }
170 if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; }
171 } else {
172 /* if not first, add from table */
173 if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
174 }
175 }
176 }
177
178 /* reduce to affine */
179 err = ltc_ecc_map(C, modulus, mp);
180
181 /* clean up */
182 ERR_MU:
183 mp_clear(mu);
184 ERR_MP:
185 mp_montgomery_free(mp);
186 ERR_P:
187 for (x = 0; x < 16; x++) {
188 ltc_ecc_del_point(precomp[x]);
189 }
190 ERR_T:
191 #ifdef LTC_CLEAN_STACK
192 zeromem(tA, ECC_BUF_SIZE);
193 zeromem(tB, ECC_BUF_SIZE);
194 #endif
195 XFREE(tA);
196 XFREE(tB);
197
198 return err;
199 }
200
201 #endif
202 #endif
203
204 /* $Source$ */
205 /* $Revision$ */
206 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_mulmod.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24 #ifndef LTC_ECC_TIMING_RESISTANT
25
26 /* size of sliding window, don't change this! */
27 #define WINSIZE 4
28
29 /**
30 Perform a point multiplication
31 @param k The scalar to multiply by
32 @param G The base point
33 @param R [out] Destination for kG
34 @param modulus The modulus of the field the ECC curve is in
35 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
36 @return CRYPT_OK on success
37 */
38 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
39 {
40 ecc_point *tG, *M[8];
41 int i, j, err;
42 void *mu, *mp;
43 unsigned long buf;
44 int first, bitbuf, bitcpy, bitcnt, mode, digidx;
45
46 LTC_ARGCHK(k != NULL);
47 LTC_ARGCHK(G != NULL);
48 LTC_ARGCHK(R != NULL);
49 LTC_ARGCHK(modulus != NULL);
50
51 /* init montgomery reduction */
52 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
53 return err;
54 }
55 if ((err = mp_init(&mu)) != CRYPT_OK) {
56 mp_montgomery_free(mp);
57 return err;
58 }
59 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
60 mp_montgomery_free(mp);
61 mp_clear(mu);
62 return err;
63 }
64
65 /* alloc ram for window temps */
66 for (i = 0; i < 8; i++) {
67 M[i] = ltc_ecc_new_point();
68 if (M[i] == NULL) {
69 for (j = 0; j < i; j++) {
70 ltc_ecc_del_point(M[j]);
71 }
72 mp_montgomery_free(mp);
73 mp_clear(mu);
74 return CRYPT_MEM;
75 }
76 }
77
78 /* make a copy of G incase R==G */
79 tG = ltc_ecc_new_point();
80 if (tG == NULL) { err = CRYPT_MEM; goto done; }
81
82 /* tG = G and convert to montgomery */
83 if (mp_cmp_d(mu, 1) == LTC_MP_EQ) {
84 if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; }
85 if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; }
86 if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; }
87 } else {
88 if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; }
89 if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; }
90 if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; }
91 }
92 mp_clear(mu);
93 mu = NULL;
94
95 /* calc the M tab, which holds kG for k==8..15 */
96 /* M[0] == 8G */
97 if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; }
98 if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
99 if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
100
101 /* now find (8+k)G for k=1..7 */
102 for (j = 9; j < 16; j++) {
103 if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; }
104 }
105
106 /* setup sliding window */
107 mode = 0;
108 bitcnt = 1;
109 buf = 0;
110 digidx = mp_get_digit_count(k) - 1;
111 bitcpy = bitbuf = 0;
112 first = 1;
113
114 /* perform ops */
115 for (;;) {
116 /* grab next digit as required */
117 if (--bitcnt == 0) {
118 if (digidx == -1) {
119 break;
120 }
121 buf = mp_get_digit(k, digidx);
122 bitcnt = (int) ltc_mp.bits_per_digit;
123 --digidx;
124 }
125
126 /* grab the next msb from the ltiplicand */
127 i = (buf >> (ltc_mp.bits_per_digit - 1)) & 1;
128 buf <<= 1;
129
130 /* skip leading zero bits */
131 if (mode == 0 && i == 0) {
132 continue;
133 }
134
135 /* if the bit is zero and mode == 1 then we double */
136 if (mode == 1 && i == 0) {
137 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
138 continue;
139 }
140
141 /* else we add it to the window */
142 bitbuf |= (i << (WINSIZE - ++bitcpy));
143 mode = 2;
144
145 if (bitcpy == WINSIZE) {
146 /* if this is the first window we do a simple copy */
147 if (first == 1) {
148 /* R = kG [k = first window] */
149 if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; }
150 if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; }
151 if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; }
152 first = 0;
153 } else {
154 /* normal window */
155 /* ok window is filled so double as required and add */
156 /* double first */
157 for (j = 0; j < WINSIZE; j++) {
158 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
159 }
160
161 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
162 if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; }
163 }
164 /* empty window and reset */
165 bitcpy = bitbuf = 0;
166 mode = 1;
167 }
168 }
169
170 /* if bits remain then double/add */
171 if (mode == 2 && bitcpy > 0) {
172 /* double then add */
173 for (j = 0; j < bitcpy; j++) {
174 /* only double if we have had at least one add first */
175 if (first == 0) {
176 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
177 }
178
179 bitbuf <<= 1;
180 if ((bitbuf & (1 << WINSIZE)) != 0) {
181 if (first == 1){
182 /* first add, so copy */
183 if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; }
184 if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; }
185 if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; }
186 first = 0;
187 } else {
188 /* then add */
189 if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; }
190 }
191 }
192 }
193 }
194
195 /* map R back from projective space */
196 if (map) {
197 err = ltc_ecc_map(R, modulus, mp);
198 } else {
199 err = CRYPT_OK;
200 }
201 done:
202 if (mu != NULL) {
203 mp_clear(mu);
204 }
205 mp_montgomery_free(mp);
206 ltc_ecc_del_point(tG);
207 for (i = 0; i < 8; i++) {
208 ltc_ecc_del_point(M[i]);
209 }
210 return err;
211 }
212
213 #endif
214
215 #undef WINSIZE
216
217 #endif
218
219 /* $Source$ */
220 /* $Revision$ */
221 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_mulmod_timing.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 #ifdef LTC_ECC_TIMING_RESISTANT
26
27 /**
28 Perform a point multiplication (timing resistant)
29 @param k The scalar to multiply by
30 @param G The base point
31 @param R [out] Destination for kG
32 @param modulus The modulus of the field the ECC curve is in
33 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
34 @return CRYPT_OK on success
35 */
36 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
37 {
38 ecc_point *tG, *M[3];
39 int i, j, err;
40 void *mu, *mp;
41 unsigned long buf;
42 int first, bitbuf, bitcpy, bitcnt, mode, digidx;
43
44 LTC_ARGCHK(k != NULL);
45 LTC_ARGCHK(G != NULL);
46 LTC_ARGCHK(R != NULL);
47 LTC_ARGCHK(modulus != NULL);
48
49 /* init montgomery reduction */
50 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
51 return err;
52 }
53 if ((err = mp_init(&mu)) != CRYPT_OK) {
54 mp_montgomery_free(mp);
55 return err;
56 }
57 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
58 mp_clear(mu);
59 mp_montgomery_free(mp);
60 return err;
61 }
62
63 /* alloc ram for window temps */
64 for (i = 0; i < 3; i++) {
65 M[i] = ltc_ecc_new_point();
66 if (M[i] == NULL) {
67 for (j = 0; j < i; j++) {
68 ltc_ecc_del_point(M[j]);
69 }
70 mp_clear(mu);
71 mp_montgomery_free(mp);
72 return CRYPT_MEM;
73 }
74 }
75
76 /* make a copy of G incase R==G */
77 tG = ltc_ecc_new_point();
78 if (tG == NULL) { err = CRYPT_MEM; goto done; }
79
80 /* tG = G and convert to montgomery */
81 if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; }
82 if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; }
83 if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; }
84 mp_clear(mu);
85 mu = NULL;
86
87 /* calc the M tab */
88 /* M[0] == G */
89 if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK) { goto done; }
90 if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; }
91 if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; }
92 /* M[1] == 2G */
93 if ((err = ltc_mp.ecc_ptdbl(tG, M[1], modulus, mp)) != CRYPT_OK) { goto done; }
94
95 /* setup sliding window */
96 mode = 0;
97 bitcnt = 1;
98 buf = 0;
99 digidx = mp_get_digit_count(k) - 1;
100 bitcpy = bitbuf = 0;
101 first = 1;
102
103 /* perform ops */
104 for (;;) {
105 /* grab next digit as required */
106 if (--bitcnt == 0) {
107 if (digidx == -1) {
108 break;
109 }
110 buf = mp_get_digit(k, digidx);
111 bitcnt = (int) MP_DIGIT_BIT;
112 --digidx;
113 }
114
115 /* grab the next msb from the ltiplicand */
116 i = (buf >> (MP_DIGIT_BIT - 1)) & 1;
117 buf <<= 1;
118
119 if (mode == 0 && i == 0) {
120 /* dummy operations */
121 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
122 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
123 continue;
124 }
125
126 if (mode == 0 && i == 1) {
127 mode = 1;
128 /* dummy operations */
129 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
130 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
131 continue;
132 }
133
134 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; }
135 if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; }
136 }
137
138 /* copy result out */
139 if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK) { goto done; }
140 if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK) { goto done; }
141 if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK) { goto done; }
142
143 /* map R back from projective space */
144 if (map) {
145 err = ltc_ecc_map(R, modulus, mp);
146 } else {
147 err = CRYPT_OK;
148 }
149 done:
150 if (mu != NULL) {
151 mp_clear(mu);
152 }
153 mp_montgomery_free(mp);
154 ltc_ecc_del_point(tG);
155 for (i = 0; i < 3; i++) {
156 ltc_ecc_del_point(M[i]);
157 }
158 return err;
159 }
160
161 #endif
162 #endif
163 /* $Source$ */
164 /* $Revision$ */
165 /* $Date$ */
166
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_points.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #ifdef LTC_MECC
24
25 /**
26 Allocate a new ECC point
27 @return A newly allocated point or NULL on error
28 */
29 ecc_point *ltc_ecc_new_point(void)
30 {
31 ecc_point *p;
32 p = XCALLOC(1, sizeof(*p));
33 if (p == NULL) {
34 return NULL;
35 }
36 if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) {
37 XFREE(p);
38 return NULL;
39 }
40 return p;
41 }
42
43 /** Free an ECC point from memory
44 @param p The point to free
45 */
46 void ltc_ecc_del_point(ecc_point *p)
47 {
48 /* prevents free'ing null arguments */
49 if (p != NULL) {
50 mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */
51 XFREE(p);
52 }
53 }
54
55 #endif
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
59
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_projective_add_point.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
24
25 /**
26 Add two ECC points
27 @param P The point to add
28 @param Q The point to add
29 @param R [out] The destination of the double
30 @param modulus The modulus of the field the ECC curve is in
31 @param mp The "b" value from montgomery_setup()
32 @return CRYPT_OK on success
33 */
34 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp)
35 {
36 void *t1, *t2, *x, *y, *z;
37 int err;
38
39 LTC_ARGCHK(P != NULL);
40 LTC_ARGCHK(Q != NULL);
41 LTC_ARGCHK(R != NULL);
42 LTC_ARGCHK(modulus != NULL);
43 LTC_ARGCHK(mp != NULL);
44
45 if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) {
46 return err;
47 }
48
49 /* should we dbl instead? */
50 if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; }
51
52 if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) &&
53 (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) &&
54 (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) {
55 mp_clear_multi(t1, t2, x, y, z, NULL);
56 return ltc_ecc_projective_dbl_point(P, R, modulus, mp);
57 }
58
59 if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; }
60 if ((err = mp_copy(P->y, y)) != CRYPT_OK) { goto done; }
61 if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; }
62
63 /* if Z is one then these are no-operations */
64 if (Q->z != NULL) {
65 /* T1 = Z' * Z' */
66 if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; }
67 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
68 /* X = X * T1 */
69 if ((err = mp_mul(t1, x, x)) != CRYPT_OK) { goto done; }
70 if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
71 /* T1 = Z' * T1 */
72 if ((err = mp_mul(Q->z, t1, t1)) != CRYPT_OK) { goto done; }
73 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
74 /* Y = Y * T1 */
75 if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; }
76 if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; }
77 }
78
79 /* T1 = Z*Z */
80 if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; }
81 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
82 /* T2 = X' * T1 */
83 if ((err = mp_mul(Q->x, t1, t2)) != CRYPT_OK) { goto done; }
84 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
85 /* T1 = Z * T1 */
86 if ((err = mp_mul(z, t1, t1)) != CRYPT_OK) { goto done; }
87 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
88 /* T1 = Y' * T1 */
89 if ((err = mp_mul(Q->y, t1, t1)) != CRYPT_OK) { goto done; }
90 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
91
92 /* Y = Y - T1 */
93 if ((err = mp_sub(y, t1, y)) != CRYPT_OK) { goto done; }
94 if (mp_cmp_d(y, 0) == LTC_MP_LT) {
95 if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
96 }
97 /* T1 = 2T1 */
98 if ((err = mp_add(t1, t1, t1)) != CRYPT_OK) { goto done; }
99 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
100 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
101 }
102 /* T1 = Y + T1 */
103 if ((err = mp_add(t1, y, t1)) != CRYPT_OK) { goto done; }
104 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
105 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
106 }
107 /* X = X - T2 */
108 if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; }
109 if (mp_cmp_d(x, 0) == LTC_MP_LT) {
110 if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; }
111 }
112 /* T2 = 2T2 */
113 if ((err = mp_add(t2, t2, t2)) != CRYPT_OK) { goto done; }
114 if (mp_cmp(t2, modulus) != LTC_MP_LT) {
115 if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; }
116 }
117 /* T2 = X + T2 */
118 if ((err = mp_add(t2, x, t2)) != CRYPT_OK) { goto done; }
119 if (mp_cmp(t2, modulus) != LTC_MP_LT) {
120 if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; }
121 }
122
123 /* if Z' != 1 */
124 if (Q->z != NULL) {
125 /* Z = Z * Z' */
126 if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; }
127 if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; }
128 }
129
130 /* Z = Z * X */
131 if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; }
132 if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; }
133
134 /* T1 = T1 * X */
135 if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; }
136 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
137 /* X = X * X */
138 if ((err = mp_sqr(x, x)) != CRYPT_OK) { goto done; }
139 if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
140 /* T2 = T2 * x */
141 if ((err = mp_mul(t2, x, t2)) != CRYPT_OK) { goto done; }
142 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
143 /* T1 = T1 * X */
144 if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; }
145 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
146
147 /* X = Y*Y */
148 if ((err = mp_sqr(y, x)) != CRYPT_OK) { goto done; }
149 if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
150 /* X = X - T2 */
151 if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; }
152 if (mp_cmp_d(x, 0) == LTC_MP_LT) {
153 if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; }
154 }
155
156 /* T2 = T2 - X */
157 if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; }
158 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
159 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
160 }
161 /* T2 = T2 - X */
162 if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; }
163 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
164 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
165 }
166 /* T2 = T2 * Y */
167 if ((err = mp_mul(t2, y, t2)) != CRYPT_OK) { goto done; }
168 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
169 /* Y = T2 - T1 */
170 if ((err = mp_sub(t2, t1, y)) != CRYPT_OK) { goto done; }
171 if (mp_cmp_d(y, 0) == LTC_MP_LT) {
172 if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
173 }
174 /* Y = Y/2 */
175 if (mp_isodd(y)) {
176 if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
177 }
178 if ((err = mp_div_2(y, y)) != CRYPT_OK) { goto done; }
179
180 if ((err = mp_copy(x, R->x)) != CRYPT_OK) { goto done; }
181 if ((err = mp_copy(y, R->y)) != CRYPT_OK) { goto done; }
182 if ((err = mp_copy(z, R->z)) != CRYPT_OK) { goto done; }
183
184 err = CRYPT_OK;
185 done:
186 mp_clear_multi(t1, t2, x, y, z, NULL);
187 return err;
188 }
189
190 #endif
191
192 /* $Source$ */
193 /* $Revision$ */
194 /* $Date$ */
195
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
15 */
16 #include "tomcrypt.h"
17
18 /**
19 @file ltc_ecc_projective_dbl_point.c
20 ECC Crypto, Tom St Denis
21 */
22
23 #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
24
25 /**
26 Double an ECC point
27 @param P The point to double
28 @param R [out] The destination of the double
29 @param modulus The modulus of the field the ECC curve is in
30 @param mp The "b" value from montgomery_setup()
31 @return CRYPT_OK on success
32 */
33 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp)
34 {
35 void *t1, *t2;
36 int err;
37
38 LTC_ARGCHK(P != NULL);
39 LTC_ARGCHK(R != NULL);
40 LTC_ARGCHK(modulus != NULL);
41 LTC_ARGCHK(mp != NULL);
42
43 if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
44 return err;
45 }
46
47 if (P != R) {
48 if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; }
49 if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; }
50 if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; }
51 }
52
53 /* t1 = Z * Z */
54 if ((err = mp_sqr(R->z, t1)) != CRYPT_OK) { goto done; }
55 if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
56 /* Z = Y * Z */
57 if ((err = mp_mul(R->z, R->y, R->z)) != CRYPT_OK) { goto done; }
58 if ((err = mp_montgomery_reduce(R->z, modulus, mp)) != CRYPT_OK) { goto done; }
59 /* Z = 2Z */
60 if ((err = mp_add(R->z, R->z, R->z)) != CRYPT_OK) { goto done; }
61 if (mp_cmp(R->z, modulus) != LTC_MP_LT) {
62 if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; }
63 }
64
65 /* T2 = X - T1 */
66 if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; }
67 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
68 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
69 }
70 /* T1 = X + T1 */
71 if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; }
72 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
73 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
74 }
75 /* T2 = T1 * T2 */
76 if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; }
77 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
78 /* T1 = 2T2 */
79 if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; }
80 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
81 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
82 }
83 /* T1 = T1 + T2 */
84 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
85 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
86 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
87 }
88
89 /* Y = 2Y */
90 if ((err = mp_add(R->y, R->y, R->y)) != CRYPT_OK) { goto done; }
91 if (mp_cmp(R->y, modulus) != LTC_MP_LT) {
92 if ((err = mp_sub(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
93 }
94 /* Y = Y * Y */
95 if ((err = mp_sqr(R->y, R->y)) != CRYPT_OK) { goto done; }
96 if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
97 /* T2 = Y * Y */
98 if ((err = mp_sqr(R->y, t2)) != CRYPT_OK) { goto done; }
99 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
100 /* T2 = T2/2 */
101 if (mp_isodd(t2)) {
102 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
103 }
104 if ((err = mp_div_2(t2, t2)) != CRYPT_OK) { goto done; }
105 /* Y = Y * X */
106 if ((err = mp_mul(R->y, R->x, R->y)) != CRYPT_OK) { goto done; }
107 if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
108
109 /* X = T1 * T1 */
110 if ((err = mp_sqr(t1, R->x)) != CRYPT_OK) { goto done; }
111 if ((err = mp_montgomery_reduce(R->x, modulus, mp)) != CRYPT_OK) { goto done; }
112 /* X = X - Y */
113 if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; }
114 if (mp_cmp_d(R->x, 0) == LTC_MP_LT) {
115 if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; }
116 }
117 /* X = X - Y */
118 if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; }
119 if (mp_cmp_d(R->x, 0) == LTC_MP_LT) {
120 if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; }
121 }
122
123 /* Y = Y - X */
124 if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; }
125 if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
126 if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
127 }
128 /* Y = Y * T1 */
129 if ((err = mp_mul(R->y, t1, R->y)) != CRYPT_OK) { goto done; }
130 if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
131 /* Y = Y - T2 */
132 if ((err = mp_sub(R->y, t2, R->y)) != CRYPT_OK) { goto done; }
133 if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
134 if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
135 }
136
137 err = CRYPT_OK;
138 done:
139 mp_clear_multi(t1, t2, NULL);
140 return err;
141 }
142 #endif
143 /* $Source$ */
144 /* $Revision$ */
145 /* $Date$ */
146
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_i2osp.c
14 Integer to Octet I2OSP, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /* always stores the same # of bytes, pads with leading zero bytes
20 as required
21 */
22
23 /**
24 LTC_PKCS #1 Integer to binary
25 @param n The integer to store
26 @param modulus_len The length of the RSA modulus
27 @param out [out] The destination for the integer
28 @return CRYPT_OK if successful
29 */
30 int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out)
31 {
32 unsigned long size;
33
34 size = mp_unsigned_bin_size(n);
35
36 if (size > modulus_len) {
37 return CRYPT_BUFFER_OVERFLOW;
38 }
39
40 /* store it */
41 zeromem(out, modulus_len);
42 return mp_to_unsigned_bin(n, out+(modulus_len-size));
43 }
44
45 #endif /* LTC_PKCS_1 */
46
47
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_mgf1.c
14 The Mask Generation Function (MGF1) for LTC_PKCS #1, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 Perform LTC_PKCS #1 MGF1 (internal)
21 @param seed The seed for MGF1
22 @param seedlen The length of the seed
23 @param hash_idx The index of the hash desired
24 @param mask [out] The destination
25 @param masklen The length of the mask desired
26 @return CRYPT_OK if successful
27 */
28 int pkcs_1_mgf1(int hash_idx,
29 const unsigned char *seed, unsigned long seedlen,
30 unsigned char *mask, unsigned long masklen)
31 {
32 unsigned long hLen, x;
33 ulong32 counter;
34 int err;
35 hash_state *md;
36 unsigned char *buf;
37
38 LTC_ARGCHK(seed != NULL);
39 LTC_ARGCHK(mask != NULL);
40
41 /* ensure valid hash */
42 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
43 return err;
44 }
45
46 /* get hash output size */
47 hLen = hash_descriptor[hash_idx].hashsize;
48
49 /* allocate memory */
50 md = XMALLOC(sizeof(hash_state));
51 buf = XMALLOC(hLen);
52 if (md == NULL || buf == NULL) {
53 if (md != NULL) {
54 XFREE(md);
55 }
56 if (buf != NULL) {
57 XFREE(buf);
58 }
59 return CRYPT_MEM;
60 }
61
62 /* start counter */
63 counter = 0;
64
65 while (masklen > 0) {
66 /* handle counter */
67 STORE32H(counter, buf);
68 ++counter;
69
70 /* get hash of seed || counter */
71 if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
72 goto LBL_ERR;
73 }
74 if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77 if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80 if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
81 goto LBL_ERR;
82 }
83
84 /* store it */
85 for (x = 0; x < hLen && masklen > 0; x++, masklen--) {
86 *mask++ = buf[x];
87 }
88 }
89
90 err = CRYPT_OK;
91 LBL_ERR:
92 #ifdef LTC_CLEAN_STACK
93 zeromem(buf, hLen);
94 zeromem(md, sizeof(hash_state));
95 #endif
96
97 XFREE(buf);
98 XFREE(md);
99
100 return err;
101 }
102
103 #endif /* LTC_PKCS_1 */
104
105 /* $Source$ */
106 /* $Revision$ */
107 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_oaep_decode.c
14 OAEP Padding for LTC_PKCS #1, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 LTC_PKCS #1 v2.00 OAEP decode
21 @param msg The encoded data to decode
22 @param msglen The length of the encoded data (octets)
23 @param lparam The session or system data (can be NULL)
24 @param lparamlen The length of the lparam
25 @param modulus_bitlen The bit length of the RSA modulus
26 @param hash_idx The index of the hash desired
27 @param out [out] Destination of decoding
28 @param outlen [in/out] The max size and resulting size of the decoding
29 @param res [out] Result of decoding, 1==valid, 0==invalid
30 @return CRYPT_OK if successful (even if invalid)
31 */
32 int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
33 const unsigned char *lparam, unsigned long lparamlen,
34 unsigned long modulus_bitlen, int hash_idx,
35 unsigned char *out, unsigned long *outlen,
36 int *res)
37 {
38 unsigned char *DB, *seed, *mask;
39 unsigned long hLen, x, y, modulus_len;
40 int err;
41
42 LTC_ARGCHK(msg != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(res != NULL);
46
47 /* default to invalid packet */
48 *res = 0;
49
50 /* test valid hash */
51 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
52 return err;
53 }
54 hLen = hash_descriptor[hash_idx].hashsize;
55 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
56
57 /* test hash/message size */
58 if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) {
59 return CRYPT_PK_INVALID_SIZE;
60 }
61
62 /* allocate ram for DB/mask/salt of size modulus_len */
63 DB = XMALLOC(modulus_len);
64 mask = XMALLOC(modulus_len);
65 seed = XMALLOC(hLen);
66 if (DB == NULL || mask == NULL || seed == NULL) {
67 if (DB != NULL) {
68 XFREE(DB);
69 }
70 if (mask != NULL) {
71 XFREE(mask);
72 }
73 if (seed != NULL) {
74 XFREE(seed);
75 }
76 return CRYPT_MEM;
77 }
78
79 /* ok so it's now in the form
80
81 0x00 || maskedseed || maskedDB
82
83 1 || hLen || modulus_len - hLen - 1
84
85 */
86
87 /* must have leading 0x00 byte */
88 if (msg[0] != 0x00) {
89 err = CRYPT_OK;
90 goto LBL_ERR;
91 }
92
93 /* now read the masked seed */
94 x = 1;
95 XMEMCPY(seed, msg + x, hLen);
96 x += hLen;
97
98 /* now read the masked DB */
99 XMEMCPY(DB, msg + x, modulus_len - hLen - 1);
100 x += modulus_len - hLen - 1;
101
102 /* compute MGF1 of maskedDB (hLen) */
103 if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
104 goto LBL_ERR;
105 }
106
107 /* XOR against seed */
108 for (y = 0; y < hLen; y++) {
109 seed[y] ^= mask[y];
110 }
111
112 /* compute MGF1 of seed (k - hlen - 1) */
113 if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
114 goto LBL_ERR;
115 }
116
117 /* xor against DB */
118 for (y = 0; y < (modulus_len - hLen - 1); y++) {
119 DB[y] ^= mask[y];
120 }
121
122 /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */
123
124 /* compute lhash and store it in seed [reuse temps!] */
125 x = modulus_len;
126 if (lparam != NULL) {
127 if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) {
128 goto LBL_ERR;
129 }
130 } else {
131 /* can't pass hash_memory a NULL so use DB with zero length */
132 if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) {
133 goto LBL_ERR;
134 }
135 }
136
137 /* compare the lhash'es */
138 if (XMEMCMP(seed, DB, hLen) != 0) {
139 err = CRYPT_OK;
140 goto LBL_ERR;
141 }
142
143 /* now zeroes before a 0x01 */
144 for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) {
145 /* step... */
146 }
147
148 /* error out if wasn't 0x01 */
149 if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) {
150 err = CRYPT_INVALID_PACKET;
151 goto LBL_ERR;
152 }
153
154 /* rest is the message (and skip 0x01) */
155 if ((modulus_len - hLen - 1 - ++x) > *outlen) {
156 *outlen = modulus_len - hLen - 1 - x;
157 err = CRYPT_BUFFER_OVERFLOW;
158 goto LBL_ERR;
159 }
160
161 /* copy message */
162 *outlen = modulus_len - hLen - 1 - x;
163 XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x);
164 x += modulus_len - hLen - 1;
165
166 /* valid packet */
167 *res = 1;
168
169 err = CRYPT_OK;
170 LBL_ERR:
171 #ifdef LTC_CLEAN_STACK
172 zeromem(DB, modulus_len);
173 zeromem(seed, hLen);
174 zeromem(mask, modulus_len);
175 #endif
176
177 XFREE(seed);
178 XFREE(mask);
179 XFREE(DB);
180
181 return err;
182 }
183
184 #endif /* LTC_PKCS_1 */
185
186 /* $Source$ */
187 /* $Revision$ */
188 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_oaep_encode.c
14 OAEP Padding for LTC_PKCS #1, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 LTC_PKCS #1 v2.00 OAEP encode
21 @param msg The data to encode
22 @param msglen The length of the data to encode (octets)
23 @param lparam A session or system parameter (can be NULL)
24 @param lparamlen The length of the lparam data
25 @param modulus_bitlen The bit length of the RSA modulus
26 @param prng An active PRNG state
27 @param prng_idx The index of the PRNG desired
28 @param hash_idx The index of the hash desired
29 @param out [out] The destination for the encoded data
30 @param outlen [in/out] The max size and resulting size of the encoded data
31 @return CRYPT_OK if successful
32 */
33 int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
34 const unsigned char *lparam, unsigned long lparamlen,
35 unsigned long modulus_bitlen, prng_state *prng,
36 int prng_idx, int hash_idx,
37 unsigned char *out, unsigned long *outlen)
38 {
39 unsigned char *DB, *seed, *mask;
40 unsigned long hLen, x, y, modulus_len;
41 int err;
42
43 LTC_ARGCHK(msg != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 /* test valid hash */
48 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
49 return err;
50 }
51
52 /* valid prng */
53 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
54 return err;
55 }
56
57 hLen = hash_descriptor[hash_idx].hashsize;
58 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
59
60 /* test message size */
61 if ((2*hLen >= (modulus_len - 2)) || (msglen > (modulus_len - 2*hLen - 2))) {
62 return CRYPT_PK_INVALID_SIZE;
63 }
64
65 /* allocate ram for DB/mask/salt of size modulus_len */
66 DB = XMALLOC(modulus_len);
67 mask = XMALLOC(modulus_len);
68 seed = XMALLOC(hLen);
69 if (DB == NULL || mask == NULL || seed == NULL) {
70 if (DB != NULL) {
71 XFREE(DB);
72 }
73 if (mask != NULL) {
74 XFREE(mask);
75 }
76 if (seed != NULL) {
77 XFREE(seed);
78 }
79 return CRYPT_MEM;
80 }
81
82 /* get lhash */
83 /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */
84 x = modulus_len;
85 if (lparam != NULL) {
86 if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) {
87 goto LBL_ERR;
88 }
89 } else {
90 /* can't pass hash_memory a NULL so use DB with zero length */
91 if ((err = hash_memory(hash_idx, DB, 0, DB, &x)) != CRYPT_OK) {
92 goto LBL_ERR;
93 }
94 }
95
96 /* append PS then 0x01 (to lhash) */
97 x = hLen;
98 y = modulus_len - msglen - 2*hLen - 2;
99 XMEMSET(DB+x, 0, y);
100 x += y;
101
102 /* 0x01 byte */
103 DB[x++] = 0x01;
104
105 /* message (length = msglen) */
106 XMEMCPY(DB+x, msg, msglen);
107 x += msglen;
108
109 /* now choose a random seed */
110 if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) {
111 err = CRYPT_ERROR_READPRNG;
112 goto LBL_ERR;
113 }
114
115 /* compute MGF1 of seed (k - hlen - 1) */
116 if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
117 goto LBL_ERR;
118 }
119
120 /* xor against DB */
121 for (y = 0; y < (modulus_len - hLen - 1); y++) {
122 DB[y] ^= mask[y];
123 }
124
125 /* compute MGF1 of maskedDB (hLen) */
126 if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
127 goto LBL_ERR;
128 }
129
130 /* XOR against seed */
131 for (y = 0; y < hLen; y++) {
132 seed[y] ^= mask[y];
133 }
134
135 /* create string of length modulus_len */
136 if (*outlen < modulus_len) {
137 *outlen = modulus_len;
138 err = CRYPT_BUFFER_OVERFLOW;
139 goto LBL_ERR;
140 }
141
142 /* start output which is 0x00 || maskedSeed || maskedDB */
143 x = 0;
144 out[x++] = 0x00;
145 XMEMCPY(out+x, seed, hLen);
146 x += hLen;
147 XMEMCPY(out+x, DB, modulus_len - hLen - 1);
148 x += modulus_len - hLen - 1;
149
150 *outlen = x;
151
152 err = CRYPT_OK;
153 LBL_ERR:
154 #ifdef LTC_CLEAN_STACK
155 zeromem(DB, modulus_len);
156 zeromem(seed, hLen);
157 zeromem(mask, modulus_len);
158 #endif
159
160 XFREE(seed);
161 XFREE(mask);
162 XFREE(DB);
163
164 return err;
165 }
166
167 #endif /* LTC_PKCS_1 */
168
169
170 /* $Source$ */
171 /* $Revision$ */
172 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_os2ip.c
14 Octet to Integer OS2IP, Tom St Denis
15 */
16 #ifdef LTC_PKCS_1
17
18 /**
19 Read a binary string into an mp_int
20 @param n [out] The mp_int destination
21 @param in The binary string to read
22 @param inlen The length of the binary string
23 @return CRYPT_OK if successful
24 */
25 int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen)
26 {
27 return mp_read_unsigned_bin(n, in, inlen);
28 }
29
30 #endif /* LTC_PKCS_1 */
31
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_pss_decode.c
14 LTC_PKCS #1 PSS Signature Padding, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 LTC_PKCS #1 v2.00 PSS decode
21 @param msghash The hash to verify
22 @param msghashlen The length of the hash (octets)
23 @param sig The signature data (encoded data)
24 @param siglen The length of the signature data (octets)
25 @param saltlen The length of the salt used (octets)
26 @param hash_idx The index of the hash desired
27 @param modulus_bitlen The bit length of the RSA modulus
28 @param res [out] The result of the comparison, 1==valid, 0==invalid
29 @return CRYPT_OK if successful (even if the comparison failed)
30 */
31 int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
32 const unsigned char *sig, unsigned long siglen,
33 unsigned long saltlen, int hash_idx,
34 unsigned long modulus_bitlen, int *res)
35 {
36 unsigned char *DB, *mask, *salt, *hash;
37 unsigned long x, y, hLen, modulus_len;
38 int err;
39 hash_state md;
40
41 LTC_ARGCHK(msghash != NULL);
42 LTC_ARGCHK(res != NULL);
43
44 /* default to invalid */
45 *res = 0;
46
47 /* ensure hash is valid */
48 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
49 return err;
50 }
51
52 hLen = hash_descriptor[hash_idx].hashsize;
53 modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
54
55 /* check sizes */
56 if ((saltlen > modulus_len) ||
57 (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) {
58 return CRYPT_PK_INVALID_SIZE;
59 }
60
61 /* allocate ram for DB/mask/salt/hash of size modulus_len */
62 DB = XMALLOC(modulus_len);
63 mask = XMALLOC(modulus_len);
64 salt = XMALLOC(modulus_len);
65 hash = XMALLOC(modulus_len);
66 if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) {
67 if (DB != NULL) {
68 XFREE(DB);
69 }
70 if (mask != NULL) {
71 XFREE(mask);
72 }
73 if (salt != NULL) {
74 XFREE(salt);
75 }
76 if (hash != NULL) {
77 XFREE(hash);
78 }
79 return CRYPT_MEM;
80 }
81
82 /* ensure the 0xBC byte */
83 if (sig[siglen-1] != 0xBC) {
84 err = CRYPT_INVALID_PACKET;
85 goto LBL_ERR;
86 }
87
88 /* copy out the DB */
89 x = 0;
90 XMEMCPY(DB, sig + x, modulus_len - hLen - 1);
91 x += modulus_len - hLen - 1;
92
93 /* copy out the hash */
94 XMEMCPY(hash, sig + x, hLen);
95 x += hLen;
96
97 /* check the MSB */
98 if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
99 err = CRYPT_INVALID_PACKET;
100 goto LBL_ERR;
101 }
102
103 /* generate mask of length modulus_len - hLen - 1 from hash */
104 if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
105 goto LBL_ERR;
106 }
107
108 /* xor against DB */
109 for (y = 0; y < (modulus_len - hLen - 1); y++) {
110 DB[y] ^= mask[y];
111 }
112
113 /* now clear the first byte [make sure smaller than modulus] */
114 DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
115
116 /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
117
118 /* check for zeroes and 0x01 */
119 for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) {
120 if (DB[x] != 0x00) {
121 err = CRYPT_INVALID_PACKET;
122 goto LBL_ERR;
123 }
124 }
125
126 /* check for the 0x01 */
127 if (DB[x++] != 0x01) {
128 err = CRYPT_INVALID_PACKET;
129 goto LBL_ERR;
130 }
131
132 /* M = (eight) 0x00 || msghash || salt, mask = H(M) */
133 if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) {
134 goto LBL_ERR;
135 }
136 zeromem(mask, 8);
137 if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) {
138 goto LBL_ERR;
139 }
140 if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) {
141 goto LBL_ERR;
142 }
143 if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) {
144 goto LBL_ERR;
145 }
146 if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) {
147 goto LBL_ERR;
148 }
149
150 /* mask == hash means valid signature */
151 if (XMEMCMP(mask, hash, hLen) == 0) {
152 *res = 1;
153 }
154
155 err = CRYPT_OK;
156 LBL_ERR:
157 #ifdef LTC_CLEAN_STACK
158 zeromem(DB, modulus_len);
159 zeromem(mask, modulus_len);
160 zeromem(salt, modulus_len);
161 zeromem(hash, modulus_len);
162 #endif
163
164 XFREE(hash);
165 XFREE(salt);
166 XFREE(mask);
167 XFREE(DB);
168
169 return err;
170 }
171
172 #endif /* LTC_PKCS_1 */
173
174 /* $Source$ */
175 /* $Revision$ */
176 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file pkcs_1_pss_encode.c
14 LTC_PKCS #1 PSS Signature Padding, Tom St Denis
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /**
20 LTC_PKCS #1 v2.00 Signature Encoding
21 @param msghash The hash to encode
22 @param msghashlen The length of the hash (octets)
23 @param saltlen The length of the salt desired (octets)
24 @param prng An active PRNG context
25 @param prng_idx The index of the PRNG desired
26 @param hash_idx The index of the hash desired
27 @param modulus_bitlen The bit length of the RSA modulus
28 @param out [out] The destination of the encoding
29 @param outlen [in/out] The max size and resulting size of the encoded data
30 @return CRYPT_OK if successful
31 */
32 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
33 unsigned long saltlen, prng_state *prng,
34 int prng_idx, int hash_idx,
35 unsigned long modulus_bitlen,
36 unsigned char *out, unsigned long *outlen)
37 {
38 unsigned char *DB, *mask, *salt, *hash;
39 unsigned long x, y, hLen, modulus_len;
40 int err;
41 hash_state md;
42
43 LTC_ARGCHK(msghash != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46
47 /* ensure hash and PRNG are valid */
48 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
49 return err;
50 }
51 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
52 return err;
53 }
54
55 hLen = hash_descriptor[hash_idx].hashsize;
56 modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
57
58 /* check sizes */
59 if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2)) {
60 return CRYPT_PK_INVALID_SIZE;
61 }
62
63 /* allocate ram for DB/mask/salt/hash of size modulus_len */
64 DB = XMALLOC(modulus_len);
65 mask = XMALLOC(modulus_len);
66 salt = XMALLOC(modulus_len);
67 hash = XMALLOC(modulus_len);
68 if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) {
69 if (DB != NULL) {
70 XFREE(DB);
71 }
72 if (mask != NULL) {
73 XFREE(mask);
74 }
75 if (salt != NULL) {
76 XFREE(salt);
77 }
78 if (hash != NULL) {
79 XFREE(hash);
80 }
81 return CRYPT_MEM;
82 }
83
84
85 /* generate random salt */
86 if (saltlen > 0) {
87 if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) {
88 err = CRYPT_ERROR_READPRNG;
89 goto LBL_ERR;
90 }
91 }
92
93 /* M = (eight) 0x00 || msghash || salt, hash = H(M) */
94 if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) {
95 goto LBL_ERR;
96 }
97 zeromem(DB, 8);
98 if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) {
99 goto LBL_ERR;
100 }
101 if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104 if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) {
105 goto LBL_ERR;
106 }
107 if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) {
108 goto LBL_ERR;
109 }
110
111 /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
112 x = 0;
113 XMEMSET(DB + x, 0, modulus_len - saltlen - hLen - 2);
114 x += modulus_len - saltlen - hLen - 2;
115 DB[x++] = 0x01;
116 XMEMCPY(DB + x, salt, saltlen);
117 x += saltlen;
118
119 /* generate mask of length modulus_len - hLen - 1 from hash */
120 if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
121 goto LBL_ERR;
122 }
123
124 /* xor against DB */
125 for (y = 0; y < (modulus_len - hLen - 1); y++) {
126 DB[y] ^= mask[y];
127 }
128
129 /* output is DB || hash || 0xBC */
130 if (*outlen < modulus_len) {
131 *outlen = modulus_len;
132 err = CRYPT_BUFFER_OVERFLOW;
133 goto LBL_ERR;
134 }
135
136 /* DB len = modulus_len - hLen - 1 */
137 y = 0;
138 XMEMCPY(out + y, DB, modulus_len - hLen - 1);
139 y += modulus_len - hLen - 1;
140
141 /* hash */
142 XMEMCPY(out + y, hash, hLen);
143 y += hLen;
144
145 /* 0xBC */
146 out[y] = 0xBC;
147
148 /* now clear the 8*modulus_len - modulus_bitlen most significant bits */
149 out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
150
151 /* store output size */
152 *outlen = modulus_len;
153 err = CRYPT_OK;
154 LBL_ERR:
155 #ifdef LTC_CLEAN_STACK
156 zeromem(DB, modulus_len);
157 zeromem(mask, modulus_len);
158 zeromem(salt, modulus_len);
159 zeromem(hash, modulus_len);
160 #endif
161
162 XFREE(hash);
163 XFREE(salt);
164 XFREE(mask);
165 XFREE(DB);
166
167 return err;
168 }
169
170 #endif /* LTC_PKCS_1 */
171
172 /* $Source$ */
173 /* $Revision$ */
174 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /** @file pkcs_1_v1_5_decode.c
13 *
14 * LTC_PKCS #1 v1.5 Padding. (Andreas Lange)
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /** @brief LTC_PKCS #1 v1.5 decode.
20 *
21 * @param msg The encoded data to decode
22 * @param msglen The length of the encoded data (octets)
23 * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
24 * @param modulus_bitlen The bit length of the RSA modulus
25 * @param out [out] Destination of decoding
26 * @param outlen [in/out] The max size and resulting size of the decoding
27 * @param is_valid [out] Boolean whether the padding was valid
28 *
29 * @return CRYPT_OK if successful (even if invalid)
30 */
31 int pkcs_1_v1_5_decode(const unsigned char *msg,
32 unsigned long msglen,
33 int block_type,
34 unsigned long modulus_bitlen,
35 unsigned char *out,
36 unsigned long *outlen,
37 int *is_valid)
38 {
39 unsigned long modulus_len, ps_len, i;
40 int result;
41
42 /* default to invalid packet */
43 *is_valid = 0;
44
45 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
46
47 /* test message size */
48
49 if ((msglen > modulus_len) || (modulus_len < 11)) {
50 return CRYPT_PK_INVALID_SIZE;
51 }
52
53 /* separate encoded message */
54
55 if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) {
56 result = CRYPT_INVALID_PACKET;
57 goto bail;
58 }
59
60 if (block_type == LTC_PKCS_1_EME) {
61 for (i = 2; i < modulus_len; i++) {
62 /* separator */
63 if (msg[i] == 0x00) { break; }
64 }
65 ps_len = i++ - 2;
66
67 if ((i >= modulus_len) || (ps_len < 8)) {
68 /* There was no octet with hexadecimal value 0x00 to separate ps from m,
69 * or the length of ps is less than 8 octets.
70 */
71 result = CRYPT_INVALID_PACKET;
72 goto bail;
73 }
74 } else {
75 for (i = 2; i < modulus_len - 1; i++) {
76 if (msg[i] != 0xFF) { break; }
77 }
78
79 /* separator check */
80 if (msg[i] != 0) {
81 /* There was no octet with hexadecimal value 0x00 to separate ps from m. */
82 result = CRYPT_INVALID_PACKET;
83 goto bail;
84 }
85
86 ps_len = i - 2;
87 }
88
89 if (*outlen < (msglen - (2 + ps_len + 1))) {
90 *outlen = msglen - (2 + ps_len + 1);
91 result = CRYPT_BUFFER_OVERFLOW;
92 goto bail;
93 }
94
95 *outlen = (msglen - (2 + ps_len + 1));
96 XMEMCPY(out, &msg[2 + ps_len + 1], *outlen);
97
98 /* valid packet */
99 *is_valid = 1;
100 result = CRYPT_OK;
101 bail:
102 return result;
103 } /* pkcs_1_v1_5_decode */
104
105 #endif /* #ifdef LTC_PKCS_1 */
106
107 /* $Source$ */
108 /* $Revision$ */
109 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /*! \file pkcs_1_v1_5_encode.c
13 *
14 * LTC_PKCS #1 v1.5 Padding (Andreas Lange)
15 */
16
17 #ifdef LTC_PKCS_1
18
19 /*! \brief LTC_PKCS #1 v1.5 encode.
20 *
21 * \param msg The data to encode
22 * \param msglen The length of the data to encode (octets)
23 * \param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
24 * \param modulus_bitlen The bit length of the RSA modulus
25 * \param prng An active PRNG state (only for LTC_PKCS_1_EME)
26 * \param prng_idx The index of the PRNG desired (only for LTC_PKCS_1_EME)
27 * \param out [out] The destination for the encoded data
28 * \param outlen [in/out] The max size and resulting size of the encoded data
29 *
30 * \return CRYPT_OK if successful
31 */
32 int pkcs_1_v1_5_encode(const unsigned char *msg,
33 unsigned long msglen,
34 int block_type,
35 unsigned long modulus_bitlen,
36 prng_state *prng,
37 int prng_idx,
38 unsigned char *out,
39 unsigned long *outlen)
40 {
41 unsigned long modulus_len, ps_len, i;
42 unsigned char *ps;
43 int result;
44
45 /* valid block_type? */
46 if ((block_type != LTC_PKCS_1_EMSA) &&
47 (block_type != LTC_PKCS_1_EME)) {
48 return CRYPT_PK_INVALID_PADDING;
49 }
50
51 if (block_type == LTC_PKCS_1_EME) { /* encryption padding, we need a valid PRNG */
52 if ((result = prng_is_valid(prng_idx)) != CRYPT_OK) {
53 return result;
54 }
55 }
56
57 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
58
59 /* test message size */
60 if ((msglen + 11) > modulus_len) {
61 return CRYPT_PK_INVALID_SIZE;
62 }
63
64 if (*outlen < modulus_len) {
65 *outlen = modulus_len;
66 result = CRYPT_BUFFER_OVERFLOW;
67 goto bail;
68 }
69
70 /* generate an octets string PS */
71 ps = &out[2];
72 ps_len = modulus_len - msglen - 3;
73
74 if (block_type == LTC_PKCS_1_EME) {
75 /* now choose a random ps */
76 if (prng_descriptor[prng_idx].read(ps, ps_len, prng) != ps_len) {
77 result = CRYPT_ERROR_READPRNG;
78 goto bail;
79 }
80
81 /* transform zero bytes (if any) to non-zero random bytes */
82 for (i = 0; i < ps_len; i++) {
83 while (ps[i] == 0) {
84 if (prng_descriptor[prng_idx].read(&ps[i], 1, prng) != 1) {
85 result = CRYPT_ERROR_READPRNG;
86 goto bail;
87 }
88 }
89 }
90 } else {
91 XMEMSET(ps, 0xFF, ps_len);
92 }
93
94 /* create string of length modulus_len */
95 out[0] = 0x00;
96 out[1] = (unsigned char)block_type; /* block_type 1 or 2 */
97 out[2 + ps_len] = 0x00;
98 XMEMCPY(&out[2 + ps_len + 1], msg, msglen);
99 *outlen = modulus_len;
100
101 result = CRYPT_OK;
102 bail:
103 return result;
104 } /* pkcs_1_v1_5_encode */
105
106 #endif /* #ifdef LTC_PKCS_1 */
107
108 /* $Source$ */
109 /* $Revision$ */
110 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_decrypt_key.c
14 RSA LTC_PKCS #1 Decryption, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 LTC_PKCS #1 decrypt then v1.5 or OAEP depad
21 @param in The ciphertext
22 @param inlen The length of the ciphertext (octets)
23 @param out [out] The plaintext
24 @param outlen [in/out] The max size and resulting size of the plaintext (octets)
25 @param lparam The system "lparam" value
26 @param lparamlen The length of the lparam value (octets)
27 @param hash_idx The index of the hash desired
28 @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5)
29 @param stat [out] Result of the decryption, 1==valid, 0==invalid
30 @param key The corresponding private RSA key
31 @return CRYPT_OK if succcessul (even if invalid)
32 */
33 int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *lparam, unsigned long lparamlen,
36 int hash_idx, int padding,
37 int *stat, rsa_key *key)
38 {
39 unsigned long modulus_bitlen, modulus_bytelen, x;
40 int err;
41 unsigned char *tmp;
42
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(key != NULL);
46 LTC_ARGCHK(stat != NULL);
47
48 /* default to invalid */
49 *stat = 0;
50
51 /* valid padding? */
52
53 if ((padding != LTC_PKCS_1_V1_5) &&
54 (padding != LTC_PKCS_1_OAEP)) {
55 return CRYPT_PK_INVALID_PADDING;
56 }
57
58 if (padding == LTC_PKCS_1_OAEP) {
59 /* valid hash ? */
60 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
61 return err;
62 }
63 }
64
65 /* get modulus len in bits */
66 modulus_bitlen = mp_count_bits( (key->N));
67
68 /* outlen must be at least the size of the modulus */
69 modulus_bytelen = mp_unsigned_bin_size( (key->N));
70 if (modulus_bytelen != inlen) {
71 return CRYPT_INVALID_PACKET;
72 }
73
74 /* allocate ram */
75 tmp = XMALLOC(inlen);
76 if (tmp == NULL) {
77 return CRYPT_MEM;
78 }
79
80 /* rsa decode the packet */
81 x = inlen;
82 if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) {
83 XFREE(tmp);
84 return err;
85 }
86
87 if (padding == LTC_PKCS_1_OAEP) {
88 /* now OAEP decode the packet */
89 err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx,
90 out, outlen, stat);
91 } else {
92 /* now LTC_PKCS #1 v1.5 depad the packet */
93 err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat);
94 }
95
96 XFREE(tmp);
97 return err;
98 }
99
100 #endif /* LTC_MRSA */
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_encrypt_key.c
14 RSA LTC_PKCS #1 encryption, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 (LTC_PKCS #1 v2.0) OAEP pad then encrypt
21 @param in The plaintext
22 @param inlen The length of the plaintext (octets)
23 @param out [out] The ciphertext
24 @param outlen [in/out] The max size and resulting size of the ciphertext
25 @param lparam The system "lparam" for the encryption
26 @param lparamlen The length of lparam (octets)
27 @param prng An active PRNG
28 @param prng_idx The index of the desired prng
29 @param hash_idx The index of the desired hash
30 @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5)
31 @param key The RSA key to encrypt to
32 @return CRYPT_OK if successful
33 */
34 int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
35 unsigned char *out, unsigned long *outlen,
36 const unsigned char *lparam, unsigned long lparamlen,
37 prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key)
38 {
39 unsigned long modulus_bitlen, modulus_bytelen, x;
40 int err;
41
42 LTC_ARGCHK(in != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(key != NULL);
46
47 /* valid padding? */
48 if ((padding != LTC_PKCS_1_V1_5) &&
49 (padding != LTC_PKCS_1_OAEP)) {
50 return CRYPT_PK_INVALID_PADDING;
51 }
52
53 /* valid prng? */
54 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
55 return err;
56 }
57
58 if (padding == LTC_PKCS_1_OAEP) {
59 /* valid hash? */
60 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
61 return err;
62 }
63 }
64
65 /* get modulus len in bits */
66 modulus_bitlen = mp_count_bits( (key->N));
67
68 /* outlen must be at least the size of the modulus */
69 modulus_bytelen = mp_unsigned_bin_size( (key->N));
70 if (modulus_bytelen > *outlen) {
71 *outlen = modulus_bytelen;
72 return CRYPT_BUFFER_OVERFLOW;
73 }
74
75 if (padding == LTC_PKCS_1_OAEP) {
76 /* OAEP pad the key */
77 x = *outlen;
78 if ((err = pkcs_1_oaep_encode(in, inlen, lparam,
79 lparamlen, modulus_bitlen, prng, prng_idx, hash_idx,
80 out, &x)) != CRYPT_OK) {
81 return err;
82 }
83 } else {
84 /* LTC_PKCS #1 v1.5 pad the key */
85 x = *outlen;
86 if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_PKCS_1_EME,
87 modulus_bitlen, prng, prng_idx,
88 out, &x)) != CRYPT_OK) {
89 return err;
90 }
91 }
92
93 /* rsa exptmod the OAEP or LTC_PKCS #1 v1.5 pad */
94 return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key);
95 }
96
97 #endif /* LTC_MRSA */
98
99 /* $Source$ */
100 /* $Revision$ */
101 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_export.c
14 Export RSA LTC_PKCS keys, Tom St Denis
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 This will export either an RSAPublicKey or RSAPrivateKey [defined in LTC_PKCS #1 v2.1]
21 @param out [out] Destination of the packet
22 @param outlen [in/out] The max size and resulting size of the packet
23 @param type The type of exported key (PK_PRIVATE or PK_PUBLIC)
24 @param key The RSA key to export
25 @return CRYPT_OK if successful
26 */
27 int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
28 {
29 unsigned long zero=0;
30 int err;
31 LTC_ARGCHK(out != NULL);
32 LTC_ARGCHK(outlen != NULL);
33 LTC_ARGCHK(key != NULL);
34
35 /* type valid? */
36 if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) {
37 return CRYPT_PK_INVALID_TYPE;
38 }
39
40 if (type == PK_PRIVATE) {
41 /* private key */
42 /* output is
43 Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p
44 */
45 return der_encode_sequence_multi(out, outlen,
46 LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
47 LTC_ASN1_INTEGER, 1UL, key->N,
48 LTC_ASN1_INTEGER, 1UL, key->e,
49 LTC_ASN1_INTEGER, 1UL, key->d,
50 LTC_ASN1_INTEGER, 1UL, key->p,
51 LTC_ASN1_INTEGER, 1UL, key->q,
52 LTC_ASN1_INTEGER, 1UL, key->dP,
53 LTC_ASN1_INTEGER, 1UL, key->dQ,
54 LTC_ASN1_INTEGER, 1UL, key->qP,
55 LTC_ASN1_EOL, 0UL, NULL);
56 } else {
57 /* public key */
58 unsigned long tmplen = (mp_count_bits(key->N)/8)*2+8;
59 unsigned char* tmp = XMALLOC(tmplen);
60
61 if (tmp == NULL) {
62 return CRYPT_MEM;
63 }
64
65 err = der_encode_sequence_multi(tmp, &tmplen,
66 LTC_ASN1_INTEGER, 1UL, key->N,
67 LTC_ASN1_INTEGER, 1UL, key->e,
68 LTC_ASN1_EOL, 0UL, NULL);
69
70 if (err != CRYPT_OK) {
71 goto error;
72 }
73
74 err = der_encode_subject_public_key_info(out, outlen,
75 PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0);
76
77 error:
78 XFREE(tmp);
79 return err;
80
81 }
82 }
83
84 #endif /* LTC_MRSA */
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 *
10 * Added RSA blinding --nmav
11 */
12 #include "tomcrypt.h"
13
14 /**
15 @file rsa_exptmod.c
16 RSA LTC_PKCS exptmod, Tom St Denis
17 */
18
19 #ifdef LTC_MRSA
20
21 /**
22 Compute an RSA modular exponentiation
23 @param in The input data to send into RSA
24 @param inlen The length of the input (octets)
25 @param out [out] The destination
26 @param outlen [in/out] The max size and resulting size of the output
27 @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC
28 @param key The RSA key to use
29 @return CRYPT_OK if successful
30 */
31 int rsa_exptmod(const unsigned char *in, unsigned long inlen,
32 unsigned char *out, unsigned long *outlen, int which,
33 rsa_key *key)
34 {
35 void *tmp, *tmpa, *tmpb;
36 #ifdef LTC_RSA_BLINDING
37 void *rnd = NULL, *rndi = NULL /* inverse of rnd */;
38 #endif
39 unsigned long x;
40 int err;
41
42 LTC_ARGCHK(in != NULL);
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(key != NULL);
46
47 /* is the key of the right type for the operation? */
48 if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) {
49 return CRYPT_PK_NOT_PRIVATE;
50 }
51
52 /* must be a private or public operation */
53 if (which != PK_PRIVATE && which != PK_PUBLIC) {
54 return CRYPT_PK_INVALID_TYPE;
55 }
56
57 /* init and copy into tmp */
58 if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK)
59 { return err; }
60 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK)
61 { goto error; }
62
63
64 /* sanity check on the input */
65 if (mp_cmp(key->N, tmp) == LTC_MP_LT) {
66 err = CRYPT_PK_INVALID_SIZE;
67 goto error;
68 }
69
70 /* are we using the private exponent and is the key optimized? */
71 if (which == PK_PRIVATE) {
72 #ifdef LTC_RSA_BLINDING
73 if ((err = mp_init_multi(&rnd, &rndi, NULL)) != CRYPT_OK)
74 { goto error; }
75 /* do blinding */
76 err = mp_rand(rnd, mp_count_bits(key->N));
77 if (err != CRYPT_OK) {
78 goto error_blind;
79 }
80
81 /* rndi = 1/rnd mod N */
82 err = mp_invmod(rnd, key->N, rndi);
83 if (err != CRYPT_OK) {
84 goto error_blind;
85 }
86
87 /* rnd = rnd^e */
88 err = mp_exptmod( rnd, key->e, key->N, rnd);
89 if (err != CRYPT_OK) {
90 goto error_blind;
91 }
92
93 /* tmp = tmp*rnd mod N */
94 err = mp_mulmod( tmp, rnd, key->N, tmp);
95 if (err != CRYPT_OK) {
96 goto error_blind;
97 }
98 #endif /* LTC_RSA_BLINDING */
99
100 /* tmpa = tmp^dP mod p */
101 if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error_blind; }
102
103 /* tmpb = tmp^dQ mod q */
104 if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error_blind; }
105
106 /* tmp = (tmpa - tmpb) * qInv (mod p) */
107 if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error_blind; }
108 if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error_blind; }
109
110 /* tmp = tmpb + q * tmp */
111 if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error_blind; }
112 if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error_blind; }
113
114 #ifdef LTC_RSA_BLINDING
115 /* unblind */
116 err = mp_mulmod( tmp, rndi, key->N, tmp);
117 if (err != CRYPT_OK) {
118 goto error_blind;
119 }
120 #endif
121 } else {
122 /* exptmod it */
123 if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; }
124 }
125
126 /* read it back */
127 x = (unsigned long)mp_unsigned_bin_size(key->N);
128 if (x > *outlen) {
129 *outlen = x;
130 err = CRYPT_BUFFER_OVERFLOW;
131 goto error;
132 }
133
134 /* this should never happen ... */
135 if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) {
136 err = CRYPT_ERROR;
137 goto error;
138 }
139 *outlen = x;
140
141 /* convert it */
142 zeromem(out, x);
143 if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; }
144
145 /* clean up and return */
146 err = CRYPT_OK;
147 error_blind:
148 #ifdef LTC_RSA_BLINDING
149 mp_clear_multi(rnd, rndi, NULL);
150 #endif
151 error:
152 mp_clear_multi(tmp, tmpa, tmpb, NULL);
153 return err;
154 }
155
156 #endif
157
158 /* $Source$ */
159 /* $Revision$ */
160 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_free.c
14 Free an RSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 Free an RSA key from memory
21 @param key The RSA key to free
22 */
23 void rsa_free(rsa_key *key)
24 {
25 LTC_ARGCHKVD(key != NULL);
26 mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
27 }
28
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_import.c
14 Import a LTC_PKCS RSA key, Tom St Denis
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1]
21 @param in The packet to import from
22 @param inlen It's length (octets)
23 @param key [out] Destination for newly imported key
24 @return CRYPT_OK if successful, upon error allocated memory is freed
25 */
26 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
27 {
28 int err;
29 void *zero;
30 unsigned char *tmpbuf=NULL;
31 unsigned long tmpbuf_len;
32
33 LTC_ARGCHK(in != NULL);
34 LTC_ARGCHK(key != NULL);
35 LTC_ARGCHK(ltc_mp.name != NULL);
36
37 /* init key */
38 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,
39 &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
40 return err;
41 }
42
43 /* see if the OpenSSL DER format RSA public key will work */
44 tmpbuf_len = MAX_RSA_SIZE * 8;
45 tmpbuf = XCALLOC(1, tmpbuf_len);
46 if (tmpbuf == NULL) {
47 err = CRYPT_MEM;
48 goto LBL_ERR;
49 }
50
51 err = der_decode_subject_public_key_info(in, inlen,
52 PKA_RSA, tmpbuf, &tmpbuf_len,
53 LTC_ASN1_NULL, NULL, 0);
54
55 if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */
56
57 /* now it should be SEQUENCE { INTEGER, INTEGER } */
58 if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len,
59 LTC_ASN1_INTEGER, 1UL, key->N,
60 LTC_ASN1_INTEGER, 1UL, key->e,
61 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
62 goto LBL_ERR;
63 }
64 key->type = PK_PUBLIC;
65 err = CRYPT_OK;
66 goto LBL_FREE;
67 }
68
69 /* not SSL public key, try to match against LTC_PKCS #1 standards */
70 if ((err = der_decode_sequence_multi(in, inlen,
71 LTC_ASN1_INTEGER, 1UL, key->N,
72 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
73 goto LBL_ERR;
74 }
75
76 if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) {
77 if ((err = mp_init(&zero)) != CRYPT_OK) {
78 goto LBL_ERR;
79 }
80 /* it's a private key */
81 if ((err = der_decode_sequence_multi(in, inlen,
82 LTC_ASN1_INTEGER, 1UL, zero,
83 LTC_ASN1_INTEGER, 1UL, key->N,
84 LTC_ASN1_INTEGER, 1UL, key->e,
85 LTC_ASN1_INTEGER, 1UL, key->d,
86 LTC_ASN1_INTEGER, 1UL, key->p,
87 LTC_ASN1_INTEGER, 1UL, key->q,
88 LTC_ASN1_INTEGER, 1UL, key->dP,
89 LTC_ASN1_INTEGER, 1UL, key->dQ,
90 LTC_ASN1_INTEGER, 1UL, key->qP,
91 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
92 mp_clear(zero);
93 goto LBL_ERR;
94 }
95 mp_clear(zero);
96 key->type = PK_PRIVATE;
97 } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) {
98 /* we don't support multi-prime RSA */
99 err = CRYPT_PK_INVALID_TYPE;
100 goto LBL_ERR;
101 } else {
102 /* it's a public key and we lack e */
103 if ((err = der_decode_sequence_multi(in, inlen,
104 LTC_ASN1_INTEGER, 1UL, key->N,
105 LTC_ASN1_INTEGER, 1UL, key->e,
106 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
107 goto LBL_ERR;
108 }
109 key->type = PK_PUBLIC;
110 }
111 err = CRYPT_OK;
112 goto LBL_FREE;
113
114 LBL_ERR:
115 mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
116
117 LBL_FREE:
118 if (tmpbuf != NULL)
119 XFREE(tmpbuf);
120
121 return err;
122 }
123
124 #endif /* LTC_MRSA */
125
126
127 /* $Source$ */
128 /* $Revision$ */
129 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_make_key.c
14 RSA key generation, Tom St Denis
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 Create an RSA key
21 @param prng An active PRNG state
22 @param wprng The index of the PRNG desired
23 @param size The size of the modulus (key size) desired (octets)
24 @param e The "e" value (public key). e==65537 is a good choice
25 @param key [out] Destination of a newly created private key pair
26 @return CRYPT_OK if successful, upon error all allocated ram is freed
27 */
28 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
29 {
30 void *p, *q, *tmp1, *tmp2, *tmp3;
31 int err;
32
33 LTC_ARGCHK(ltc_mp.name != NULL);
34 LTC_ARGCHK(key != NULL);
35
36 if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
37 return CRYPT_INVALID_KEYSIZE;
38 }
39
40 if ((e < 3) || ((e & 1) == 0)) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
45 return err;
46 }
47
48 if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) {
49 return err;
50 }
51
52 /* make primes p and q (optimization provided by Wayne Scott) */
53 if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto errkey; } /* tmp3 = e */
54
55 /* make prime "p" */
56 do {
57 if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; }
58 if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = p-1 */
59 if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(p-1, e) */
60 } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides p-1 */
61
62 /* make prime "q" */
63 do {
64 if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; }
65 if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */
66 if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(q-1, e) */
67 } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides q-1 */
68
69 /* tmp1 = lcm(p-1, q-1) */
70 if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */
71 /* tmp1 = q-1 (previous do/while loop) */
72 if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = lcm(p-1, q-1) */
73
74 /* make key */
75 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
76 goto errkey;
77 }
78
79 if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */
80 if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */
81 if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */
82
83 /* optimize for CRT now */
84 /* find d mod q-1 and d mod p-1 */
85 if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */
86 if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */
87 if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */
88 if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */
89 if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */
90
91 if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto errkey; }
92 if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto errkey; }
93
94 /* set key type (in this case it's CRT optimized) */
95 key->type = PK_PRIVATE;
96
97 /* return ok and free temps */
98 err = CRYPT_OK;
99 goto cleanup;
100 errkey:
101 mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
102 cleanup:
103 mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL);
104 return err;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_sign_hash.c
14 RSA LTC_PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 LTC_PKCS #1 pad then sign
21 @param in The hash to sign
22 @param inlen The length of the hash to sign (octets)
23 @param out [out] The signature
24 @param outlen [in/out] The max size and resulting size of the signature
25 @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5)
26 @param prng An active PRNG state
27 @param prng_idx The index of the PRNG desired
28 @param hash_idx The index of the hash desired
29 @param saltlen The length of the salt desired (octets)
30 @param key The private RSA key to use
31 @return CRYPT_OK if successful
32 */
33 int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
34 unsigned char *out, unsigned long *outlen,
35 int padding,
36 prng_state *prng, int prng_idx,
37 int hash_idx, unsigned long saltlen,
38 rsa_key *key)
39 {
40 unsigned long modulus_bitlen, modulus_bytelen, x, y;
41 int err;
42
43 LTC_ARGCHK(in != NULL);
44 LTC_ARGCHK(out != NULL);
45 LTC_ARGCHK(outlen != NULL);
46 LTC_ARGCHK(key != NULL);
47
48 /* valid padding? */
49 if ((padding != LTC_PKCS_1_V1_5) && (padding != LTC_PKCS_1_PSS)) {
50 return CRYPT_PK_INVALID_PADDING;
51 }
52
53 if (padding == LTC_PKCS_1_PSS) {
54 /* valid prng and hash ? */
55 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
56 return err;
57 }
58 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
59 return err;
60 }
61 }
62
63 /* get modulus len in bits */
64 modulus_bitlen = mp_count_bits((key->N));
65
66 /* outlen must be at least the size of the modulus */
67 modulus_bytelen = mp_unsigned_bin_size((key->N));
68 if (modulus_bytelen > *outlen) {
69 *outlen = modulus_bytelen;
70 return CRYPT_BUFFER_OVERFLOW;
71 }
72
73 if (padding == LTC_PKCS_1_PSS) {
74 /* PSS pad the key */
75 x = *outlen;
76 if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx,
77 hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) {
78 return err;
79 }
80 } else {
81 /* LTC_PKCS #1 v1.5 pad the hash */
82 unsigned char *tmpin;
83 ltc_asn1_list digestinfo[2], siginfo[2];
84
85 /* not all hashes have OIDs... so sad */
86 if (hash_descriptor[hash_idx].OIDlen == 0) {
87 return CRYPT_INVALID_ARG;
88 }
89
90 /* construct the SEQUENCE
91 SEQUENCE {
92 SEQUENCE {hashoid OID
93 blah NULL
94 }
95 hash OCTET STRING
96 }
97 */
98 LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen);
99 LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
100 LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
101 LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen);
102
103 /* allocate memory for the encoding */
104 y = mp_unsigned_bin_size(key->N);
105 tmpin = XMALLOC(y);
106 if (tmpin == NULL) {
107 return CRYPT_MEM;
108 }
109
110 if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) {
111 XFREE(tmpin);
112 return err;
113 }
114
115 x = *outlen;
116 if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_PKCS_1_EMSA,
117 modulus_bitlen, NULL, 0,
118 out, &x)) != CRYPT_OK) {
119 XFREE(tmpin);
120 return err;
121 }
122 XFREE(tmpin);
123 }
124
125 /* RSA encode it */
126 return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key);
127 }
128
129 #endif /* LTC_MRSA */
130
131 /* $Source$ */
132 /* $Revision$ */
133 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rsa_verify_hash.c
14 RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 LTC_PKCS #1 de-sign then v1.5 or PSS depad
21 @param sig The signature data
22 @param siglen The length of the signature data (octets)
23 @param hash The hash of the message that was signed
24 @param hashlen The length of the hash of the message that was signed (octets)
25 @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5)
26 @param hash_idx The index of the desired hash
27 @param saltlen The length of the salt used during signature
28 @param stat [out] The result of the signature comparison, 1==valid, 0==invalid
29 @param key The public RSA key corresponding to the key that performed the signature
30 @return CRYPT_OK on success (even if the signature is invalid)
31 */
32 int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
33 const unsigned char *hash, unsigned long hashlen,
34 int padding,
35 int hash_idx, unsigned long saltlen,
36 int *stat, rsa_key *key)
37 {
38 unsigned long modulus_bitlen, modulus_bytelen, x;
39 int err;
40 unsigned char *tmpbuf;
41
42 LTC_ARGCHK(hash != NULL);
43 LTC_ARGCHK(sig != NULL);
44 LTC_ARGCHK(stat != NULL);
45 LTC_ARGCHK(key != NULL);
46
47 /* default to invalid */
48 *stat = 0;
49
50 /* valid padding? */
51
52 if ((padding != LTC_PKCS_1_V1_5) &&
53 (padding != LTC_PKCS_1_PSS)) {
54 return CRYPT_PK_INVALID_PADDING;
55 }
56
57 if (padding == LTC_PKCS_1_PSS) {
58 /* valid hash ? */
59 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
60 return err;
61 }
62 }
63
64 /* get modulus len in bits */
65 modulus_bitlen = mp_count_bits( (key->N));
66
67 /* outlen must be at least the size of the modulus */
68 modulus_bytelen = mp_unsigned_bin_size( (key->N));
69 if (modulus_bytelen != siglen) {
70 return CRYPT_INVALID_PACKET;
71 }
72
73 /* allocate temp buffer for decoded sig */
74 tmpbuf = XMALLOC(siglen);
75 if (tmpbuf == NULL) {
76 return CRYPT_MEM;
77 }
78
79 /* RSA decode it */
80 x = siglen;
81 if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
82 XFREE(tmpbuf);
83 return err;
84 }
85
86 /* make sure the output is the right size */
87 if (x != siglen) {
88 XFREE(tmpbuf);
89 return CRYPT_INVALID_PACKET;
90 }
91
92 if (padding == LTC_PKCS_1_PSS) {
93 /* PSS decode and verify it */
94 err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
95 } else {
96 /* LTC_PKCS #1 v1.5 decode it */
97 unsigned char *out;
98 unsigned long outlen, loid[16];
99 int decoded;
100 ltc_asn1_list digestinfo[2], siginfo[2];
101
102 /* not all hashes have OIDs... so sad */
103 if (hash_descriptor[hash_idx].OIDlen == 0) {
104 err = CRYPT_INVALID_ARG;
105 goto bail_2;
106 }
107
108 /* allocate temp buffer for decoded hash */
109 outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3;
110 out = XMALLOC(outlen);
111 if (out == NULL) {
112 err = CRYPT_MEM;
113 goto bail_2;
114 }
115
116 if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) {
117 XFREE(out);
118 goto bail_2;
119 }
120
121 /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */
122 /* construct the SEQUENCE
123 SEQUENCE {
124 SEQUENCE {hashoid OID
125 blah NULL
126 }
127 hash OCTET STRING
128 }
129 */
130 LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0]));
131 LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
132 LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
133 LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
134
135 if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
136 XFREE(out);
137 goto bail_2;
138 }
139
140 /* test OID */
141 if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) &&
142 (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) &&
143 (siginfo[1].size == hashlen) &&
144 (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) {
145 *stat = 1;
146 }
147
148 #ifdef LTC_CLEAN_STACK
149 zeromem(out, outlen);
150 #endif
151 XFREE(out);
152 }
153
154 bail_2:
155 #ifdef LTC_CLEAN_STACK
156 zeromem(tmpbuf, siglen);
157 #endif
158 XFREE(tmpbuf);
159 return err;
160 }
161
162 #endif /* LTC_MRSA */
163
164 /* $Source$ */
165 /* $Revision$ */
166 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file fortuna.c
14 Fortuna PRNG, Tom St Denis
15 */
16
17 /* Implementation of Fortuna by Tom St Denis
18
19 We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources"
20 in the AddEntropy function are fixed to 0. Second since no reliable timer is provided
21 we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */
22
23 #ifdef LTC_FORTUNA
24
25 /* requries LTC_SHA256 and AES */
26 #if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256))
27 #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES)
28 #endif
29
30 #ifndef LTC_FORTUNA_POOLS
31 #warning LTC_FORTUNA_POOLS was not previously defined (old headers?)
32 #define LTC_FORTUNA_POOLS 32
33 #endif
34
35 #if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32
36 #error LTC_FORTUNA_POOLS must be in [4..32]
37 #endif
38
39 const struct ltc_prng_descriptor fortuna_desc = {
40 "fortuna", 1024,
41 &fortuna_start,
42 &fortuna_add_entropy,
43 &fortuna_ready,
44 &fortuna_read,
45 &fortuna_done,
46 &fortuna_export,
47 &fortuna_import,
48 &fortuna_test
49 };
50
51 /* update the IV */
52 static void fortuna_update_iv(prng_state *prng)
53 {
54 int x;
55 unsigned char *IV;
56 /* update IV */
57 IV = prng->fortuna.IV;
58 for (x = 0; x < 16; x++) {
59 IV[x] = (IV[x] + 1) & 255;
60 if (IV[x] != 0) break;
61 }
62 }
63
64 /* reseed the PRNG */
65 static int fortuna_reseed(prng_state *prng)
66 {
67 unsigned char tmp[MAXBLOCKSIZE];
68 hash_state md;
69 int err, x;
70
71 ++prng->fortuna.reset_cnt;
72
73 /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */
74 sha256_init(&md);
75 if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) {
76 sha256_done(&md, tmp);
77 return err;
78 }
79
80 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
81 if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) {
82 /* terminate this hash */
83 if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) {
84 sha256_done(&md, tmp);
85 return err;
86 }
87 /* add it to the string */
88 if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) {
89 sha256_done(&md, tmp);
90 return err;
91 }
92 /* reset this pool */
93 if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) {
94 sha256_done(&md, tmp);
95 return err;
96 }
97 } else {
98 break;
99 }
100 }
101
102 /* finish key */
103 if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) {
104 return err;
105 }
106 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) {
107 return err;
108 }
109 fortuna_update_iv(prng);
110
111 /* reset pool len */
112 prng->fortuna.pool0_len = 0;
113 prng->fortuna.wd = 0;
114
115
116 #ifdef LTC_CLEAN_STACK
117 zeromem(&md, sizeof(md));
118 zeromem(tmp, sizeof(tmp));
119 #endif
120
121 return CRYPT_OK;
122 }
123
124 /**
125 Start the PRNG
126 @param prng [out] The PRNG state to initialize
127 @return CRYPT_OK if successful
128 */
129 int fortuna_start(prng_state *prng)
130 {
131 int err, x, y;
132 unsigned char tmp[MAXBLOCKSIZE];
133
134 LTC_ARGCHK(prng != NULL);
135
136 /* initialize the pools */
137 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
138 if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) {
139 for (y = 0; y < x; y++) {
140 sha256_done(&prng->fortuna.pool[y], tmp);
141 }
142 return err;
143 }
144 }
145 prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.wd = 0;
146 prng->fortuna.reset_cnt = 0;
147
148 /* reset bufs */
149 zeromem(prng->fortuna.K, 32);
150 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) {
151 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
152 sha256_done(&prng->fortuna.pool[x], tmp);
153 }
154 return err;
155 }
156 zeromem(prng->fortuna.IV, 16);
157
158 LTC_MUTEX_INIT(&prng->fortuna.prng_lock)
159
160 return CRYPT_OK;
161 }
162
163 /**
164 Add entropy to the PRNG state
165 @param in The data to add
166 @param inlen Length of the data to add
167 @param prng PRNG state to update
168 @return CRYPT_OK if successful
169 */
170 int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
171 {
172 unsigned char tmp[2];
173 int err;
174
175 LTC_ARGCHK(in != NULL);
176 LTC_ARGCHK(prng != NULL);
177
178 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
179
180 /* ensure inlen <= 32 */
181 if (inlen > 32) {
182 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
183 return CRYPT_INVALID_ARG;
184 }
185
186 /* add s || length(in) || in to pool[pool_idx] */
187 tmp[0] = 0;
188 tmp[1] = (unsigned char)inlen;
189 if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) {
190 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
191 return err;
192 }
193 if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], in, inlen)) != CRYPT_OK) {
194 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
195 return err;
196 }
197 if (prng->fortuna.pool_idx == 0) {
198 prng->fortuna.pool0_len += inlen;
199 }
200 if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) {
201 prng->fortuna.pool_idx = 0;
202 }
203
204 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
205 return CRYPT_OK;
206 }
207
208 /**
209 Make the PRNG ready to read from
210 @param prng The PRNG to make active
211 @return CRYPT_OK if successful
212 */
213 int fortuna_ready(prng_state *prng)
214 {
215 return fortuna_reseed(prng);
216 }
217
218 /**
219 Read from the PRNG
220 @param out Destination
221 @param outlen Length of output
222 @param prng The active PRNG to read from
223 @return Number of octets read
224 */
225 unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng)
226 {
227 unsigned char tmp[16];
228 unsigned long tlen;
229
230 LTC_ARGCHK(out != NULL);
231 LTC_ARGCHK(prng != NULL);
232
233 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
234
235 /* do we have to reseed? */
236 if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) {
237 if (fortuna_reseed(prng) != CRYPT_OK) {
238 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
239 return 0;
240 }
241 }
242
243 /* now generate the blocks required */
244 tlen = outlen;
245
246 /* handle whole blocks without the extra XMEMCPY */
247 while (outlen >= 16) {
248 /* encrypt the IV and store it */
249 rijndael_ecb_encrypt(prng->fortuna.IV, out, &prng->fortuna.skey);
250 out += 16;
251 outlen -= 16;
252 fortuna_update_iv(prng);
253 }
254
255 /* left over bytes? */
256 if (outlen > 0) {
257 rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey);
258 XMEMCPY(out, tmp, outlen);
259 fortuna_update_iv(prng);
260 }
261
262 /* generate new key */
263 rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey);
264 fortuna_update_iv(prng);
265
266 rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey);
267 fortuna_update_iv(prng);
268
269 if (rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey) != CRYPT_OK) {
270 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
271 return 0;
272 }
273
274 #ifdef LTC_CLEAN_STACK
275 zeromem(tmp, sizeof(tmp));
276 #endif
277 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
278 return tlen;
279 }
280
281 /**
282 Terminate the PRNG
283 @param prng The PRNG to terminate
284 @return CRYPT_OK if successful
285 */
286 int fortuna_done(prng_state *prng)
287 {
288 int err, x;
289 unsigned char tmp[32];
290
291 LTC_ARGCHK(prng != NULL);
292 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
293
294 /* terminate all the hashes */
295 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
296 if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) {
297 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
298 return err;
299 }
300 }
301 /* call cipher done when we invent one ;-) */
302
303 #ifdef LTC_CLEAN_STACK
304 zeromem(tmp, sizeof(tmp));
305 #endif
306
307 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
308 return CRYPT_OK;
309 }
310
311 /**
312 Export the PRNG state
313 @param out [out] Destination
314 @param outlen [in/out] Max size and resulting size of the state
315 @param prng The PRNG to export
316 @return CRYPT_OK if successful
317 */
318 int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
319 {
320 int x, err;
321 hash_state *md;
322
323 LTC_ARGCHK(out != NULL);
324 LTC_ARGCHK(outlen != NULL);
325 LTC_ARGCHK(prng != NULL);
326
327 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
328
329 /* we'll write bytes for s&g's */
330 if (*outlen < 32*LTC_FORTUNA_POOLS) {
331 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
332 *outlen = 32*LTC_FORTUNA_POOLS;
333 return CRYPT_BUFFER_OVERFLOW;
334 }
335
336 md = XMALLOC(sizeof(hash_state));
337 if (md == NULL) {
338 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
339 return CRYPT_MEM;
340 }
341
342 /* to emit the state we copy each pool, terminate it then hash it again so
343 * an attacker who sees the state can't determine the current state of the PRNG
344 */
345 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
346 /* copy the PRNG */
347 XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md));
348
349 /* terminate it */
350 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) {
351 goto LBL_ERR;
352 }
353
354 /* now hash it */
355 if ((err = sha256_init(md)) != CRYPT_OK) {
356 goto LBL_ERR;
357 }
358 if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) {
359 goto LBL_ERR;
360 }
361 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) {
362 goto LBL_ERR;
363 }
364 }
365 *outlen = 32*LTC_FORTUNA_POOLS;
366 err = CRYPT_OK;
367
368 LBL_ERR:
369 #ifdef LTC_CLEAN_STACK
370 zeromem(md, sizeof(*md));
371 #endif
372 XFREE(md);
373 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
374 return err;
375 }
376
377 /**
378 Import a PRNG state
379 @param in The PRNG state
380 @param inlen Size of the state
381 @param prng The PRNG to import
382 @return CRYPT_OK if successful
383 */
384 int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
385 {
386 int err, x;
387
388 LTC_ARGCHK(in != NULL);
389 LTC_ARGCHK(prng != NULL);
390
391 if (inlen != 32*LTC_FORTUNA_POOLS) {
392 return CRYPT_INVALID_ARG;
393 }
394
395 if ((err = fortuna_start(prng)) != CRYPT_OK) {
396 return err;
397 }
398 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
399 if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) {
400 return err;
401 }
402 }
403 return err;
404 }
405
406 /**
407 PRNG self-test
408 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
409 */
410 int fortuna_test(void)
411 {
412 #ifndef LTC_TEST
413 return CRYPT_NOP;
414 #else
415 int err;
416
417 if ((err = sha256_test()) != CRYPT_OK) {
418 return err;
419 }
420 return rijndael_test();
421 #endif
422 }
423
424 #endif
425
426
427 /* $Source$ */
428 /* $Revision$ */
429 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rc4.c
14 LTC_RC4 PRNG, Tom St Denis
15 */
16
17 #ifdef LTC_RC4
18
19 const struct ltc_prng_descriptor rc4_desc =
20 {
21 "rc4", 32,
22 &rc4_start,
23 &rc4_add_entropy,
24 &rc4_ready,
25 &rc4_read,
26 &rc4_done,
27 &rc4_export,
28 &rc4_import,
29 &rc4_test
30 };
31
32 /**
33 Start the PRNG
34 @param prng [out] The PRNG state to initialize
35 @return CRYPT_OK if successful
36 */
37 int rc4_start(prng_state *prng)
38 {
39 LTC_ARGCHK(prng != NULL);
40
41 /* set keysize to zero */
42 prng->rc4.x = 0;
43
44 return CRYPT_OK;
45 }
46
47 /**
48 Add entropy to the PRNG state
49 @param in The data to add
50 @param inlen Length of the data to add
51 @param prng PRNG state to update
52 @return CRYPT_OK if successful
53 */
54 int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
55 {
56 LTC_ARGCHK(in != NULL);
57 LTC_ARGCHK(prng != NULL);
58
59 /* trim as required */
60 if (prng->rc4.x + inlen > 256) {
61 if (prng->rc4.x == 256) {
62 /* I can't possibly accept another byte, ok maybe a mint wafer... */
63 return CRYPT_OK;
64 } else {
65 /* only accept part of it */
66 inlen = 256 - prng->rc4.x;
67 }
68 }
69
70 while (inlen--) {
71 prng->rc4.buf[prng->rc4.x++] = *in++;
72 }
73
74 return CRYPT_OK;
75
76 }
77
78 /**
79 Make the PRNG ready to read from
80 @param prng The PRNG to make active
81 @return CRYPT_OK if successful
82 */
83 int rc4_ready(prng_state *prng)
84 {
85 unsigned char key[256], tmp, *s;
86 int keylen, x, y, j;
87
88 LTC_ARGCHK(prng != NULL);
89
90 /* extract the key */
91 s = prng->rc4.buf;
92 XMEMCPY(key, s, 256);
93 keylen = prng->rc4.x;
94
95 /* make LTC_RC4 perm and shuffle */
96 for (x = 0; x < 256; x++) {
97 s[x] = x;
98 }
99
100 for (j = x = y = 0; x < 256; x++) {
101 y = (y + prng->rc4.buf[x] + key[j++]) & 255;
102 if (j == keylen) {
103 j = 0;
104 }
105 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
106 }
107 prng->rc4.x = 0;
108 prng->rc4.y = 0;
109
110 #ifdef LTC_CLEAN_STACK
111 zeromem(key, sizeof(key));
112 #endif
113
114 return CRYPT_OK;
115 }
116
117 /**
118 Read from the PRNG
119 @param out Destination
120 @param outlen Length of output
121 @param prng The active PRNG to read from
122 @return Number of octets read
123 */
124 unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng)
125 {
126 unsigned char x, y, *s, tmp;
127 unsigned long n;
128
129 LTC_ARGCHK(out != NULL);
130 LTC_ARGCHK(prng != NULL);
131
132 #ifdef LTC_VALGRIND
133 zeromem(out, outlen);
134 #endif
135
136 n = outlen;
137 x = prng->rc4.x;
138 y = prng->rc4.y;
139 s = prng->rc4.buf;
140 while (outlen--) {
141 x = (x + 1) & 255;
142 y = (y + s[x]) & 255;
143 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
144 tmp = (s[x] + s[y]) & 255;
145 *out++ ^= s[tmp];
146 }
147 prng->rc4.x = x;
148 prng->rc4.y = y;
149 return n;
150 }
151
152 /**
153 Terminate the PRNG
154 @param prng The PRNG to terminate
155 @return CRYPT_OK if successful
156 */
157 int rc4_done(prng_state *prng)
158 {
159 LTC_ARGCHK(prng != NULL);
160 return CRYPT_OK;
161 }
162
163 /**
164 Export the PRNG state
165 @param out [out] Destination
166 @param outlen [in/out] Max size and resulting size of the state
167 @param prng The PRNG to export
168 @return CRYPT_OK if successful
169 */
170 int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
171 {
172 LTC_ARGCHK(outlen != NULL);
173 LTC_ARGCHK(out != NULL);
174 LTC_ARGCHK(prng != NULL);
175
176 if (*outlen < 32) {
177 *outlen = 32;
178 return CRYPT_BUFFER_OVERFLOW;
179 }
180
181 if (rc4_read(out, 32, prng) != 32) {
182 return CRYPT_ERROR_READPRNG;
183 }
184 *outlen = 32;
185
186 return CRYPT_OK;
187 }
188
189 /**
190 Import a PRNG state
191 @param in The PRNG state
192 @param inlen Size of the state
193 @param prng The PRNG to import
194 @return CRYPT_OK if successful
195 */
196 int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
197 {
198 int err;
199 LTC_ARGCHK(in != NULL);
200 LTC_ARGCHK(prng != NULL);
201
202 if (inlen != 32) {
203 return CRYPT_INVALID_ARG;
204 }
205
206 if ((err = rc4_start(prng)) != CRYPT_OK) {
207 return err;
208 }
209 return rc4_add_entropy(in, 32, prng);
210 }
211
212 /**
213 PRNG self-test
214 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
215 */
216 int rc4_test(void)
217 {
218 #if !defined(LTC_TEST) || defined(LTC_VALGRIND)
219 return CRYPT_NOP;
220 #else
221 static const struct {
222 unsigned char key[8], pt[8], ct[8];
223 } tests[] = {
224 {
225 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
226 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
227 { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 }
228 }
229 };
230 prng_state prng;
231 unsigned char dst[8];
232 int err, x;
233
234 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
235 if ((err = rc4_start(&prng)) != CRYPT_OK) {
236 return err;
237 }
238 if ((err = rc4_add_entropy(tests[x].key, 8, &prng)) != CRYPT_OK) {
239 return err;
240 }
241 if ((err = rc4_ready(&prng)) != CRYPT_OK) {
242 return err;
243 }
244 XMEMCPY(dst, tests[x].pt, 8);
245 if (rc4_read(dst, 8, &prng) != 8) {
246 return CRYPT_ERROR_READPRNG;
247 }
248 rc4_done(&prng);
249 if (XMEMCMP(dst, tests[x].ct, 8)) {
250 #if 0
251 int y;
252 printf("\n\nLTC_RC4 failed, I got:\n");
253 for (y = 0; y < 8; y++) printf("%02x ", dst[y]);
254 printf("\n");
255 #endif
256 return CRYPT_FAIL_TESTVECTOR;
257 }
258 }
259 return CRYPT_OK;
260 #endif
261 }
262
263 #endif
264
265
266 /* $Source$ */
267 /* $Revision$ */
268 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rng_get_bytes.c
14 portable way to get secure random bits to feed a PRNG (Tom St Denis)
15 */
16
17 #ifdef LTC_DEVRANDOM
18 /* on *NIX read /dev/random */
19 static unsigned long rng_nix(unsigned char *buf, unsigned long len,
20 void (*callback)(void))
21 {
22 #ifdef LTC_NO_FILE
23 return 0;
24 #else
25 FILE *f;
26 unsigned long x;
27 #ifdef TRY_URANDOM_FIRST
28 f = fopen("/dev/urandom", "rb");
29 if (f == NULL)
30 #endif /* TRY_URANDOM_FIRST */
31 f = fopen("/dev/random", "rb");
32
33 if (f == NULL) {
34 return 0;
35 }
36
37 /* disable buffering */
38 if (setvbuf(f, NULL, _IONBF, 0) != 0) {
39 fclose(f);
40 return 0;
41 }
42
43 x = (unsigned long)fread(buf, 1, (size_t)len, f);
44 fclose(f);
45 return x;
46 #endif /* LTC_NO_FILE */
47 }
48
49 #endif /* LTC_DEVRANDOM */
50
51 /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
52 #if defined(CLOCKS_PER_SEC) && !defined(WINCE)
53
54 #define ANSI_RNG
55
56 static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
57 void (*callback)(void))
58 {
59 clock_t t1;
60 int l, acc, bits, a, b;
61
62 if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
63 return 0;
64 }
65
66 l = len;
67 bits = 8;
68 acc = a = b = 0;
69 while (len--) {
70 if (callback != NULL) callback();
71 while (bits--) {
72 do {
73 t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
74 t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
75 } while (a == b);
76 acc = (acc << 1) | a;
77 }
78 *buf++ = acc;
79 acc = 0;
80 bits = 8;
81 }
82 acc = bits = a = b = 0;
83 return l;
84 }
85
86 #endif
87
88 /* Try the Microsoft CSP */
89 #if defined(WIN32) || defined(WINCE)
90 #ifndef _WIN32_WINNT
91 #define _WIN32_WINNT 0x0400
92 #endif
93 #ifdef WINCE
94 #define UNDER_CE
95 #define ARM
96 #endif
97
98 #define WIN32_LEAN_AND_MEAN
99 #include <windows.h>
100 #include <wincrypt.h>
101
102 static unsigned long rng_win32(unsigned char *buf, unsigned long len,
103 void (*callback)(void))
104 {
105 HCRYPTPROV hProv = 0;
106 if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
107 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
108 !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
109 CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
110 return 0;
111
112 if (CryptGenRandom(hProv, len, buf) == TRUE) {
113 CryptReleaseContext(hProv, 0);
114 return len;
115 } else {
116 CryptReleaseContext(hProv, 0);
117 return 0;
118 }
119 }
120
121 #endif /* WIN32 */
122
123 /**
124 Read the system RNG
125 @param out Destination
126 @param outlen Length desired (octets)
127 @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL
128 @return Number of octets read
129 */
130 unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen,
131 void (*callback)(void))
132 {
133 unsigned long x;
134
135 LTC_ARGCHK(out != NULL);
136
137 #if defined(LTC_DEVRANDOM)
138 x = rng_nix(out, outlen, callback); if (x != 0) { return x; }
139 #endif
140 #ifdef WIN32
141 x = rng_win32(out, outlen, callback); if (x != 0) { return x; }
142 #endif
143 #ifdef ANSI_RNG
144 x = rng_ansic(out, outlen, callback); if (x != 0) { return x; }
145 #endif
146 return 0;
147 }
148
149 /* $Source$ */
150 /* $Revision$ */
151 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file rng_make_prng.c
14 portable way to get secure random bits to feed a PRNG (Tom St Denis)
15 */
16
17 /**
18 Create a PRNG from a RNG
19 @param bits Number of bits of entropy desired (64 ... 1024)
20 @param wprng Index of which PRNG to setup
21 @param prng [out] PRNG state to initialize
22 @param callback A pointer to a void function for when the RNG is slow, this can be NULL
23 @return CRYPT_OK if successful
24 */
25 int rng_make_prng(int bits, int wprng, prng_state *prng,
26 void (*callback)(void))
27 {
28 unsigned char buf[256];
29 int err;
30
31 LTC_ARGCHK(prng != NULL);
32
33 /* check parameter */
34 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
35 return err;
36 }
37
38 if (bits < 64 || bits > 1024) {
39 return CRYPT_INVALID_PRNGSIZE;
40 }
41
42 if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) {
43 return err;
44 }
45
46 bits = ((bits/8)+((bits&7)!=0?1:0)) * 2;
47 if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) {
48 return CRYPT_ERROR_READPRNG;
49 }
50
51 if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) {
52 return err;
53 }
54
55 if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) {
56 return err;
57 }
58
59 #ifdef LTC_CLEAN_STACK
60 zeromem(buf, sizeof(buf));
61 #endif
62 return CRYPT_OK;
63 }
64
65
66 /* $Source$ */
67 /* $Revision$ */
68 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file sober128.c
14 Implementation of SOBER-128 by Tom St Denis.
15 Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
16 */
17
18 #ifdef LTC_SOBER128
19
20 #include "sober128tab.c.inc"
21
22 const struct ltc_prng_descriptor sober128_desc =
23 {
24 "sober128", 64,
25 &sober128_start,
26 &sober128_add_entropy,
27 &sober128_ready,
28 &sober128_read,
29 &sober128_done,
30 &sober128_export,
31 &sober128_import,
32 &sober128_test
33 };
34
35 /* don't change these... */
36 #define N 17
37 #define FOLD N /* how many iterations of folding to do */
38 #define INITKONST 0x6996c53a /* value of KONST to use during key loading */
39 #define KEYP 15 /* where to insert key words */
40 #define FOLDP 4 /* where to insert non-linear feedback */
41
42 #define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF))
43
44 static ulong32 BYTE2WORD(unsigned char *b)
45 {
46 ulong32 t;
47 LOAD32L(t, b);
48 return t;
49 }
50
51 #define WORD2BYTE(w, b) STORE32L(b, w)
52
53 static void XORWORD(ulong32 w, unsigned char *b)
54 {
55 ulong32 t;
56 LOAD32L(t, b);
57 t ^= w;
58 STORE32L(t, b);
59 }
60
61 /* give correct offset for the current position of the register,
62 * where logically R[0] is at position "zero".
63 */
64 #define OFF(zero, i) (((zero)+(i)) % N)
65
66 /* step the LFSR */
67 /* After stepping, "zero" moves right one place */
68 #define STEP(R,z) \
69 R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
70
71 static void cycle(ulong32 *R)
72 {
73 ulong32 t;
74 int i;
75
76 STEP(R,0);
77 t = R[0];
78 for (i = 1; i < N; ++i) {
79 R[i-1] = R[i];
80 }
81 R[N-1] = t;
82 }
83
84 /* Return a non-linear function of some parts of the register.
85 */
86 #define NLFUNC(c,z) \
87 { \
88 t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \
89 t ^= Sbox[(t >> 24) & 0xFF]; \
90 t = RORc(t, 8); \
91 t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \
92 t ^= Sbox[(t >> 24) & 0xFF]; \
93 t = t + c->R[OFF(z,13)]; \
94 }
95
96 static ulong32 nltap(struct sober128_prng *c)
97 {
98 ulong32 t;
99 NLFUNC(c, 0);
100 return t;
101 }
102
103 /**
104 Start the PRNG
105 @param prng [out] The PRNG state to initialize
106 @return CRYPT_OK if successful
107 */
108 int sober128_start(prng_state *prng)
109 {
110 int i;
111 struct sober128_prng *c;
112
113 LTC_ARGCHK(prng != NULL);
114
115 c = &(prng->sober128);
116
117 /* Register initialised to Fibonacci numbers */
118 c->R[0] = 1;
119 c->R[1] = 1;
120 for (i = 2; i < N; ++i) {
121 c->R[i] = c->R[i-1] + c->R[i-2];
122 }
123 c->konst = INITKONST;
124
125 /* next add_entropy will be the key */
126 c->flag = 1;
127 c->set = 0;
128
129 return CRYPT_OK;
130 }
131
132 /* Save the current register state
133 */
134 static void s128_savestate(struct sober128_prng *c)
135 {
136 int i;
137 for (i = 0; i < N; ++i) {
138 c->initR[i] = c->R[i];
139 }
140 }
141
142 /* initialise to previously saved register state
143 */
144 static void s128_reloadstate(struct sober128_prng *c)
145 {
146 int i;
147
148 for (i = 0; i < N; ++i) {
149 c->R[i] = c->initR[i];
150 }
151 }
152
153 /* Initialise "konst"
154 */
155 static void s128_genkonst(struct sober128_prng *c)
156 {
157 ulong32 newkonst;
158
159 do {
160 cycle(c->R);
161 newkonst = nltap(c);
162 } while ((newkonst & 0xFF000000) == 0);
163 c->konst = newkonst;
164 }
165
166 /* Load key material into the register
167 */
168 #define ADDKEY(k) \
169 c->R[KEYP] += (k);
170
171 #define XORNL(nl) \
172 c->R[FOLDP] ^= (nl);
173
174 /* nonlinear diffusion of register for key */
175 #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t;
176 static void s128_diffuse(struct sober128_prng *c)
177 {
178 ulong32 t;
179 /* relies on FOLD == N == 17! */
180 DROUND(0);
181 DROUND(1);
182 DROUND(2);
183 DROUND(3);
184 DROUND(4);
185 DROUND(5);
186 DROUND(6);
187 DROUND(7);
188 DROUND(8);
189 DROUND(9);
190 DROUND(10);
191 DROUND(11);
192 DROUND(12);
193 DROUND(13);
194 DROUND(14);
195 DROUND(15);
196 DROUND(16);
197 }
198
199 /**
200 Add entropy to the PRNG state
201 @param in The data to add
202 @param inlen Length of the data to add
203 @param prng PRNG state to update
204 @return CRYPT_OK if successful
205 */
206 int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
207 {
208 struct sober128_prng *c;
209 ulong32 i, k;
210
211 LTC_ARGCHK(in != NULL);
212 LTC_ARGCHK(prng != NULL);
213 c = &(prng->sober128);
214
215 if (c->flag == 1) {
216 /* this is the first call to the add_entropy so this input is the key */
217 /* inlen must be multiple of 4 bytes */
218 if ((inlen & 3) != 0) {
219 return CRYPT_INVALID_KEYSIZE;
220 }
221
222 for (i = 0; i < inlen; i += 4) {
223 k = BYTE2WORD((unsigned char *)&in[i]);
224 ADDKEY(k);
225 cycle(c->R);
226 XORNL(nltap(c));
227 }
228
229 /* also fold in the length of the key */
230 ADDKEY(inlen);
231
232 /* now diffuse */
233 s128_diffuse(c);
234
235 s128_genkonst(c);
236 s128_savestate(c);
237 c->nbuf = 0;
238 c->flag = 0;
239 c->set = 1;
240 } else {
241 /* ok we are adding an IV then... */
242 s128_reloadstate(c);
243
244 /* inlen must be multiple of 4 bytes */
245 if ((inlen & 3) != 0) {
246 return CRYPT_INVALID_KEYSIZE;
247 }
248
249 for (i = 0; i < inlen; i += 4) {
250 k = BYTE2WORD((unsigned char *)&in[i]);
251 ADDKEY(k);
252 cycle(c->R);
253 XORNL(nltap(c));
254 }
255
256 /* also fold in the length of the key */
257 ADDKEY(inlen);
258
259 /* now diffuse */
260 s128_diffuse(c);
261 c->nbuf = 0;
262 }
263
264 return CRYPT_OK;
265 }
266
267 /**
268 Make the PRNG ready to read from
269 @param prng The PRNG to make active
270 @return CRYPT_OK if successful
271 */
272 int sober128_ready(prng_state *prng)
273 {
274 return prng->sober128.set == 1 ? CRYPT_OK : CRYPT_ERROR;
275 }
276
277 /* XOR pseudo-random bytes into buffer
278 */
279 #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, out+(z*4));
280
281 /**
282 Read from the PRNG
283 @param out Destination
284 @param outlen Length of output
285 @param prng The active PRNG to read from
286 @return Number of octets read
287 */
288 unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng)
289 {
290 struct sober128_prng *c;
291 ulong32 t, tlen;
292
293 LTC_ARGCHK(out != NULL);
294 LTC_ARGCHK(prng != NULL);
295
296 #ifdef LTC_VALGRIND
297 zeromem(out, outlen);
298 #endif
299
300 c = &(prng->sober128);
301 t = 0;
302 tlen = outlen;
303
304 /* handle any previously buffered bytes */
305 while (c->nbuf != 0 && outlen != 0) {
306 *out++ ^= c->sbuf & 0xFF;
307 c->sbuf >>= 8;
308 c->nbuf -= 8;
309 --outlen;
310 }
311
312 #ifndef LTC_SMALL_CODE
313 /* do lots at a time, if there's enough to do */
314 while (outlen >= N*4) {
315 SROUND(0);
316 SROUND(1);
317 SROUND(2);
318 SROUND(3);
319 SROUND(4);
320 SROUND(5);
321 SROUND(6);
322 SROUND(7);
323 SROUND(8);
324 SROUND(9);
325 SROUND(10);
326 SROUND(11);
327 SROUND(12);
328 SROUND(13);
329 SROUND(14);
330 SROUND(15);
331 SROUND(16);
332 out += 4*N;
333 outlen -= 4*N;
334 }
335 #endif
336
337 /* do small or odd size buffers the slow way */
338 while (4 <= outlen) {
339 cycle(c->R);
340 t = nltap(c);
341 XORWORD(t, out);
342 out += 4;
343 outlen -= 4;
344 }
345
346 /* handle any trailing bytes */
347 if (outlen != 0) {
348 cycle(c->R);
349 c->sbuf = nltap(c);
350 c->nbuf = 32;
351 while (c->nbuf != 0 && outlen != 0) {
352 *out++ ^= c->sbuf & 0xFF;
353 c->sbuf >>= 8;
354 c->nbuf -= 8;
355 --outlen;
356 }
357 }
358
359 return tlen;
360 }
361
362 /**
363 Terminate the PRNG
364 @param prng The PRNG to terminate
365 @return CRYPT_OK if successful
366 */
367 int sober128_done(prng_state *prng)
368 {
369 LTC_ARGCHK(prng != NULL);
370 return CRYPT_OK;
371 }
372
373 /**
374 Export the PRNG state
375 @param out [out] Destination
376 @param outlen [in/out] Max size and resulting size of the state
377 @param prng The PRNG to export
378 @return CRYPT_OK if successful
379 */
380 int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
381 {
382 LTC_ARGCHK(outlen != NULL);
383 LTC_ARGCHK(out != NULL);
384 LTC_ARGCHK(prng != NULL);
385
386 if (*outlen < 64) {
387 *outlen = 64;
388 return CRYPT_BUFFER_OVERFLOW;
389 }
390
391 if (sober128_read(out, 64, prng) != 64) {
392 return CRYPT_ERROR_READPRNG;
393 }
394 *outlen = 64;
395
396 return CRYPT_OK;
397 }
398
399 /**
400 Import a PRNG state
401 @param in The PRNG state
402 @param inlen Size of the state
403 @param prng The PRNG to import
404 @return CRYPT_OK if successful
405 */
406 int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
407 {
408 int err;
409 LTC_ARGCHK(in != NULL);
410 LTC_ARGCHK(prng != NULL);
411
412 if (inlen != 64) {
413 return CRYPT_INVALID_ARG;
414 }
415
416 if ((err = sober128_start(prng)) != CRYPT_OK) {
417 return err;
418 }
419 if ((err = sober128_add_entropy(in, 64, prng)) != CRYPT_OK) {
420 return err;
421 }
422 return sober128_ready(prng);
423 }
424
425 /**
426 PRNG self-test
427 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
428 */
429 int sober128_test(void)
430 {
431 #ifndef LTC_TEST
432 return CRYPT_NOP;
433 #else
434 static const struct {
435 int keylen, ivlen, len;
436 unsigned char key[16], iv[4], out[20];
437 } tests[] = {
438
439 {
440 16, 4, 20,
441
442 /* key */
443 { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79,
444 0x20, 0x31, 0x32, 0x38, 0x62, 0x69, 0x74, 0x73 },
445
446 /* IV */
447 { 0x00, 0x00, 0x00, 0x00 },
448
449 /* expected output */
450 { 0x43, 0x50, 0x0c, 0xcf, 0x89, 0x91, 0x9f, 0x1d,
451 0xaa, 0x37, 0x74, 0x95, 0xf4, 0xb4, 0x58, 0xc2,
452 0x40, 0x37, 0x8b, 0xbb }
453 }
454
455 };
456 prng_state prng;
457 unsigned char dst[20];
458 int err, x;
459
460 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
461 if ((err = sober128_start(&prng)) != CRYPT_OK) {
462 return err;
463 }
464 if ((err = sober128_add_entropy(tests[x].key, tests[x].keylen, &prng)) != CRYPT_OK) {
465 return err;
466 }
467 /* add IV */
468 if ((err = sober128_add_entropy(tests[x].iv, tests[x].ivlen, &prng)) != CRYPT_OK) {
469 return err;
470 }
471
472 /* ready up */
473 if ((err = sober128_ready(&prng)) != CRYPT_OK) {
474 return err;
475 }
476 XMEMSET(dst, 0, tests[x].len);
477 if (sober128_read(dst, tests[x].len, &prng) != (unsigned long)tests[x].len) {
478 return CRYPT_ERROR_READPRNG;
479 }
480 sober128_done(&prng);
481 if (XMEMCMP(dst, tests[x].out, tests[x].len)) {
482 #if 0
483 printf("\n\nLTC_SOBER128 failed, I got:\n");
484 for (y = 0; y < tests[x].len; y++) printf("%02x ", dst[y]);
485 printf("\n");
486 #endif
487 return CRYPT_FAIL_TESTVECTOR;
488 }
489 }
490 return CRYPT_OK;
491 #endif
492 }
493
494 #endif
495
496
497 /* $Source$ */
498 /* $Revision$ */
499 /* $Date$ */
0 /**
1 @file sober128tab.c
2 SOBER-128 Tables
3 */
4 /* $ID$ */
5 /* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */
6 /* Multiplication table for Turing using 0xD02B4367 */
7 static const ulong32 Multab[256] = {
8 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9,
9 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478,
10 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746,
11 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697,
12 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A,
13 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB,
14 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5,
15 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04,
16 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2,
17 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613,
18 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D,
19 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC,
20 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51,
21 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80,
22 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE,
23 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F,
24 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F,
25 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE,
26 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90,
27 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41,
28 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC,
29 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D,
30 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703,
31 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2,
32 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14,
33 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5,
34 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB,
35 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A,
36 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787,
37 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656,
38 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568,
39 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9,
40 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748,
41 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699,
42 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7,
43 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476,
44 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB,
45 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A,
46 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34,
47 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5,
48 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523,
49 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2,
50 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC,
51 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D,
52 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0,
53 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61,
54 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F,
55 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E,
56 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E,
57 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F,
58 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71,
59 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0,
60 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D,
61 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC,
62 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2,
63 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433,
64 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5,
65 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24,
66 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A,
67 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB,
68 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566,
69 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7,
70 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789,
71 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658,
72 };
73
74 /* $ID$ */
75 /* Sbox for SOBER-128 */
76 /*
77 * This is really the combination of two SBoxes; the least significant
78 * 24 bits comes from:
79 * 8->32 Sbox generated by Millan et. al. at Queensland University of
80 * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter,
81 * "On the Design of 8*32 S-boxes". Unpublished report, by the
82 * Information Systems Research Centre,
83 * Queensland University of Technology, 1999.
84 *
85 * The most significant 8 bits are the Skipjack "F table", which can be
86 * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf .
87 * In this optimised table, though, the intent is to XOR the word from
88 * the table selected by the high byte with the input word. Thus, the
89 * high byte is actually the Skipjack F-table entry XORED with its
90 * table index.
91 */
92 static const ulong32 Sbox[256] = {
93 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4,
94 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae,
95 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c,
96 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35,
97 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e,
98 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b,
99 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f,
100 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1,
101 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd,
102 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3,
103 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f,
104 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36,
105 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf,
106 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816,
107 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d,
108 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af,
109 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6,
110 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418,
111 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0,
112 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd,
113 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088,
114 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759,
115 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895,
116 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66,
117 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc,
118 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1,
119 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911,
120 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e,
121 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515,
122 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133,
123 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226,
124 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084,
125 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb,
126 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184,
127 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420,
128 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02,
129 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655,
130 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c,
131 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418,
132 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473,
133 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a,
134 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0,
135 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21,
136 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36,
137 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5,
138 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6,
139 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0,
140 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795,
141 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0,
142 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78,
143 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da,
144 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a,
145 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118,
146 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed,
147 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd,
148 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b,
149 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921,
150 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e,
151 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5,
152 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8,
153 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376,
154 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a,
155 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8,
156 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40,
157 };
158
159 /* $Source$ */
160 /* $Revision$ */
161 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file sprng.c
14 Secure PRNG, Tom St Denis
15 */
16
17 /* A secure PRNG using the RNG functions. Basically this is a
18 * wrapper that allows you to use a secure RNG as a PRNG
19 * in the various other functions.
20 */
21
22 #ifdef LTC_SPRNG
23
24 const struct ltc_prng_descriptor sprng_desc =
25 {
26 "sprng", 0,
27 &sprng_start,
28 &sprng_add_entropy,
29 &sprng_ready,
30 &sprng_read,
31 &sprng_done,
32 &sprng_export,
33 &sprng_import,
34 &sprng_test
35 };
36
37 /**
38 Start the PRNG
39 @param prng [out] The PRNG state to initialize
40 @return CRYPT_OK if successful
41 */
42 int sprng_start(prng_state *prng)
43 {
44 return CRYPT_OK;
45 }
46
47 /**
48 Add entropy to the PRNG state
49 @param in The data to add
50 @param inlen Length of the data to add
51 @param prng PRNG state to update
52 @return CRYPT_OK if successful
53 */
54 int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
55 {
56 return CRYPT_OK;
57 }
58
59 /**
60 Make the PRNG ready to read from
61 @param prng The PRNG to make active
62 @return CRYPT_OK if successful
63 */
64 int sprng_ready(prng_state *prng)
65 {
66 return CRYPT_OK;
67 }
68
69 /**
70 Read from the PRNG
71 @param out Destination
72 @param outlen Length of output
73 @param prng The active PRNG to read from
74 @return Number of octets read
75 */
76 unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
77 {
78 LTC_ARGCHK(out != NULL);
79 return rng_get_bytes(out, outlen, NULL);
80 }
81
82 /**
83 Terminate the PRNG
84 @param prng The PRNG to terminate
85 @return CRYPT_OK if successful
86 */
87 int sprng_done(prng_state *prng)
88 {
89 return CRYPT_OK;
90 }
91
92 /**
93 Export the PRNG state
94 @param out [out] Destination
95 @param outlen [in/out] Max size and resulting size of the state
96 @param prng The PRNG to export
97 @return CRYPT_OK if successful
98 */
99 int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
100 {
101 LTC_ARGCHK(outlen != NULL);
102
103 *outlen = 0;
104 return CRYPT_OK;
105 }
106
107 /**
108 Import a PRNG state
109 @param in The PRNG state
110 @param inlen Size of the state
111 @param prng The PRNG to import
112 @return CRYPT_OK if successful
113 */
114 int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
115 {
116 return CRYPT_OK;
117 }
118
119 /**
120 PRNG self-test
121 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
122 */
123 int sprng_test(void)
124 {
125 return CRYPT_OK;
126 }
127
128 #endif
129
130
131
132
133 /* $Source$ */
134 /* $Revision$ */
135 /* $Date$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10 #include "tomcrypt.h"
11
12 /**
13 @file yarrow.c
14 Yarrow PRNG, Tom St Denis
15 */
16
17 #ifdef LTC_YARROW
18
19 const struct ltc_prng_descriptor yarrow_desc =
20 {
21 "yarrow", 64,
22 &yarrow_start,
23 &yarrow_add_entropy,
24 &yarrow_ready,
25 &yarrow_read,
26 &yarrow_done,
27 &yarrow_export,
28 &yarrow_import,
29 &yarrow_test
30 };
31
32 /**
33 Start the PRNG
34 @param prng [out] The PRNG state to initialize
35 @return CRYPT_OK if successful
36 */
37 int yarrow_start(prng_state *prng)
38 {
39 int err;
40
41 LTC_ARGCHK(prng != NULL);
42
43 /* these are the default hash/cipher combo used */
44 #ifdef LTC_RIJNDAEL
45 #if LTC_YARROW_AES==0
46 prng->yarrow.cipher = register_cipher(&rijndael_enc_desc);
47 #elif LTC_YARROW_AES==1
48 prng->yarrow.cipher = register_cipher(&aes_enc_desc);
49 #elif LTC_YARROW_AES==2
50 prng->yarrow.cipher = register_cipher(&rijndael_desc);
51 #elif LTC_YARROW_AES==3
52 prng->yarrow.cipher = register_cipher(&aes_desc);
53 #endif
54 #elif defined(LTC_BLOWFISH)
55 prng->yarrow.cipher = register_cipher(&blowfish_desc);
56 #elif defined(LTC_TWOFISH)
57 prng->yarrow.cipher = register_cipher(&twofish_desc);
58 #elif defined(LTC_RC6)
59 prng->yarrow.cipher = register_cipher(&rc6_desc);
60 #elif defined(LTC_RC5)
61 prng->yarrow.cipher = register_cipher(&rc5_desc);
62 #elif defined(LTC_SAFERP)
63 prng->yarrow.cipher = register_cipher(&saferp_desc);
64 #elif defined(LTC_RC2)
65 prng->yarrow.cipher = register_cipher(&rc2_desc);
66 #elif defined(LTC_NOEKEON)
67 prng->yarrow.cipher = register_cipher(&noekeon_desc);
68 #elif defined(LTC_ANUBIS)
69 prng->yarrow.cipher = register_cipher(&anubis_desc);
70 #elif defined(LTC_KSEED)
71 prng->yarrow.cipher = register_cipher(&kseed_desc);
72 #elif defined(LTC_KHAZAD)
73 prng->yarrow.cipher = register_cipher(&khazad_desc);
74 #elif defined(LTC_CAST5)
75 prng->yarrow.cipher = register_cipher(&cast5_desc);
76 #elif defined(LTC_XTEA)
77 prng->yarrow.cipher = register_cipher(&xtea_desc);
78 #elif defined(LTC_SAFER)
79 prng->yarrow.cipher = register_cipher(&safer_sk128_desc);
80 #elif defined(LTC_DES)
81 prng->yarrow.cipher = register_cipher(&des3_desc);
82 #else
83 #error LTC_YARROW needs at least one CIPHER
84 #endif
85 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
86 return err;
87 }
88
89 #ifdef LTC_SHA256
90 prng->yarrow.hash = register_hash(&sha256_desc);
91 #elif defined(LTC_SHA512)
92 prng->yarrow.hash = register_hash(&sha512_desc);
93 #elif defined(LTC_TIGER)
94 prng->yarrow.hash = register_hash(&tiger_desc);
95 #elif defined(LTC_SHA1)
96 prng->yarrow.hash = register_hash(&sha1_desc);
97 #elif defined(LTC_RIPEMD320)
98 prng->yarrow.hash = register_hash(&rmd320_desc);
99 #elif defined(LTC_RIPEMD256)
100 prng->yarrow.hash = register_hash(&rmd256_desc);
101 #elif defined(LTC_RIPEMD160)
102 prng->yarrow.hash = register_hash(&rmd160_desc);
103 #elif defined(LTC_RIPEMD128)
104 prng->yarrow.hash = register_hash(&rmd128_desc);
105 #elif defined(LTC_MD5)
106 prng->yarrow.hash = register_hash(&md5_desc);
107 #elif defined(LTC_MD4)
108 prng->yarrow.hash = register_hash(&md4_desc);
109 #elif defined(LTC_MD2)
110 prng->yarrow.hash = register_hash(&md2_desc);
111 #elif defined(LTC_WHIRLPOOL)
112 prng->yarrow.hash = register_hash(&whirlpool_desc);
113 #else
114 #error LTC_YARROW needs at least one HASH
115 #endif
116 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
117 return err;
118 }
119
120 /* zero the memory used */
121 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
122 LTC_MUTEX_INIT(&prng->yarrow.prng_lock)
123
124 return CRYPT_OK;
125 }
126
127 /**
128 Add entropy to the PRNG state
129 @param in The data to add
130 @param inlen Length of the data to add
131 @param prng PRNG state to update
132 @return CRYPT_OK if successful
133 */
134 int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
135 {
136 hash_state md;
137 int err;
138
139 LTC_ARGCHK(in != NULL);
140 LTC_ARGCHK(prng != NULL);
141
142 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
143
144 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
145 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
146 return err;
147 }
148
149 /* start the hash */
150 if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) {
151 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
152 return err;
153 }
154
155 /* hash the current pool */
156 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,
157 hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
158 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
159 return err;
160 }
161
162 /* add the new entropy */
163 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) {
164 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
165 return err;
166 }
167
168 /* store result */
169 if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
170 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
171 return err;
172 }
173
174 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
175 return CRYPT_OK;
176 }
177
178 /**
179 Make the PRNG ready to read from
180 @param prng The PRNG to make active
181 @return CRYPT_OK if successful
182 */
183 int yarrow_ready(prng_state *prng)
184 {
185 int ks, err;
186
187 LTC_ARGCHK(prng != NULL);
188 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
189
190 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
191 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
192 return err;
193 }
194
195 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
196 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
197 return err;
198 }
199
200 /* setup CTR mode using the "pool" as the key */
201 ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
202 if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
203 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
204 return err;
205 }
206
207 if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */
208 prng->yarrow.pool, /* IV */
209 prng->yarrow.pool, ks, /* KEY and key size */
210 0, /* number of rounds */
211 CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */
212 &prng->yarrow.ctr)) != CRYPT_OK) {
213 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
214 return err;
215 }
216 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
217 return CRYPT_OK;
218 }
219
220 /**
221 Read from the PRNG
222 @param out Destination
223 @param outlen Length of output
224 @param prng The active PRNG to read from
225 @return Number of octets read
226 */
227 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng)
228 {
229 LTC_ARGCHK(out != NULL);
230 LTC_ARGCHK(prng != NULL);
231
232 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
233
234 /* put out in predictable state first */
235 zeromem(out, outlen);
236
237 /* now randomize it */
238 if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) {
239 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
240 return 0;
241 }
242 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
243 return outlen;
244 }
245
246 /**
247 Terminate the PRNG
248 @param prng The PRNG to terminate
249 @return CRYPT_OK if successful
250 */
251 int yarrow_done(prng_state *prng)
252 {
253 int err;
254 LTC_ARGCHK(prng != NULL);
255
256 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
257
258 /* call cipher done when we invent one ;-) */
259
260 /* we invented one */
261 err = ctr_done(&prng->yarrow.ctr);
262
263 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
264 return err;
265 }
266
267 /**
268 Export the PRNG state
269 @param out [out] Destination
270 @param outlen [in/out] Max size and resulting size of the state
271 @param prng The PRNG to export
272 @return CRYPT_OK if successful
273 */
274 int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
275 {
276 LTC_ARGCHK(out != NULL);
277 LTC_ARGCHK(outlen != NULL);
278 LTC_ARGCHK(prng != NULL);
279
280 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
281
282 /* we'll write 64 bytes for s&g's */
283 if (*outlen < 64) {
284 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
285 *outlen = 64;
286 return CRYPT_BUFFER_OVERFLOW;
287 }
288
289 if (yarrow_read(out, 64, prng) != 64) {
290 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
291 return CRYPT_ERROR_READPRNG;
292 }
293 *outlen = 64;
294
295 return CRYPT_OK;
296 }
297
298 /**
299 Import a PRNG state
300 @param in The PRNG state
301 @param inlen Size of the state
302 @param prng The PRNG to import
303 @return CRYPT_OK if successful
304 */
305 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
306 {
307 int err;
308
309 LTC_ARGCHK(in != NULL);
310 LTC_ARGCHK(prng != NULL);
311
312 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
313
314 if (inlen != 64) {
315 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
316 return CRYPT_INVALID_ARG;
317 }
318
319 if ((err = yarrow_start(prng)) != CRYPT_OK) {
320 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
321 return err;
322 }
323 err = yarrow_add_entropy(in, 64, prng);
324 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
325 return err;
326 }
327
328 /**
329 PRNG self-test
330 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
331 */
332 int yarrow_test(void)
333 {
334 #ifndef LTC_TEST
335 return CRYPT_NOP;
336 #else
337 int err;
338 prng_state prng;
339
340 if ((err = yarrow_start(&prng)) != CRYPT_OK) {
341 return err;
342 }
343
344 /* now let's test the hash/cipher that was chosen */
345 if (cipher_descriptor[prng.yarrow.cipher].test &&
346 ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK)) {
347 return err;
348 }
349 if (hash_descriptor[prng.yarrow.hash].test &&
350 ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK)) {
351 return err;
352 }
353
354 return CRYPT_OK;
355 #endif
356 }
357
358 #endif
359
360
361 /* $Source$ */
362 /* $Revision$ */
363 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_ERROR_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 static const struct {
18 int code;
19 const char *msg;
20 } msgs[] = {
21 { MP_OKAY, "Successful" },
22 { MP_MEM, "Out of heap" },
23 { MP_VAL, "Value out of range" }
24 };
25
26 /* return a char * string for a given code */
27 const char *mp_error_to_string(int code)
28 {
29 int x;
30
31 /* scan the lookup table for the given message */
32 for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
33 if (msgs[x].code == code) {
34 return msgs[x].msg;
35 }
36 }
37
38 /* generic reply for invalid code */
39 return "Invalid error code";
40 }
41
42 #endif
43
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_FAST_MP_INVMOD_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 /* computes the modular inverse via binary extended euclidean algorithm,
18 * that is c = 1/a mod b
19 *
20 * Based on slow invmod except this is optimized for the case where b is
21 * odd as per HAC Note 14.64 on pp. 610
22 */
23 int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
24 {
25 mp_int x, y, u, v, B, D;
26 int res, neg;
27
28 /* 2. [modified] b must be odd */
29 if (mp_iseven (b) == 1) {
30 return MP_VAL;
31 }
32
33 /* init all our temps */
34 if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
35 return res;
36 }
37
38 /* x == modulus, y == value to invert */
39 if ((res = mp_copy (b, &x)) != MP_OKAY) {
40 goto LBL_ERR;
41 }
42
43 /* we need y = |a| */
44 if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
45 goto LBL_ERR;
46 }
47
48 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
49 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
50 goto LBL_ERR;
51 }
52 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 mp_set (&D, 1);
56
57 top:
58 /* 4. while u is even do */
59 while (mp_iseven (&u) == 1) {
60 /* 4.1 u = u/2 */
61 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
62 goto LBL_ERR;
63 }
64 /* 4.2 if B is odd then */
65 if (mp_isodd (&B) == 1) {
66 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
67 goto LBL_ERR;
68 }
69 }
70 /* B = B/2 */
71 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
72 goto LBL_ERR;
73 }
74 }
75
76 /* 5. while v is even do */
77 while (mp_iseven (&v) == 1) {
78 /* 5.1 v = v/2 */
79 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
80 goto LBL_ERR;
81 }
82 /* 5.2 if D is odd then */
83 if (mp_isodd (&D) == 1) {
84 /* D = (D-x)/2 */
85 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
86 goto LBL_ERR;
87 }
88 }
89 /* D = D/2 */
90 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
91 goto LBL_ERR;
92 }
93 }
94
95 /* 6. if u >= v then */
96 if (mp_cmp (&u, &v) != MP_LT) {
97 /* u = u - v, B = B - D */
98 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
99 goto LBL_ERR;
100 }
101
102 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
103 goto LBL_ERR;
104 }
105 } else {
106 /* v - v - u, D = D - B */
107 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
108 goto LBL_ERR;
109 }
110
111 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
112 goto LBL_ERR;
113 }
114 }
115
116 /* if not zero goto step 4 */
117 if (mp_iszero (&u) == 0) {
118 goto top;
119 }
120
121 /* now a = C, b = D, gcd == g*v */
122
123 /* if v != 1 then there is no inverse */
124 if (mp_cmp_d (&v, 1) != MP_EQ) {
125 res = MP_VAL;
126 goto LBL_ERR;
127 }
128
129 /* b is now the inverse */
130 neg = a->sign;
131 while (D.sign == MP_NEG) {
132 if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
133 goto LBL_ERR;
134 }
135 }
136 mp_exch (&D, c);
137 c->sign = neg;
138 res = MP_OKAY;
139
140 LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
141 return res;
142 }
143 #endif
144
145 /* $Source$ */
146 /* $Revision$ */
147 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_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 /* computes xR**-1 == x (mod N) via Montgomery Reduction
18 *
19 * This is an optimized implementation of montgomery_reduce
20 * which uses the comba method to quickly calculate the columns of the
21 * reduction.
22 *
23 * Based on Algorithm 14.32 on pp.601 of HAC.
24 */
25 int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
26 {
27 int ix, res, olduse;
28 mp_word W[MP_WARRAY];
29
30 /* get old used count */
31 olduse = x->used;
32
33 /* grow a as required */
34 if (x->alloc < n->used + 1) {
35 if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
36 return res;
37 }
38 }
39
40 /* first we have to get the digits of the input into
41 * an array of double precision words W[...]
42 */
43 {
44 register mp_word *_W;
45 register mp_digit *tmpx;
46
47 /* alias for the W[] array */
48 _W = W;
49
50 /* alias for the digits of x*/
51 tmpx = x->dp;
52
53 /* copy the digits of a into W[0..a->used-1] */
54 for (ix = 0; ix < x->used; ix++) {
55 *_W++ = *tmpx++;
56 }
57
58 /* zero the high words of W[a->used..m->used*2] */
59 for (; ix < n->used * 2 + 1; ix++) {
60 *_W++ = 0;
61 }
62 }
63
64 /* now we proceed to zero successive digits
65 * from the least significant upwards
66 */
67 for (ix = 0; ix < n->used; ix++) {
68 /* mu = ai * m' mod b
69 *
70 * We avoid a double precision multiplication (which isn't required)
71 * by casting the value down to a mp_digit. Note this requires
72 * that W[ix-1] have the carry cleared (see after the inner loop)
73 */
74 register mp_digit mu;
75 mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
76
77 /* a = a + mu * m * b**i
78 *
79 * This is computed in place and on the fly. The multiplication
80 * by b**i is handled by offseting which columns the results
81 * are added to.
82 *
83 * Note the comba method normally doesn't handle carries in the
84 * inner loop In this case we fix the carry from the previous
85 * column since the Montgomery reduction requires digits of the
86 * result (so far) [see above] to work. This is
87 * handled by fixing up one carry after the inner loop. The
88 * carry fixups are done in order so after these loops the
89 * first m->used words of W[] have the carries fixed
90 */
91 {
92 register int iy;
93 register mp_digit *tmpn;
94 register mp_word *_W;
95
96 /* alias for the digits of the modulus */
97 tmpn = n->dp;
98
99 /* Alias for the columns set by an offset of ix */
100 _W = W + ix;
101
102 /* inner loop */
103 for (iy = 0; iy < n->used; iy++) {
104 *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
105 }
106 }
107
108 /* now fix carry for next digit, W[ix+1] */
109 W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
110 }
111
112 /* now we have to propagate the carries and
113 * shift the words downward [all those least
114 * significant digits we zeroed].
115 */
116 {
117 register mp_digit *tmpx;
118 register mp_word *_W, *_W1;
119
120 /* nox fix rest of carries */
121
122 /* alias for current word */
123 _W1 = W + ix;
124
125 /* alias for next word, where the carry goes */
126 _W = W + ++ix;
127
128 for (; ix <= n->used * 2 + 1; ix++) {
129 *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
130 }
131
132 /* copy out, A = A/b**n
133 *
134 * The result is A/b**n but instead of converting from an
135 * array of mp_word to mp_digit than calling mp_rshd
136 * we just copy them in the right order
137 */
138
139 /* alias for destination word */
140 tmpx = x->dp;
141
142 /* alias for shifted double precision result */
143 _W = W + n->used;
144
145 for (ix = 0; ix < n->used + 1; ix++) {
146 *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
147 }
148
149 /* zero oldused digits, if the input a was larger than
150 * m->used+1 we'll have to clear the digits
151 */
152 for (; ix < olduse; ix++) {
153 *tmpx++ = 0;
154 }
155 }
156
157 /* set the max used and clamp */
158 x->used = n->used + 1;
159 mp_clamp (x);
160
161 /* if A >= m then A = A - m */
162 if (mp_cmp_mag (x, n) != MP_LT) {
163 return s_mp_sub (x, n, x);
164 }
165 return MP_OKAY;
166 }
167 #endif
168
169 /* $Source$ */
170 /* $Revision$ */
171 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_FAST_S_MP_MUL_DIGS_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 /* Fast (comba) multiplier
18 *
19 * This is the fast column-array [comba] multiplier. It is
20 * designed to compute the columns of the product first
21 * then handle the carries afterwards. This has the effect
22 * of making the nested loops that compute the columns very
23 * simple and schedulable on super-scalar processors.
24 *
25 * This has been modified to produce a variable number of
26 * digits of output so if say only a half-product is required
27 * you don't have to compute the upper half (a feature
28 * required for fast Barrett reduction).
29 *
30 * Based on Algorithm 14.12 on pp.595 of HAC.
31 *
32 */
33 int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
34 {
35 int olduse, res, pa, ix, iz;
36 mp_digit W[MP_WARRAY];
37 register mp_word _W;
38
39 /* grow the destination as required */
40 if (c->alloc < digs) {
41 if ((res = mp_grow (c, digs)) != MP_OKAY) {
42 return res;
43 }
44 }
45
46 /* number of output digits to produce */
47 pa = MIN(digs, a->used + b->used);
48
49 /* clear the carry */
50 _W = 0;
51 for (ix = 0; ix < pa; ix++) {
52 int tx, ty;
53 int iy;
54 mp_digit *tmpx, *tmpy;
55
56 /* get offsets into the two bignums */
57 ty = MIN(b->used-1, ix);
58 tx = ix - ty;
59
60 /* setup temp aliases */
61 tmpx = a->dp + tx;
62 tmpy = b->dp + ty;
63
64 /* this is the number of times the loop will iterrate, essentially
65 while (tx++ < a->used && ty-- >= 0) { ... }
66 */
67 iy = MIN(a->used-tx, ty+1);
68
69 /* execute loop */
70 for (iz = 0; iz < iy; ++iz) {
71 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
72
73 }
74
75 /* store term */
76 W[ix] = ((mp_digit)_W) & MP_MASK;
77
78 /* make next carry */
79 _W = _W >> ((mp_word)DIGIT_BIT);
80 }
81
82 /* setup dest */
83 olduse = c->used;
84 c->used = pa;
85
86 {
87 register mp_digit *tmpc;
88 tmpc = c->dp;
89 for (ix = 0; ix < pa+1; ix++) {
90 /* now extract the previous digit [below the carry] */
91 *tmpc++ = W[ix];
92 }
93
94 /* clear unused digits [that existed in the old copy of c] */
95 for (; ix < olduse; ix++) {
96 *tmpc++ = 0;
97 }
98 }
99 mp_clamp (c);
100 return MP_OKAY;
101 }
102 #endif
103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_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 /* this is a modified version of fast_s_mul_digs that only produces
18 * output digits *above* digs. See the comments for fast_s_mul_digs
19 * to see how it works.
20 *
21 * This is used in the Barrett reduction since for one of the multiplications
22 * only the higher digits were needed. This essentially halves the work.
23 *
24 * Based on Algorithm 14.12 on pp.595 of HAC.
25 */
26 int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
27 {
28 int olduse, res, pa, ix, iz;
29 mp_digit W[MP_WARRAY];
30 mp_word _W;
31
32 /* grow the destination as required */
33 pa = a->used + b->used;
34 if (c->alloc < pa) {
35 if ((res = mp_grow (c, pa)) != MP_OKAY) {
36 return res;
37 }
38 }
39
40 /* number of output digits to produce */
41 pa = a->used + b->used;
42 _W = 0;
43 for (ix = digs; ix < pa; ix++) {
44 int tx, ty, iy;
45 mp_digit *tmpx, *tmpy;
46
47 /* get offsets into the two bignums */
48 ty = MIN(b->used-1, ix);
49 tx = ix - ty;
50
51 /* setup temp aliases */
52 tmpx = a->dp + tx;
53 tmpy = b->dp + ty;
54
55 /* this is the number of times the loop will iterrate, essentially its
56 while (tx++ < a->used && ty-- >= 0) { ... }
57 */
58 iy = MIN(a->used-tx, ty+1);
59
60 /* execute loop */
61 for (iz = 0; iz < iy; iz++) {
62 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
63 }
64
65 /* store term */
66 W[ix] = ((mp_digit)_W) & MP_MASK;
67
68 /* make next carry */
69 _W = _W >> ((mp_word)DIGIT_BIT);
70 }
71
72 /* setup dest */
73 olduse = c->used;
74 c->used = pa;
75
76 {
77 register mp_digit *tmpc;
78
79 tmpc = c->dp + digs;
80 for (ix = digs; ix < pa; ix++) {
81 /* now extract the previous digit [below the carry] */
82 *tmpc++ = W[ix];
83 }
84
85 /* clear unused digits [that existed in the old copy of c] */
86 for (; ix < olduse; ix++) {
87 *tmpc++ = 0;
88 }
89 }
90 mp_clamp (c);
91 return MP_OKAY;
92 }
93 #endif
94
95 /* $Source$ */
96 /* $Revision$ */
97 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_FAST_S_MP_SQR_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 /* the jist of squaring...
18 * you do like mult except the offset of the tmpx [one that
19 * starts closer to zero] can't equal the offset of tmpy.
20 * So basically you set up iy like before then you min it with
21 * (ty-tx) so that it never happens. You double all those
22 * you add in the inner loop
23
24 After that loop you do the squares and add them in.
25 */
26
27 int fast_s_mp_sqr (mp_int * a, mp_int * b)
28 {
29 int olduse, res, pa, ix, iz;
30 mp_digit W[MP_WARRAY], *tmpx;
31 mp_word W1;
32
33 /* grow the destination as required */
34 pa = a->used + a->used;
35 if (b->alloc < pa) {
36 if ((res = mp_grow (b, pa)) != MP_OKAY) {
37 return res;
38 }
39 }
40
41 /* number of output digits to produce */
42 W1 = 0;
43 for (ix = 0; ix < pa; ix++) {
44 int tx, ty, iy;
45 mp_word _W;
46 mp_digit *tmpy;
47
48 /* clear counter */
49 _W = 0;
50
51 /* get offsets into the two bignums */
52 ty = MIN(a->used-1, ix);
53 tx = ix - ty;
54
55 /* setup temp aliases */
56 tmpx = a->dp + tx;
57 tmpy = a->dp + ty;
58
59 /* this is the number of times the loop will iterrate, essentially
60 while (tx++ < a->used && ty-- >= 0) { ... }
61 */
62 iy = MIN(a->used-tx, ty+1);
63
64 /* now for squaring tx can never equal ty
65 * we halve the distance since they approach at a rate of 2x
66 * and we have to round because odd cases need to be executed
67 */
68 iy = MIN(iy, (ty-tx+1)>>1);
69
70 /* execute loop */
71 for (iz = 0; iz < iy; iz++) {
72 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
73 }
74
75 /* double the inner product and add carry */
76 _W = _W + _W + W1;
77
78 /* even columns have the square term in them */
79 if ((ix&1) == 0) {
80 _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
81 }
82
83 /* store it */
84 W[ix] = (mp_digit)(_W & MP_MASK);
85
86 /* make next carry */
87 W1 = _W >> ((mp_word)DIGIT_BIT);
88 }
89
90 /* setup dest */
91 olduse = b->used;
92 b->used = a->used+a->used;
93
94 {
95 mp_digit *tmpb;
96 tmpb = b->dp;
97 for (ix = 0; ix < pa; ix++) {
98 *tmpb++ = W[ix] & MP_MASK;
99 }
100
101 /* clear unused digits [that existed in the old copy of c] */
102 for (; ix < olduse; ix++) {
103 *tmpb++ = 0;
104 }
105 }
106 mp_clamp (b);
107 return MP_OKAY;
108 }
109 #endif
110
111 /* $Source$ */
112 /* $Revision$ */
113 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_2EXPT_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 /* computes a = 2**b
18 *
19 * Simple algorithm which zeroes the int, grows it then just sets one bit
20 * as required.
21 */
22 int
23 mp_2expt (mp_int * a, int b)
24 {
25 int res;
26
27 /* zero a as per default */
28 mp_zero (a);
29
30 /* grow a to accomodate the single bit */
31 if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
32 return res;
33 }
34
35 /* set the used count of where the bit will go */
36 a->used = b / DIGIT_BIT + 1;
37
38 /* put the single bit in its place */
39 a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
40
41 return MP_OKAY;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_ABS_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 /* b = |a|
18 *
19 * Simple function copies the input and fixes the sign to positive
20 */
21 int
22 mp_abs (mp_int * a, mp_int * b)
23 {
24 int res;
25
26 /* copy a to b */
27 if (a != b) {
28 if ((res = mp_copy (a, b)) != MP_OKAY) {
29 return res;
30 }
31 }
32
33 /* force the sign of b to positive */
34 b->sign = MP_ZPOS;
35
36 return MP_OKAY;
37 }
38 #endif
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_ADD_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 /* high level addition (handles signs) */
18 int mp_add (mp_int * a, mp_int * b, mp_int * c)
19 {
20 int sa, sb, res;
21
22 /* get sign of both inputs */
23 sa = a->sign;
24 sb = b->sign;
25
26 /* handle two cases, not four */
27 if (sa == sb) {
28 /* both positive or both negative */
29 /* add their magnitudes, copy the sign */
30 c->sign = sa;
31 res = s_mp_add (a, b, c);
32 } else {
33 /* one positive, the other negative */
34 /* subtract the one with the greater magnitude from */
35 /* the one of the lesser magnitude. The result gets */
36 /* the sign of the one with the greater magnitude. */
37 if (mp_cmp_mag (a, b) == MP_LT) {
38 c->sign = sb;
39 res = s_mp_sub (b, a, c);
40 } else {
41 c->sign = sa;
42 res = s_mp_sub (a, b, c);
43 }
44 }
45 return res;
46 }
47
48 #endif
49
50 /* $Source$ */
51 /* $Revision$ */
52 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_ADD_D_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 /* single digit addition */
18 int
19 mp_add_d (mp_int * a, mp_digit b, mp_int * c)
20 {
21 int res, ix, oldused;
22 mp_digit *tmpa, *tmpc, mu;
23
24 /* grow c as required */
25 if (c->alloc < a->used + 1) {
26 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27 return res;
28 }
29 }
30
31 /* if a is negative and |a| >= b, call c = |a| - b */
32 if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
33 /* temporarily fix sign of a */
34 a->sign = MP_ZPOS;
35
36 /* c = |a| - b */
37 res = mp_sub_d(a, b, c);
38
39 /* fix sign */
40 a->sign = c->sign = MP_NEG;
41
42 /* clamp */
43 mp_clamp(c);
44
45 return res;
46 }
47
48 /* old number of used digits in c */
49 oldused = c->used;
50
51 /* sign always positive */
52 c->sign = MP_ZPOS;
53
54 /* source alias */
55 tmpa = a->dp;
56
57 /* destination alias */
58 tmpc = c->dp;
59
60 /* if a is positive */
61 if (a->sign == MP_ZPOS) {
62 /* add digit, after this we're propagating
63 * the carry.
64 */
65 *tmpc = *tmpa++ + b;
66 mu = *tmpc >> DIGIT_BIT;
67 *tmpc++ &= MP_MASK;
68
69 /* now handle rest of the digits */
70 for (ix = 1; ix < a->used; ix++) {
71 *tmpc = *tmpa++ + mu;
72 mu = *tmpc >> DIGIT_BIT;
73 *tmpc++ &= MP_MASK;
74 }
75 /* set final carry */
76 ix++;
77 *tmpc++ = mu;
78
79 /* setup size */
80 c->used = a->used + 1;
81 } else {
82 /* a was negative and |a| < b */
83 c->used = 1;
84
85 /* the result is a single digit */
86 if (a->used == 1) {
87 *tmpc++ = b - a->dp[0];
88 } else {
89 *tmpc++ = b;
90 }
91
92 /* setup count so the clearing of oldused
93 * can fall through correctly
94 */
95 ix = 1;
96 }
97
98 /* now zero to oldused */
99 while (ix++ < oldused) {
100 *tmpc++ = 0;
101 }
102 mp_clamp(c);
103
104 return MP_OKAY;
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_ADDMOD_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 /* d = a + b (mod c) */
18 int
19 mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
20 {
21 int res;
22 mp_int t;
23
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
27
28 if ((res = mp_add (a, b, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
32 res = mp_mod (&t, c, d);
33 mp_clear (&t);
34 return res;
35 }
36 #endif
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_AND_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 /* AND two ints together */
18 int
19 mp_and (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int res, ix, px;
22 mp_int t, *x;
23
24 if (a->used > b->used) {
25 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
37
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] &= x->dp[ix];
40 }
41
42 /* zero digits above the last from the smallest mp_int */
43 for (; ix < t.used; ix++) {
44 t.dp[ix] = 0;
45 }
46
47 mp_clamp (&t);
48 mp_exch (c, &t);
49 mp_clear (&t);
50 return MP_OKAY;
51 }
52 #endif
53
54 /* $Source$ */
55 /* $Revision$ */
56 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_CLAMP_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 /* trim unused digits
18 *
19 * This is used to ensure that leading zero digits are
20 * trimed and the leading "used" digit will be non-zero
21 * Typically very fast. Also fixes the sign if there
22 * are no more leading digits
23 */
24 void
25 mp_clamp (mp_int * a)
26 {
27 /* decrease used while the most significant digit is
28 * zero.
29 */
30 while (a->used > 0 && a->dp[a->used - 1] == 0) {
31 --(a->used);
32 }
33
34 /* reset the sign flag if used == 0 */
35 if (a->used == 0) {
36 a->sign = MP_ZPOS;
37 }
38 }
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_CLEAR_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 /* clear one (frees) */
18 void
19 mp_clear (mp_int * a)
20 {
21 int i;
22
23 /* only do anything if a hasn't been freed previously */
24 if (a->dp != NULL) {
25 /* first zero the digits */
26 for (i = 0; i < a->used; i++) {
27 a->dp[i] = 0;
28 }
29
30 /* free ram */
31 XFREE(a->dp);
32
33 /* reset members to make debugging easier */
34 a->dp = NULL;
35 a->alloc = a->used = 0;
36 a->sign = MP_ZPOS;
37 }
38 }
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_CLEAR_MULTI_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 #include <stdarg.h>
17
18 void mp_clear_multi(mp_int *mp, ...)
19 {
20 mp_int* next_mp = mp;
21 va_list args;
22 va_start(args, mp);
23 while (next_mp != NULL) {
24 mp_clear(next_mp);
25 next_mp = va_arg(args, mp_int*);
26 }
27 va_end(args);
28 }
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_CMP_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 /* compare two ints (signed)*/
18 int
19 mp_cmp (mp_int * a, mp_int * b)
20 {
21 /* compare based on sign */
22 if (a->sign != b->sign) {
23 if (a->sign == MP_NEG) {
24 return MP_LT;
25 } else {
26 return MP_GT;
27 }
28 }
29
30 /* compare digits */
31 if (a->sign == MP_NEG) {
32 /* if negative compare opposite direction */
33 return mp_cmp_mag(b, a);
34 } else {
35 return mp_cmp_mag(a, b);
36 }
37 }
38 #endif
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_CMP_D_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 /* compare a digit */
18 int mp_cmp_d(mp_int * a, mp_digit b)
19 {
20 /* compare based on sign */
21 if (a->sign == MP_NEG) {
22 return MP_LT;
23 }
24
25 /* compare based on magnitude */
26 if (a->used > 1) {
27 return MP_GT;
28 }
29
30 /* compare the only digit of a to b */
31 if (a->dp[0] > b) {
32 return MP_GT;
33 } else if (a->dp[0] < b) {
34 return MP_LT;
35 } else {
36 return MP_EQ;
37 }
38 }
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_CMP_MAG_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 /* compare maginitude of two ints (unsigned) */
18 int mp_cmp_mag (mp_int * a, mp_int * b)
19 {
20 int n;
21 mp_digit *tmpa, *tmpb;
22
23 /* compare based on # of non-zero digits */
24 if (a->used > b->used) {
25 return MP_GT;
26 }
27
28 if (a->used < b->used) {
29 return MP_LT;
30 }
31
32 /* alias for a */
33 tmpa = a->dp + (a->used - 1);
34
35 /* alias for b */
36 tmpb = b->dp + (a->used - 1);
37
38 /* compare based on digits */
39 for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
40 if (*tmpa > *tmpb) {
41 return MP_GT;
42 }
43
44 if (*tmpa < *tmpb) {
45 return MP_LT;
46 }
47 }
48 return MP_EQ;
49 }
50 #endif
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_CNT_LSB_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 static const int lnz[16] = {
18 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
19 };
20
21 /* Counts the number of lsbs which are zero before the first zero bit */
22 int mp_cnt_lsb(mp_int *a)
23 {
24 int x;
25 mp_digit q, qq;
26
27 /* easy out */
28 if (mp_iszero(a) == 1) {
29 return 0;
30 }
31
32 /* scan lower digits until non-zero */
33 for (x = 0; x < a->used && a->dp[x] == 0; x++);
34 q = a->dp[x];
35 x *= DIGIT_BIT;
36
37 /* now scan this digit until a 1 is found */
38 if ((q & 1) == 0) {
39 do {
40 qq = q & 15;
41 x += lnz[qq];
42 q >>= 4;
43 } while (qq == 0);
44 }
45 return x;
46 }
47
48 #endif
49
50 /* $Source$ */
51 /* $Revision$ */
52 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_COPY_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 /* copy, b = a */
18 int
19 mp_copy (mp_int * a, mp_int * b)
20 {
21 int res, n;
22
23 /* if dst == src do nothing */
24 if (a == b) {
25 return MP_OKAY;
26 }
27
28 /* grow dest */
29 if (b->alloc < a->used) {
30 if ((res = mp_grow (b, a->used)) != MP_OKAY) {
31 return res;
32 }
33 }
34
35 /* zero b and copy the parameters over */
36 {
37 register mp_digit *tmpa, *tmpb;
38
39 /* pointer aliases */
40
41 /* source */
42 tmpa = a->dp;
43
44 /* destination */
45 tmpb = b->dp;
46
47 /* copy all the digits */
48 for (n = 0; n < a->used; n++) {
49 *tmpb++ = *tmpa++;
50 }
51
52 /* clear high digits */
53 for (; n < b->used; n++) {
54 *tmpb++ = 0;
55 }
56 }
57
58 /* copy used count and sign */
59 b->used = a->used;
60 b->sign = a->sign;
61 return MP_OKAY;
62 }
63 #endif
64
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_COUNT_BITS_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 /* returns the number of bits in an int */
18 int
19 mp_count_bits (mp_int * a)
20 {
21 int r;
22 mp_digit q;
23
24 /* shortcut */
25 if (a->used == 0) {
26 return 0;
27 }
28
29 /* get number of digits and add that */
30 r = (a->used - 1) * DIGIT_BIT;
31
32 /* take the last digit and count the bits in it */
33 q = a->dp[a->used - 1];
34 while (q > ((mp_digit) 0)) {
35 ++r;
36 q >>= ((mp_digit) 1);
37 }
38 return r;
39 }
40 #endif
41
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_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 #ifdef BN_MP_DIV_SMALL
18
19 /* slower bit-bang division... also smaller */
20 int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
21 {
22 mp_int ta, tb, tq, q;
23 int res, n, n2;
24
25 /* is divisor zero ? */
26 if (mp_iszero (b) == 1) {
27 return MP_VAL;
28 }
29
30 /* if a < b then q=0, r = a */
31 if (mp_cmp_mag (a, b) == MP_LT) {
32 if (d != NULL) {
33 res = mp_copy (a, d);
34 } else {
35 res = MP_OKAY;
36 }
37 if (c != NULL) {
38 mp_zero (c);
39 }
40 return res;
41 }
42
43 /* init our temps */
44 if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
45 return res;
46 }
47
48
49 mp_set(&tq, 1);
50 n = mp_count_bits(a) - mp_count_bits(b);
51 if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
52 ((res = mp_abs(b, &tb)) != MP_OKAY) ||
53 ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
54 ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
55 goto LBL_ERR;
56 }
57
58 while (n-- >= 0) {
59 if (mp_cmp(&tb, &ta) != MP_GT) {
60 if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
61 ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
62 goto LBL_ERR;
63 }
64 }
65 if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
66 ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
67 goto LBL_ERR;
68 }
69 }
70
71 /* now q == quotient and ta == remainder */
72 n = a->sign;
73 n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
74 if (c != NULL) {
75 mp_exch(c, &q);
76 c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
77 }
78 if (d != NULL) {
79 mp_exch(d, &ta);
80 d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
81 }
82 LBL_ERR:
83 mp_clear_multi(&ta, &tb, &tq, &q, NULL);
84 return res;
85 }
86
87 #else
88
89 /* integer signed division.
90 * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
91 * HAC pp.598 Algorithm 14.20
92 *
93 * Note that the description in HAC is horribly
94 * incomplete. For example, it doesn't consider
95 * the case where digits are removed from 'x' in
96 * the inner loop. It also doesn't consider the
97 * case that y has fewer than three digits, etc..
98 *
99 * The overall algorithm is as described as
100 * 14.20 from HAC but fixed to treat these cases.
101 */
102 int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
103 {
104 mp_int q, x, y, t1, t2;
105 int res, n, t, i, norm, neg;
106
107 /* is divisor zero ? */
108 if (mp_iszero (b) == 1) {
109 return MP_VAL;
110 }
111
112 /* if a < b then q=0, r = a */
113 if (mp_cmp_mag (a, b) == MP_LT) {
114 if (d != NULL) {
115 res = mp_copy (a, d);
116 } else {
117 res = MP_OKAY;
118 }
119 if (c != NULL) {
120 mp_zero (c);
121 }
122 return res;
123 }
124
125 if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
126 return res;
127 }
128 q.used = a->used + 2;
129
130 if ((res = mp_init (&t1)) != MP_OKAY) {
131 goto LBL_Q;
132 }
133
134 if ((res = mp_init (&t2)) != MP_OKAY) {
135 goto LBL_T1;
136 }
137
138 if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
139 goto LBL_T2;
140 }
141
142 if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
143 goto LBL_X;
144 }
145
146 /* fix the sign */
147 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
148 x.sign = y.sign = MP_ZPOS;
149
150 /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
151 norm = mp_count_bits(&y) % DIGIT_BIT;
152 if (norm < (int)(DIGIT_BIT-1)) {
153 norm = (DIGIT_BIT-1) - norm;
154 if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
155 goto LBL_Y;
156 }
157 if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
158 goto LBL_Y;
159 }
160 } else {
161 norm = 0;
162 }
163
164 /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
165 n = x.used - 1;
166 t = y.used - 1;
167
168 /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
169 if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
170 goto LBL_Y;
171 }
172
173 while (mp_cmp (&x, &y) != MP_LT) {
174 ++(q.dp[n - t]);
175 if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
176 goto LBL_Y;
177 }
178 }
179
180 /* reset y by shifting it back down */
181 mp_rshd (&y, n - t);
182
183 /* step 3. for i from n down to (t + 1) */
184 for (i = n; i >= (t + 1); i--) {
185 if (i > x.used) {
186 continue;
187 }
188
189 /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
190 * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
191 if (x.dp[i] == y.dp[t]) {
192 q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
193 } else {
194 mp_word tmp;
195 tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
196 tmp |= ((mp_word) x.dp[i - 1]);
197 tmp /= ((mp_word) y.dp[t]);
198 if (tmp > (mp_word) MP_MASK)
199 tmp = MP_MASK;
200 q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
201 }
202
203 /* while (q{i-t-1} * (yt * b + y{t-1})) >
204 xi * b**2 + xi-1 * b + xi-2
205
206 do q{i-t-1} -= 1;
207 */
208 q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
209 do {
210 q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
211
212 /* find left hand */
213 mp_zero (&t1);
214 t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
215 t1.dp[1] = y.dp[t];
216 t1.used = 2;
217 if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
218 goto LBL_Y;
219 }
220
221 /* find right hand */
222 t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
223 t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
224 t2.dp[2] = x.dp[i];
225 t2.used = 3;
226 } while (mp_cmp_mag(&t1, &t2) == MP_GT);
227
228 /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
229 if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
230 goto LBL_Y;
231 }
232
233 if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
234 goto LBL_Y;
235 }
236
237 if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
238 goto LBL_Y;
239 }
240
241 /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
242 if (x.sign == MP_NEG) {
243 if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
244 goto LBL_Y;
245 }
246 if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
247 goto LBL_Y;
248 }
249 if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
250 goto LBL_Y;
251 }
252
253 q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
254 }
255 }
256
257 /* now q is the quotient and x is the remainder
258 * [which we have to normalize]
259 */
260
261 /* get sign before writing to c */
262 x.sign = x.used == 0 ? MP_ZPOS : a->sign;
263
264 if (c != NULL) {
265 mp_clamp (&q);
266 mp_exch (&q, c);
267 c->sign = neg;
268 }
269
270 if (d != NULL) {
271 mp_div_2d (&x, norm, &x, NULL);
272 mp_exch (&x, d);
273 }
274
275 res = MP_OKAY;
276
277 LBL_Y:mp_clear (&y);
278 LBL_X:mp_clear (&x);
279 LBL_T2:mp_clear (&t2);
280 LBL_T1:mp_clear (&t1);
281 LBL_Q:mp_clear (&q);
282 return res;
283 }
284
285 #endif
286
287 #endif
288
289 /* $Source$ */
290 /* $Revision$ */
291 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_2_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 /* b = a/2 */
18 int mp_div_2(mp_int * a, mp_int * b)
19 {
20 int x, res, oldused;
21
22 /* copy */
23 if (b->alloc < a->used) {
24 if ((res = mp_grow (b, a->used)) != MP_OKAY) {
25 return res;
26 }
27 }
28
29 oldused = b->used;
30 b->used = a->used;
31 {
32 register mp_digit r, rr, *tmpa, *tmpb;
33
34 /* source alias */
35 tmpa = a->dp + b->used - 1;
36
37 /* dest alias */
38 tmpb = b->dp + b->used - 1;
39
40 /* carry */
41 r = 0;
42 for (x = b->used - 1; x >= 0; x--) {
43 /* get the carry for the next iteration */
44 rr = *tmpa & 1;
45
46 /* shift the current digit, add in carry and store */
47 *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
48
49 /* forward carry to next iteration */
50 r = rr;
51 }
52
53 /* zero excess digits */
54 tmpb = b->dp + b->used;
55 for (x = b->used; x < oldused; x++) {
56 *tmpb++ = 0;
57 }
58 }
59 b->sign = a->sign;
60 mp_clamp (b);
61 return MP_OKAY;
62 }
63 #endif
64
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_2D_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 /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
18 int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
19 {
20 mp_digit D, r, rr;
21 int x, res;
22 mp_int t;
23
24
25 /* if the shift count is <= 0 then we do no work */
26 if (b <= 0) {
27 res = mp_copy (a, c);
28 if (d != NULL) {
29 mp_zero (d);
30 }
31 return res;
32 }
33
34 if ((res = mp_init (&t)) != MP_OKAY) {
35 return res;
36 }
37
38 /* get the remainder */
39 if (d != NULL) {
40 if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
41 mp_clear (&t);
42 return res;
43 }
44 }
45
46 /* copy */
47 if ((res = mp_copy (a, c)) != MP_OKAY) {
48 mp_clear (&t);
49 return res;
50 }
51
52 /* shift by as many digits in the bit count */
53 if (b >= (int)DIGIT_BIT) {
54 mp_rshd (c, b / DIGIT_BIT);
55 }
56
57 /* shift any bit count < DIGIT_BIT */
58 D = (mp_digit) (b % DIGIT_BIT);
59 if (D != 0) {
60 register mp_digit *tmpc, mask, shift;
61
62 /* mask */
63 mask = (((mp_digit)1) << D) - 1;
64
65 /* shift for lsb */
66 shift = DIGIT_BIT - D;
67
68 /* alias */
69 tmpc = c->dp + (c->used - 1);
70
71 /* carry */
72 r = 0;
73 for (x = c->used - 1; x >= 0; x--) {
74 /* get the lower bits of this word in a temp */
75 rr = *tmpc & mask;
76
77 /* shift the current word and mix in the carry bits from the previous word */
78 *tmpc = (*tmpc >> D) | (r << shift);
79 --tmpc;
80
81 /* set the carry to the carry bits of the current word found above */
82 r = rr;
83 }
84 }
85 mp_clamp (c);
86 if (d != NULL) {
87 mp_exch (&t, d);
88 }
89 mp_clear (&t);
90 return MP_OKAY;
91 }
92 #endif
93
94 /* $Source$ */
95 /* $Revision$ */
96 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_3_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 /* divide by three (based on routine from MPI and the GMP manual) */
18 int
19 mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
20 {
21 mp_int q;
22 mp_word w, t;
23 mp_digit b;
24 int res, ix;
25
26 /* b = 2**DIGIT_BIT / 3 */
27 b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
28
29 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
30 return res;
31 }
32
33 q.used = a->used;
34 q.sign = a->sign;
35 w = 0;
36 for (ix = a->used - 1; ix >= 0; ix--) {
37 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
38
39 if (w >= 3) {
40 /* multiply w by [1/3] */
41 t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
42
43 /* now subtract 3 * [w/3] from w, to get the remainder */
44 w -= t+t+t;
45
46 /* fixup the remainder as required since
47 * the optimization is not exact.
48 */
49 while (w >= 3) {
50 t += 1;
51 w -= 3;
52 }
53 } else {
54 t = 0;
55 }
56 q.dp[ix] = (mp_digit)t;
57 }
58
59 /* [optional] store the remainder */
60 if (d != NULL) {
61 *d = (mp_digit)w;
62 }
63
64 /* [optional] store the quotient */
65 if (c != NULL) {
66 mp_clamp(&q);
67 mp_exch(&q, c);
68 }
69 mp_clear(&q);
70
71 return res;
72 }
73
74 #endif
75
76 /* $Source$ */
77 /* $Revision$ */
78 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_DIV_D_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 static int s_is_power_of_two(mp_digit b, int *p)
18 {
19 int x;
20
21 /* fast return if no power of two */
22 if ((b==0) || (b & (b-1))) {
23 return 0;
24 }
25
26 for (x = 0; x < DIGIT_BIT; x++) {
27 if (b == (((mp_digit)1)<<x)) {
28 *p = x;
29 return 1;
30 }
31 }
32 return 0;
33 }
34
35 /* single digit division (based on routine from MPI) */
36 int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
37 {
38 mp_int q;
39 mp_word w;
40 mp_digit t;
41 int res, ix;
42
43 /* cannot divide by zero */
44 if (b == 0) {
45 return MP_VAL;
46 }
47
48 /* quick outs */
49 if (b == 1 || mp_iszero(a) == 1) {
50 if (d != NULL) {
51 *d = 0;
52 }
53 if (c != NULL) {
54 return mp_copy(a, c);
55 }
56 return MP_OKAY;
57 }
58
59 /* power of two ? */
60 if (s_is_power_of_two(b, &ix) == 1) {
61 if (d != NULL) {
62 *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
63 }
64 if (c != NULL) {
65 return mp_div_2d(a, ix, c, NULL);
66 }
67 return MP_OKAY;
68 }
69
70 #ifdef BN_MP_DIV_3_C
71 /* three? */
72 if (b == 3) {
73 return mp_div_3(a, c, d);
74 }
75 #endif
76
77 /* no easy answer [c'est la vie]. Just division */
78 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
79 return res;
80 }
81
82 q.used = a->used;
83 q.sign = a->sign;
84 w = 0;
85 for (ix = a->used - 1; ix >= 0; ix--) {
86 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
87
88 if (w >= b) {
89 t = (mp_digit)(w / b);
90 w -= ((mp_word)t) * ((mp_word)b);
91 } else {
92 t = 0;
93 }
94 q.dp[ix] = (mp_digit)t;
95 }
96
97 if (d != NULL) {
98 *d = (mp_digit)w;
99 }
100
101 if (c != NULL) {
102 mp_clamp(&q);
103 mp_exch(&q, c);
104 }
105 mp_clear(&q);
106
107 return res;
108 }
109
110 #endif
111
112 /* $Source$ */
113 /* $Revision$ */
114 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_DR_IS_MODULUS_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 /* determines if a number is a valid DR modulus */
18 int mp_dr_is_modulus(mp_int *a)
19 {
20 int ix;
21
22 /* must be at least two digits */
23 if (a->used < 2) {
24 return 0;
25 }
26
27 /* must be of the form b**k - a [a <= b] so all
28 * but the first digit must be equal to -1 (mod b).
29 */
30 for (ix = 1; ix < a->used; ix++) {
31 if (a->dp[ix] != MP_MASK) {
32 return 0;
33 }
34 }
35 return 1;
36 }
37
38 #endif
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_DR_REDUCE_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 /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
18 *
19 * Based on algorithm from the paper
20 *
21 * "Generating Efficient Primes for Discrete Log Cryptosystems"
22 * Chae Hoon Lim, Pil Joong Lee,
23 * POSTECH Information Research Laboratories
24 *
25 * The modulus must be of a special format [see manual]
26 *
27 * Has been modified to use algorithm 7.10 from the LTM book instead
28 *
29 * Input x must be in the range 0 <= x <= (n-1)**2
30 */
31 int
32 mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
33 {
34 int err, i, m;
35 mp_word r;
36 mp_digit mu, *tmpx1, *tmpx2;
37
38 /* m = digits in modulus */
39 m = n->used;
40
41 /* ensure that "x" has at least 2m digits */
42 if (x->alloc < m + m) {
43 if ((err = mp_grow (x, m + m)) != MP_OKAY) {
44 return err;
45 }
46 }
47
48 /* top of loop, this is where the code resumes if
49 * another reduction pass is required.
50 */
51 top:
52 /* aliases for digits */
53 /* alias for lower half of x */
54 tmpx1 = x->dp;
55
56 /* alias for upper half of x, or x/B**m */
57 tmpx2 = x->dp + m;
58
59 /* set carry to zero */
60 mu = 0;
61
62 /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
63 for (i = 0; i < m; i++) {
64 r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
65 *tmpx1++ = (mp_digit)(r & MP_MASK);
66 mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
67 }
68
69 /* set final carry */
70 *tmpx1++ = mu;
71
72 /* zero words above m */
73 for (i = m + 1; i < x->used; i++) {
74 *tmpx1++ = 0;
75 }
76
77 /* clamp, sub and return */
78 mp_clamp (x);
79
80 /* if x >= n then subtract and reduce again
81 * Each successive "recursion" makes the input smaller and smaller.
82 */
83 if (mp_cmp_mag (x, n) != MP_LT) {
84 s_mp_sub(x, n, x);
85 goto top;
86 }
87 return MP_OKAY;
88 }
89 #endif
90
91 /* $Source$ */
92 /* $Revision$ */
93 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_DR_SETUP_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 /* determines the setup value */
18 void mp_dr_setup(mp_int *a, mp_digit *d)
19 {
20 /* the casts are required if DIGIT_BIT is one less than
21 * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
22 */
23 *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
24 ((mp_word)a->dp[0]));
25 }
26
27 #endif
28
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_EXCH_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 /* swap the elements of two integers, for cases where you can't simply swap the
18 * mp_int pointers around
19 */
20 void
21 mp_exch (mp_int * a, mp_int * b)
22 {
23 mp_int t;
24
25 t = *a;
26 *a = *b;
27 *b = t;
28 }
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_EXPT_D_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 (mp_int * a, mp_digit b, mp_int * c)
19 {
20 int res;
21 mp_int g;
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 #endif
53
54 /* $Source$ */
55 /* $Revision$ */
56 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_EXPTMOD_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
18 /* this is a shell function that calls either the normal or Montgomery
19 * exptmod functions. Originally the call to the montgomery code was
20 * embedded in the normal function but that wasted alot of stack space
21 * for nothing (since 99% of the time the Montgomery code would be called)
22 */
23 int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
24 {
25 int dr;
26
27 /* modulus P must be positive */
28 if (P->sign == MP_NEG) {
29 return MP_VAL;
30 }
31
32 /* if exponent X is negative we have to recurse */
33 if (X->sign == MP_NEG) {
34 #ifdef BN_MP_INVMOD_C
35 mp_int tmpG, tmpX;
36 int err;
37
38 /* first compute 1/G mod P */
39 if ((err = mp_init(&tmpG)) != MP_OKAY) {
40 return err;
41 }
42 if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
43 mp_clear(&tmpG);
44 return err;
45 }
46
47 /* now get |X| */
48 if ((err = mp_init(&tmpX)) != MP_OKAY) {
49 mp_clear(&tmpG);
50 return err;
51 }
52 if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
53 mp_clear_multi(&tmpG, &tmpX, NULL);
54 return err;
55 }
56
57 /* and now compute (1/G)**|X| instead of G**X [X < 0] */
58 err = mp_exptmod(&tmpG, &tmpX, P, Y);
59 mp_clear_multi(&tmpG, &tmpX, NULL);
60 return err;
61 #else
62 /* no invmod */
63 return MP_VAL;
64 #endif
65 }
66
67 /* modified diminished radix reduction */
68 #if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
69 if (mp_reduce_is_2k_l(P) == MP_YES) {
70 return s_mp_exptmod(G, X, P, Y, 1);
71 }
72 #endif
73
74 #ifdef BN_MP_DR_IS_MODULUS_C
75 /* is it a DR modulus? */
76 dr = mp_dr_is_modulus(P);
77 #else
78 /* default to no */
79 dr = 0;
80 #endif
81
82 #ifdef BN_MP_REDUCE_IS_2K_C
83 /* if not, is it a unrestricted DR modulus? */
84 if (dr == 0) {
85 dr = mp_reduce_is_2k(P) << 1;
86 }
87 #endif
88
89 /* if the modulus is odd or dr != 0 use the montgomery method */
90 #ifdef BN_MP_EXPTMOD_FAST_C
91 if (mp_isodd (P) == 1 || dr != 0) {
92 return mp_exptmod_fast (G, X, P, Y, dr);
93 } else {
94 #endif
95 #ifdef BN_S_MP_EXPTMOD_C
96 /* otherwise use the generic Barrett reduction technique */
97 return s_mp_exptmod (G, X, P, Y, 0);
98 #else
99 /* no exptmod for evens */
100 return MP_VAL;
101 #endif
102 #ifdef BN_MP_EXPTMOD_FAST_C
103 }
104 #endif
105 }
106
107 #endif
108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_EXPTMOD_FAST_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 /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
18 *
19 * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
20 * The value of k changes based on the size of the exponent.
21 *
22 * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
23 */
24
25 #ifdef MP_LOW_MEM
26 #define TAB_SIZE 32
27 #else
28 #define TAB_SIZE 256
29 #endif
30
31 int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
32 {
33 mp_int M[TAB_SIZE], res;
34 mp_digit buf, mp;
35 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
36
37 /* use a pointer to the reduction algorithm. This allows us to use
38 * one of many reduction algorithms without modding the guts of
39 * the code with if statements everywhere.
40 */
41 int (*redux)(mp_int*,mp_int*,mp_digit);
42
43 /* find window size */
44 x = mp_count_bits (X);
45 if (x <= 7) {
46 winsize = 2;
47 } else if (x <= 36) {
48 winsize = 3;
49 } else if (x <= 140) {
50 winsize = 4;
51 } else if (x <= 450) {
52 winsize = 5;
53 } else if (x <= 1303) {
54 winsize = 6;
55 } else if (x <= 3529) {
56 winsize = 7;
57 } else {
58 winsize = 8;
59 }
60
61 #ifdef MP_LOW_MEM
62 if (winsize > 5) {
63 winsize = 5;
64 }
65 #endif
66
67 /* init M array */
68 /* init first cell */
69 if ((err = mp_init(&M[1])) != MP_OKAY) {
70 return err;
71 }
72
73 /* now init the second half of the array */
74 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
75 if ((err = mp_init(&M[x])) != MP_OKAY) {
76 for (y = 1<<(winsize-1); y < x; y++) {
77 mp_clear (&M[y]);
78 }
79 mp_clear(&M[1]);
80 return err;
81 }
82 }
83
84 /* determine and setup reduction code */
85 if (redmode == 0) {
86 #ifdef BN_MP_MONTGOMERY_SETUP_C
87 /* now setup montgomery */
88 if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
89 goto LBL_M;
90 }
91 #else
92 err = MP_VAL;
93 goto LBL_M;
94 #endif
95
96 /* automatically pick the comba one if available (saves quite a few calls/ifs) */
97 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
98 if (((P->used * 2 + 1) < MP_WARRAY) &&
99 P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
100 redux = fast_mp_montgomery_reduce;
101 } else
102 #endif
103 {
104 #ifdef BN_MP_MONTGOMERY_REDUCE_C
105 /* use slower baseline Montgomery method */
106 redux = mp_montgomery_reduce;
107 #else
108 err = MP_VAL;
109 goto LBL_M;
110 #endif
111 }
112 } else if (redmode == 1) {
113 #if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
114 /* setup DR reduction for moduli of the form B**k - b */
115 mp_dr_setup(P, &mp);
116 redux = mp_dr_reduce;
117 #else
118 err = MP_VAL;
119 goto LBL_M;
120 #endif
121 } else {
122 #if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
123 /* setup DR reduction for moduli of the form 2**k - b */
124 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
125 goto LBL_M;
126 }
127 redux = mp_reduce_2k;
128 #else
129 err = MP_VAL;
130 goto LBL_M;
131 #endif
132 }
133
134 /* setup result */
135 if ((err = mp_init (&res)) != MP_OKAY) {
136 goto LBL_M;
137 }
138
139 /* create M table
140 *
141
142 *
143 * The first half of the table is not computed though accept for M[0] and M[1]
144 */
145
146 if (redmode == 0) {
147 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
148 /* now we need R mod m */
149 if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
150 goto LBL_RES;
151 }
152 #else
153 err = MP_VAL;
154 goto LBL_RES;
155 #endif
156
157 /* now set M[1] to G * R mod m */
158 if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
159 goto LBL_RES;
160 }
161 } else {
162 mp_set(&res, 1);
163 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
164 goto LBL_RES;
165 }
166 }
167
168 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
169 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
170 goto LBL_RES;
171 }
172
173 for (x = 0; x < (winsize - 1); x++) {
174 if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
175 goto LBL_RES;
176 }
177 if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
178 goto LBL_RES;
179 }
180 }
181
182 /* create upper table */
183 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
184 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
185 goto LBL_RES;
186 }
187 if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
188 goto LBL_RES;
189 }
190 }
191
192 /* set initial mode and bit cnt */
193 mode = 0;
194 bitcnt = 1;
195 buf = 0;
196 digidx = X->used - 1;
197 bitcpy = 0;
198 bitbuf = 0;
199
200 for (;;) {
201 /* grab next digit as required */
202 if (--bitcnt == 0) {
203 /* if digidx == -1 we are out of digits so break */
204 if (digidx == -1) {
205 break;
206 }
207 /* read next digit and reset bitcnt */
208 buf = X->dp[digidx--];
209 bitcnt = (int)DIGIT_BIT;
210 }
211
212 /* grab the next msb from the exponent */
213 y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
214 buf <<= (mp_digit)1;
215
216 /* if the bit is zero and mode == 0 then we ignore it
217 * These represent the leading zero bits before the first 1 bit
218 * in the exponent. Technically this opt is not required but it
219 * does lower the # of trivial squaring/reductions used
220 */
221 if (mode == 0 && y == 0) {
222 continue;
223 }
224
225 /* if the bit is zero and mode == 1 then we square */
226 if (mode == 1 && y == 0) {
227 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
228 goto LBL_RES;
229 }
230 if ((err = redux (&res, P, mp)) != MP_OKAY) {
231 goto LBL_RES;
232 }
233 continue;
234 }
235
236 /* else we add it to the window */
237 bitbuf |= (y << (winsize - ++bitcpy));
238 mode = 2;
239
240 if (bitcpy == winsize) {
241 /* ok window is filled so square as required and multiply */
242 /* square first */
243 for (x = 0; x < winsize; x++) {
244 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
245 goto LBL_RES;
246 }
247 if ((err = redux (&res, P, mp)) != MP_OKAY) {
248 goto LBL_RES;
249 }
250 }
251
252 /* then multiply */
253 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
254 goto LBL_RES;
255 }
256 if ((err = redux (&res, P, mp)) != MP_OKAY) {
257 goto LBL_RES;
258 }
259
260 /* empty window and reset */
261 bitcpy = 0;
262 bitbuf = 0;
263 mode = 1;
264 }
265 }
266
267 /* if bits remain then square/multiply */
268 if (mode == 2 && bitcpy > 0) {
269 /* square then multiply if the bit is set */
270 for (x = 0; x < bitcpy; x++) {
271 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
272 goto LBL_RES;
273 }
274 if ((err = redux (&res, P, mp)) != MP_OKAY) {
275 goto LBL_RES;
276 }
277
278 /* get next bit of the window */
279 bitbuf <<= 1;
280 if ((bitbuf & (1 << winsize)) != 0) {
281 /* then multiply */
282 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
283 goto LBL_RES;
284 }
285 if ((err = redux (&res, P, mp)) != MP_OKAY) {
286 goto LBL_RES;
287 }
288 }
289 }
290 }
291
292 if (redmode == 0) {
293 /* fixup result if Montgomery reduction is used
294 * recall that any value in a Montgomery system is
295 * actually multiplied by R mod n. So we have
296 * to reduce one more time to cancel out the factor
297 * of R.
298 */
299 if ((err = redux(&res, P, mp)) != MP_OKAY) {
300 goto LBL_RES;
301 }
302 }
303
304 /* swap res with Y */
305 mp_exch (&res, Y);
306 err = MP_OKAY;
307 LBL_RES:mp_clear (&res);
308 LBL_M:
309 mp_clear(&M[1]);
310 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
311 mp_clear (&M[x]);
312 }
313 return err;
314 }
315 #endif
316
317
318 /* $Source$ */
319 /* $Revision$ */
320 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_EXTEUCLID_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 /* Extended euclidean algorithm of (a, b) produces
18 a*u1 + b*u2 = u3
19 */
20 int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
21 {
22 mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
23 int err;
24
25 if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
26 return err;
27 }
28
29 /* initialize, (u1,u2,u3) = (1,0,a) */
30 mp_set(&u1, 1);
31 if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
32
33 /* initialize, (v1,v2,v3) = (0,1,b) */
34 mp_set(&v2, 1);
35 if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
36
37 /* loop while v3 != 0 */
38 while (mp_iszero(&v3) == MP_NO) {
39 /* q = u3/v3 */
40 if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
41
42 /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
43 if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
44 if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
45 if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
46 if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
47 if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
48 if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
49
50 /* (u1,u2,u3) = (v1,v2,v3) */
51 if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
52 if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
53 if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
54
55 /* (v1,v2,v3) = (t1,t2,t3) */
56 if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
57 if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
58 if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
59 }
60
61 /* make sure U3 >= 0 */
62 if (u3.sign == MP_NEG) {
63 mp_neg(&u1, &u1);
64 mp_neg(&u2, &u2);
65 mp_neg(&u3, &u3);
66 }
67
68 /* copy result out */
69 if (U1 != NULL) { mp_exch(U1, &u1); }
70 if (U2 != NULL) { mp_exch(U2, &u2); }
71 if (U3 != NULL) { mp_exch(U3, &u3); }
72
73 err = MP_OKAY;
74 _ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
75 return err;
76 }
77 #endif
78
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_FREAD_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 /* read a bigint from a file stream in ASCII */
18 int mp_fread(mp_int *a, int radix, FILE *stream)
19 {
20 int err, ch, neg, y;
21
22 /* clear a */
23 mp_zero(a);
24
25 /* if first digit is - then set negative */
26 ch = fgetc(stream);
27 if (ch == '-') {
28 neg = MP_NEG;
29 ch = fgetc(stream);
30 } else {
31 neg = MP_ZPOS;
32 }
33
34 for (;;) {
35 /* find y in the radix map */
36 for (y = 0; y < radix; y++) {
37 if (mp_s_rmap[y] == ch) {
38 break;
39 }
40 }
41 if (y == radix) {
42 break;
43 }
44
45 /* shift up and add */
46 if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
47 return err;
48 }
49 if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
50 return err;
51 }
52
53 ch = fgetc(stream);
54 }
55 if (mp_cmp_d(a, 0) != MP_EQ) {
56 a->sign = neg;
57 }
58
59 return MP_OKAY;
60 }
61
62 #endif
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_FWRITE_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 int mp_fwrite(mp_int *a, int radix, FILE *stream)
18 {
19 char *buf;
20 int err, len, x;
21
22 if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
23 return err;
24 }
25
26 buf = OPT_CAST(char) XMALLOC (len);
27 if (buf == NULL) {
28 return MP_MEM;
29 }
30
31 if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
32 XFREE (buf);
33 return err;
34 }
35
36 for (x = 0; x < len; x++) {
37 if (fputc(buf[x], stream) == EOF) {
38 XFREE (buf);
39 return MP_VAL;
40 }
41 }
42
43 XFREE (buf);
44 return MP_OKAY;
45 }
46
47 #endif
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_GCD_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 /* Greatest Common Divisor using the binary method */
18 int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
19 {
20 mp_int u, v;
21 int k, u_lsb, v_lsb, res;
22
23 /* either zero than gcd is the largest */
24 if (mp_iszero (a) == MP_YES) {
25 return mp_abs (b, c);
26 }
27 if (mp_iszero (b) == MP_YES) {
28 return mp_abs (a, c);
29 }
30
31 /* get copies of a and b we can modify */
32 if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
33 return res;
34 }
35
36 if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
37 goto LBL_U;
38 }
39
40 /* must be positive for the remainder of the algorithm */
41 u.sign = v.sign = MP_ZPOS;
42
43 /* B1. Find the common power of two for u and v */
44 u_lsb = mp_cnt_lsb(&u);
45 v_lsb = mp_cnt_lsb(&v);
46 k = MIN(u_lsb, v_lsb);
47
48 if (k > 0) {
49 /* divide the power of two out */
50 if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
51 goto LBL_V;
52 }
53
54 if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
55 goto LBL_V;
56 }
57 }
58
59 /* divide any remaining factors of two out */
60 if (u_lsb != k) {
61 if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
62 goto LBL_V;
63 }
64 }
65
66 if (v_lsb != k) {
67 if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
68 goto LBL_V;
69 }
70 }
71
72 while (mp_iszero(&v) == 0) {
73 /* make sure v is the largest */
74 if (mp_cmp_mag(&u, &v) == MP_GT) {
75 /* swap u and v to make sure v is >= u */
76 mp_exch(&u, &v);
77 }
78
79 /* subtract smallest from largest */
80 if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
81 goto LBL_V;
82 }
83
84 /* Divide out all factors of two */
85 if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
86 goto LBL_V;
87 }
88 }
89
90 /* multiply by 2**k which we divided out at the beginning */
91 if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
92 goto LBL_V;
93 }
94 c->sign = MP_ZPOS;
95 res = MP_OKAY;
96 LBL_V:mp_clear (&u);
97 LBL_U:mp_clear (&v);
98 return res;
99 }
100 #endif
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_GET_INT_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 32-bits of an mp_int */
18 unsigned long mp_get_int(mp_int * a)
19 {
20 int i;
21 ulong64 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 while (--i >= 0) {
34 res = (res << DIGIT_BIT) | DIGIT(a,i);
35 }
36
37 /* force result to 32-bits always so it is consistent on non 32-bit platforms */
38 return (unsigned long)(res & 0xFFFFFFFFUL);
39 }
40 #endif
41
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_GROW_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 /* grow as required */
18 int mp_grow (mp_int * a, int size)
19 {
20 int i;
21 mp_digit *tmp;
22
23 /* if the alloc size is smaller alloc more ram */
24 if (a->alloc < size) {
25 /* ensure there are always at least MP_PREC digits extra on top */
26 size += (MP_PREC * 2) - (size % MP_PREC);
27
28 /* reallocate the array a->dp
29 *
30 * We store the return in a temporary variable
31 * in case the operation failed we don't want
32 * to overwrite the dp member of a.
33 */
34 tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
35 if (tmp == NULL) {
36 /* reallocation failed but "a" is still valid [can be freed] */
37 return MP_MEM;
38 }
39
40 /* reallocation succeeded so set a->dp */
41 a->dp = tmp;
42
43 /* zero excess digits */
44 i = a->alloc;
45 a->alloc = size;
46 for (; i < a->alloc; i++) {
47 a->dp[i] = 0;
48 }
49 }
50 return MP_OKAY;
51 }
52 #endif
53
54 /* $Source$ */
55 /* $Revision$ */
56 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_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 /* init a new mp_int */
18 int mp_init (mp_int * a)
19 {
20 int i;
21
22 /* allocate memory required and clear it */
23 a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
24 if (a->dp == NULL) {
25 return MP_MEM;
26 }
27
28 /* set the digits to zero */
29 for (i = 0; i < MP_PREC; i++) {
30 a->dp[i] = 0;
31 }
32
33 /* set the used to zero, allocated digits to the default precision
34 * and sign to positive */
35 a->used = 0;
36 a->alloc = MP_PREC;
37 a->sign = MP_ZPOS;
38
39 return MP_OKAY;
40 }
41 #endif
42
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_COPY_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 /* creates "a" then copies b into it */
18 int mp_init_copy (mp_int * a, mp_int * b)
19 {
20 int res;
21
22 if ((res = mp_init (a)) != MP_OKAY) {
23 return res;
24 }
25 return mp_copy (b, a);
26 }
27 #endif
28
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_MULTI_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 #include <stdarg.h>
17
18 int mp_init_multi(mp_int *mp, ...)
19 {
20 mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
21 int n = 0; /* Number of ok inits */
22 mp_int* cur_arg = mp;
23 va_list args;
24
25 va_start(args, mp); /* init args to next argument from caller */
26 while (cur_arg != NULL) {
27 if (mp_init(cur_arg) != MP_OKAY) {
28 /* Oops - error! Back-track and mp_clear what we already
29 succeeded in init-ing, then return error.
30 */
31 va_list clean_args;
32
33 /* end the current list */
34 va_end(args);
35
36 /* now start cleaning up */
37 cur_arg = mp;
38 va_start(clean_args, mp);
39 while (n--) {
40 mp_clear(cur_arg);
41 cur_arg = va_arg(clean_args, mp_int*);
42 }
43 va_end(clean_args);
44 res = MP_MEM;
45 break;
46 }
47 n++;
48 cur_arg = va_arg(args, mp_int*);
49 }
50 va_end(args);
51 return res; /* Assumed ok, if error flagged above. */
52 }
53
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_SET_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 /* initialize and set a digit */
18 int mp_init_set (mp_int * a, mp_digit b)
19 {
20 int err;
21 if ((err = mp_init(a)) != MP_OKAY) {
22 return err;
23 }
24 mp_set(a, b);
25 return err;
26 }
27 #endif
28
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_SET_INT_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 /* initialize and set a digit */
18 int mp_init_set_int (mp_int * a, unsigned long b)
19 {
20 int err;
21 if ((err = mp_init(a)) != MP_OKAY) {
22 return err;
23 }
24 return mp_set_int(a, b);
25 }
26 #endif
27
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_INIT_SIZE_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 /* init an mp_init for a given size */
18 int mp_init_size (mp_int * a, int size)
19 {
20 int x;
21
22 /* pad size so there are always extra digits */
23 size += (MP_PREC * 2) - (size % MP_PREC);
24
25 /* alloc mem */
26 a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
27 if (a->dp == NULL) {
28 return MP_MEM;
29 }
30
31 /* set the members */
32 a->used = 0;
33 a->alloc = size;
34 a->sign = MP_ZPOS;
35
36 /* zero the digits */
37 for (x = 0; x < size; x++) {
38 a->dp[x] = 0;
39 }
40
41 return MP_OKAY;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_INVMOD_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 /* hac 14.61, pp608 */
18 int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
19 {
20 /* b cannot be negative */
21 if (b->sign == MP_NEG || mp_iszero(b) == 1) {
22 return MP_VAL;
23 }
24
25 #ifdef BN_FAST_MP_INVMOD_C
26 /* if the modulus is odd we can use a faster routine instead */
27 if (mp_isodd (b) == 1) {
28 return fast_mp_invmod (a, b, c);
29 }
30 #endif
31
32 #ifdef BN_MP_INVMOD_SLOW_C
33 return mp_invmod_slow(a, b, c);
34 #endif
35
36 return MP_VAL;
37 }
38 #endif
39
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_INVMOD_SLOW_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 /* hac 14.61, pp608 */
18 int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
19 {
20 mp_int x, y, u, v, A, B, C, D;
21 int res;
22
23 /* b cannot be negative */
24 if (b->sign == MP_NEG || mp_iszero(b) == 1) {
25 return MP_VAL;
26 }
27
28 /* init temps */
29 if ((res = mp_init_multi(&x, &y, &u, &v,
30 &A, &B, &C, &D, NULL)) != MP_OKAY) {
31 return res;
32 }
33
34 /* x = a, y = b */
35 if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
36 goto LBL_ERR;
37 }
38 if ((res = mp_copy (b, &y)) != MP_OKAY) {
39 goto LBL_ERR;
40 }
41
42 /* 2. [modified] if x,y are both even then return an error! */
43 if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
44 res = MP_VAL;
45 goto LBL_ERR;
46 }
47
48 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
49 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
50 goto LBL_ERR;
51 }
52 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 mp_set (&A, 1);
56 mp_set (&D, 1);
57
58 top:
59 /* 4. while u is even do */
60 while (mp_iseven (&u) == 1) {
61 /* 4.1 u = u/2 */
62 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
63 goto LBL_ERR;
64 }
65 /* 4.2 if A or B is odd then */
66 if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
67 /* A = (A+y)/2, B = (B-x)/2 */
68 if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
69 goto LBL_ERR;
70 }
71 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
72 goto LBL_ERR;
73 }
74 }
75 /* A = A/2, B = B/2 */
76 if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
77 goto LBL_ERR;
78 }
79 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
80 goto LBL_ERR;
81 }
82 }
83
84 /* 5. while v is even do */
85 while (mp_iseven (&v) == 1) {
86 /* 5.1 v = v/2 */
87 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
88 goto LBL_ERR;
89 }
90 /* 5.2 if C or D is odd then */
91 if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
92 /* C = (C+y)/2, D = (D-x)/2 */
93 if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
94 goto LBL_ERR;
95 }
96 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
97 goto LBL_ERR;
98 }
99 }
100 /* C = C/2, D = D/2 */
101 if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
102 goto LBL_ERR;
103 }
104 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
105 goto LBL_ERR;
106 }
107 }
108
109 /* 6. if u >= v then */
110 if (mp_cmp (&u, &v) != MP_LT) {
111 /* u = u - v, A = A - C, B = B - D */
112 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
113 goto LBL_ERR;
114 }
115
116 if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
117 goto LBL_ERR;
118 }
119
120 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
121 goto LBL_ERR;
122 }
123 } else {
124 /* v - v - u, C = C - A, D = D - B */
125 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
126 goto LBL_ERR;
127 }
128
129 if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
130 goto LBL_ERR;
131 }
132
133 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
134 goto LBL_ERR;
135 }
136 }
137
138 /* if not zero goto step 4 */
139 if (mp_iszero (&u) == 0)
140 goto top;
141
142 /* now a = C, b = D, gcd == g*v */
143
144 /* if v != 1 then there is no inverse */
145 if (mp_cmp_d (&v, 1) != MP_EQ) {
146 res = MP_VAL;
147 goto LBL_ERR;
148 }
149
150 /* if its too low */
151 while (mp_cmp_d(&C, 0) == MP_LT) {
152 if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
153 goto LBL_ERR;
154 }
155 }
156
157 /* too big */
158 while (mp_cmp_mag(&C, b) != MP_LT) {
159 if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
160 goto LBL_ERR;
161 }
162 }
163
164 /* C is now the inverse */
165 mp_exch (&C, c);
166 res = MP_OKAY;
167 LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
168 return res;
169 }
170 #endif
171
172 /* $Source$ */
173 /* $Revision$ */
174 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_IS_SQUARE_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 /* Check if remainders are possible squares - fast exclude non-squares */
18 static const char rem_128[128] = {
19 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
20 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
21 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
22 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
23 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
24 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
25 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
26 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
27 };
28
29 static const char rem_105[105] = {
30 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
31 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
32 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
33 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
34 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
35 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
36 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
37 };
38
39 /* Store non-zero to ret if arg is square, and zero if not */
40 int mp_is_square(mp_int *arg,int *ret)
41 {
42 int res;
43 mp_digit c;
44 mp_int t;
45 unsigned long r;
46
47 /* Default to Non-square :) */
48 *ret = MP_NO;
49
50 if (arg->sign == MP_NEG) {
51 return MP_VAL;
52 }
53
54 /* digits used? (TSD) */
55 if (arg->used == 0) {
56 return MP_OKAY;
57 }
58
59 /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
60 if (rem_128[127 & DIGIT(arg,0)] == 1) {
61 return MP_OKAY;
62 }
63
64 /* Next check mod 105 (3*5*7) */
65 if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
66 return res;
67 }
68 if (rem_105[c] == 1) {
69 return MP_OKAY;
70 }
71
72
73 if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
74 return res;
75 }
76 if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
77 goto ERR;
78 }
79 r = mp_get_int(&t);
80 /* Check for other prime modules, note it's not an ERROR but we must
81 * free "t" so the easiest way is to goto ERR. We know that res
82 * is already equal to MP_OKAY from the mp_mod call
83 */
84 if ( (1L<<(r%11)) & 0x5C4L ) goto ERR;
85 if ( (1L<<(r%13)) & 0x9E4L ) goto ERR;
86 if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR;
87 if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR;
88 if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR;
89 if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR;
90 if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR;
91
92 /* Final check - is sqr(sqrt(arg)) == arg ? */
93 if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
94 goto ERR;
95 }
96 if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
97 goto ERR;
98 }
99
100 *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
101 ERR:mp_clear(&t);
102 return res;
103 }
104 #endif
105
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_JACOBI_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 /* computes the jacobi c = (a | n) (or Legendre if n is prime)
18 * HAC pp. 73 Algorithm 2.149
19 */
20 int mp_jacobi (mp_int * a, mp_int * p, int *c)
21 {
22 mp_int a1, p1;
23 int k, s, r, res;
24 mp_digit residue;
25
26 /* if p <= 0 return MP_VAL */
27 if (mp_cmp_d(p, 0) != MP_GT) {
28 return MP_VAL;
29 }
30
31 /* step 1. if a == 0, return 0 */
32 if (mp_iszero (a) == 1) {
33 *c = 0;
34 return MP_OKAY;
35 }
36
37 /* step 2. if a == 1, return 1 */
38 if (mp_cmp_d (a, 1) == MP_EQ) {
39 *c = 1;
40 return MP_OKAY;
41 }
42
43 /* default */
44 s = 0;
45
46 /* step 3. write a = a1 * 2**k */
47 if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
48 return res;
49 }
50
51 if ((res = mp_init (&p1)) != MP_OKAY) {
52 goto LBL_A1;
53 }
54
55 /* divide out larger power of two */
56 k = mp_cnt_lsb(&a1);
57 if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
58 goto LBL_P1;
59 }
60
61 /* step 4. if e is even set s=1 */
62 if ((k & 1) == 0) {
63 s = 1;
64 } else {
65 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
66 residue = p->dp[0] & 7;
67
68 if (residue == 1 || residue == 7) {
69 s = 1;
70 } else if (residue == 3 || residue == 5) {
71 s = -1;
72 }
73 }
74
75 /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
76 if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
77 s = -s;
78 }
79
80 /* if a1 == 1 we're done */
81 if (mp_cmp_d (&a1, 1) == MP_EQ) {
82 *c = s;
83 } else {
84 /* n1 = n mod a1 */
85 if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) {
86 goto LBL_P1;
87 }
88 if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
89 goto LBL_P1;
90 }
91 *c = s * r;
92 }
93
94 /* done */
95 res = MP_OKAY;
96 LBL_P1:mp_clear (&p1);
97 LBL_A1:mp_clear (&a1);
98 return res;
99 }
100 #endif
101
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_KARATSUBA_MUL_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 /* c = |a| * |b| using Karatsuba Multiplication using
18 * three half size multiplications
19 *
20 * Let B represent the radix [e.g. 2**DIGIT_BIT] and
21 * let n represent half of the number of digits in
22 * the min(a,b)
23 *
24 * a = a1 * B**n + a0
25 * b = b1 * B**n + b0
26 *
27 * Then, a * b =>
28 a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
29 *
30 * Note that a1b1 and a0b0 are used twice and only need to be
31 * computed once. So in total three half size (half # of
32 * digit) multiplications are performed, a0b0, a1b1 and
33 * (a1+b1)(a0+b0)
34 *
35 * Note that a multiplication of half the digits requires
36 * 1/4th the number of single precision multiplications so in
37 * total after one call 25% of the single precision multiplications
38 * are saved. Note also that the call to mp_mul can end up back
39 * in this function if the a0, a1, b0, or b1 are above the threshold.
40 * This is known as divide-and-conquer and leads to the famous
41 * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
42 * the standard O(N**2) that the baseline/comba methods use.
43 * Generally though the overhead of this method doesn't pay off
44 * until a certain size (N ~ 80) is reached.
45 */
46 int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
47 {
48 mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
49 int B, err;
50
51 /* default the return code to an error */
52 err = MP_MEM;
53
54 /* min # of digits */
55 B = MIN (a->used, b->used);
56
57 /* now divide in two */
58 B = B >> 1;
59
60 /* init copy all the temps */
61 if (mp_init_size (&x0, B) != MP_OKAY)
62 goto ERR;
63 if (mp_init_size (&x1, a->used - B) != MP_OKAY)
64 goto X0;
65 if (mp_init_size (&y0, B) != MP_OKAY)
66 goto X1;
67 if (mp_init_size (&y1, b->used - B) != MP_OKAY)
68 goto Y0;
69
70 /* init temps */
71 if (mp_init_size (&t1, B * 2) != MP_OKAY)
72 goto Y1;
73 if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
74 goto T1;
75 if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
76 goto X0Y0;
77
78 /* now shift the digits */
79 x0.used = y0.used = B;
80 x1.used = a->used - B;
81 y1.used = b->used - B;
82
83 {
84 register int x;
85 register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
86
87 /* we copy the digits directly instead of using higher level functions
88 * since we also need to shift the digits
89 */
90 tmpa = a->dp;
91 tmpb = b->dp;
92
93 tmpx = x0.dp;
94 tmpy = y0.dp;
95 for (x = 0; x < B; x++) {
96 *tmpx++ = *tmpa++;
97 *tmpy++ = *tmpb++;
98 }
99
100 tmpx = x1.dp;
101 for (x = B; x < a->used; x++) {
102 *tmpx++ = *tmpa++;
103 }
104
105 tmpy = y1.dp;
106 for (x = B; x < b->used; x++) {
107 *tmpy++ = *tmpb++;
108 }
109 }
110
111 /* only need to clamp the lower words since by definition the
112 * upper words x1/y1 must have a known number of digits
113 */
114 mp_clamp (&x0);
115 mp_clamp (&y0);
116
117 /* now calc the products x0y0 and x1y1 */
118 /* after this x0 is no longer required, free temp [x0==t2]! */
119 if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)
120 goto X1Y1; /* x0y0 = x0*y0 */
121 if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
122 goto X1Y1; /* x1y1 = x1*y1 */
123
124 /* now calc x1+x0 and y1+y0 */
125 if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
126 goto X1Y1; /* t1 = x1 - x0 */
127 if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
128 goto X1Y1; /* t2 = y1 - y0 */
129 if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
130 goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */
131
132 /* add x0y0 */
133 if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
134 goto X1Y1; /* t2 = x0y0 + x1y1 */
135 if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
136 goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
137
138 /* shift by B */
139 if (mp_lshd (&t1, B) != MP_OKAY)
140 goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
141 if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
142 goto X1Y1; /* x1y1 = x1y1 << 2*B */
143
144 if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
145 goto X1Y1; /* t1 = x0y0 + t1 */
146 if (mp_add (&t1, &x1y1, c) != MP_OKAY)
147 goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
148
149 /* Algorithm succeeded set the return code to MP_OKAY */
150 err = MP_OKAY;
151
152 X1Y1:mp_clear (&x1y1);
153 X0Y0:mp_clear (&x0y0);
154 T1:mp_clear (&t1);
155 Y1:mp_clear (&y1);
156 Y0:mp_clear (&y0);
157 X1:mp_clear (&x1);
158 X0:mp_clear (&x0);
159 ERR:
160 return err;
161 }
162 #endif
163
164 /* $Source$ */
165 /* $Revision$ */
166 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_KARATSUBA_SQR_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 /* Karatsuba squaring, computes b = a*a using three
18 * half size squarings
19 *
20 * See comments of karatsuba_mul for details. It
21 * is essentially the same algorithm but merely
22 * tuned to perform recursive squarings.
23 */
24 int mp_karatsuba_sqr (mp_int * a, mp_int * b)
25 {
26 mp_int x0, x1, t1, t2, x0x0, x1x1;
27 int B, err;
28
29 err = MP_MEM;
30
31 /* min # of digits */
32 B = a->used;
33
34 /* now divide in two */
35 B = B >> 1;
36
37 /* init copy all the temps */
38 if (mp_init_size (&x0, B) != MP_OKAY)
39 goto ERR;
40 if (mp_init_size (&x1, a->used - B) != MP_OKAY)
41 goto X0;
42
43 /* init temps */
44 if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
45 goto X1;
46 if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
47 goto T1;
48 if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
49 goto T2;
50 if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
51 goto X0X0;
52
53 {
54 register int x;
55 register mp_digit *dst, *src;
56
57 src = a->dp;
58
59 /* now shift the digits */
60 dst = x0.dp;
61 for (x = 0; x < B; x++) {
62 *dst++ = *src++;
63 }
64
65 dst = x1.dp;
66 for (x = B; x < a->used; x++) {
67 *dst++ = *src++;
68 }
69 }
70
71 x0.used = B;
72 x1.used = a->used - B;
73
74 mp_clamp (&x0);
75
76 /* now calc the products x0*x0 and x1*x1 */
77 if (mp_sqr (&x0, &x0x0) != MP_OKAY)
78 goto X1X1; /* x0x0 = x0*x0 */
79 if (mp_sqr (&x1, &x1x1) != MP_OKAY)
80 goto X1X1; /* x1x1 = x1*x1 */
81
82 /* now calc (x1+x0)**2 */
83 if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
84 goto X1X1; /* t1 = x1 - x0 */
85 if (mp_sqr (&t1, &t1) != MP_OKAY)
86 goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
87
88 /* add x0y0 */
89 if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
90 goto X1X1; /* t2 = x0x0 + x1x1 */
91 if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
92 goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
93
94 /* shift by B */
95 if (mp_lshd (&t1, B) != MP_OKAY)
96 goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
97 if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
98 goto X1X1; /* x1x1 = x1x1 << 2*B */
99
100 if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
101 goto X1X1; /* t1 = x0x0 + t1 */
102 if (mp_add (&t1, &x1x1, b) != MP_OKAY)
103 goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
104
105 err = MP_OKAY;
106
107 X1X1:mp_clear (&x1x1);
108 X0X0:mp_clear (&x0x0);
109 T2:mp_clear (&t2);
110 T1:mp_clear (&t1);
111 X1:mp_clear (&x1);
112 X0:mp_clear (&x0);
113 ERR:
114 return err;
115 }
116 #endif
117
118 /* $Source$ */
119 /* $Revision$ */
120 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_LCM_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 /* computes least common multiple as |a*b|/(a, b) */
18 int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
19 {
20 int res;
21 mp_int t1, t2;
22
23
24 if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
25 return res;
26 }
27
28 /* t1 = get the GCD of the two inputs */
29 if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
30 goto LBL_T;
31 }
32
33 /* divide the smallest by the GCD */
34 if (mp_cmp_mag(a, b) == MP_LT) {
35 /* store quotient in t2 such that t2 * b is the LCM */
36 if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
37 goto LBL_T;
38 }
39 res = mp_mul(b, &t2, c);
40 } else {
41 /* store quotient in t2 such that t2 * a is the LCM */
42 if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
43 goto LBL_T;
44 }
45 res = mp_mul(a, &t2, c);
46 }
47
48 /* fix the sign to positive */
49 c->sign = MP_ZPOS;
50
51 LBL_T:
52 mp_clear_multi (&t1, &t2, NULL);
53 return res;
54 }
55 #endif
56
57 /* $Source$ */
58 /* $Revision$ */
59 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_LSHD_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 /* shift left a certain amount of digits */
18 int mp_lshd (mp_int * a, int b)
19 {
20 int x, res;
21
22 /* if its less than zero return */
23 if (b <= 0) {
24 return MP_OKAY;
25 }
26
27 /* grow to fit the new digits */
28 if (a->alloc < a->used + b) {
29 if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
30 return res;
31 }
32 }
33
34 {
35 register mp_digit *top, *bottom;
36
37 /* increment the used by the shift amount then copy upwards */
38 a->used += b;
39
40 /* top */
41 top = a->dp + a->used - 1;
42
43 /* base */
44 bottom = a->dp + a->used - 1 - b;
45
46 /* much like mp_rshd this is implemented using a sliding window
47 * except the window goes the otherway around. Copying from
48 * the bottom to the top. see bn_mp_rshd.c for more info.
49 */
50 for (x = a->used - 1; x >= b; x--) {
51 *top-- = *bottom--;
52 }
53
54 /* zero the lower digits */
55 top = a->dp;
56 for (x = 0; x < b; x++) {
57 *top++ = 0;
58 }
59 }
60 return MP_OKAY;
61 }
62 #endif
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MOD_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 /* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */
18 int
19 mp_mod (mp_int * a, mp_int * b, mp_int * c)
20 {
21 mp_int t;
22 int res;
23
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
27
28 if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
32
33 if (mp_iszero(&t) || t.sign == b->sign) {
34 res = MP_OKAY;
35 mp_exch (&t, c);
36 } else {
37 res = mp_add (b, &t, c);
38 }
39
40 mp_clear (&t);
41 return res;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MOD_2D_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 /* calc a value mod 2**b */
18 int
19 mp_mod_2d (mp_int * a, int b, mp_int * c)
20 {
21 int x, res;
22
23 /* if b is <= 0 then zero the int */
24 if (b <= 0) {
25 mp_zero (c);
26 return MP_OKAY;
27 }
28
29 /* if the modulus is larger than the value than return */
30 if (b >= (int) (a->used * DIGIT_BIT)) {
31 res = mp_copy (a, c);
32 return res;
33 }
34
35 /* copy */
36 if ((res = mp_copy (a, c)) != MP_OKAY) {
37 return res;
38 }
39
40 /* zero digits above the last digit of the modulus */
41 for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
42 c->dp[x] = 0;
43 }
44 /* clear the digit that is not completely outside/inside the modulus */
45 c->dp[b / DIGIT_BIT] &=
46 (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
47 mp_clamp (c);
48 return MP_OKAY;
49 }
50 #endif
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MOD_D_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 int
18 mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
19 {
20 return mp_div_d(a, b, NULL, c);
21 }
22 #endif
23
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_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 /*
18 * shifts with subtractions when the result is greater than b.
19 *
20 * The method is slightly modified to shift B unconditionally upto just under
21 * the leading bit of b. This saves alot of multiple precision shifting.
22 */
23 int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
24 {
25 int x, bits, res;
26
27 /* how many bits of last digit does b use */
28 bits = mp_count_bits (b) % DIGIT_BIT;
29
30 if (b->used > 1) {
31 if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
32 return res;
33 }
34 } else {
35 mp_set(a, 1);
36 bits = 1;
37 }
38
39
40 /* now compute C = A * B mod b */
41 for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
42 if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
43 return res;
44 }
45 if (mp_cmp_mag (a, b) != MP_LT) {
46 if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
47 return res;
48 }
49 }
50 }
51
52 return MP_OKAY;
53 }
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MONTGOMERY_REDUCE_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 /* computes xR**-1 == x (mod N) via Montgomery Reduction */
18 int
19 mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
20 {
21 int ix, res, digs;
22 mp_digit mu;
23
24 /* can the fast reduction [comba] method be used?
25 *
26 * Note that unlike in mul you're safely allowed *less*
27 * than the available columns [255 per default] since carries
28 * are fixed up in the inner loop.
29 */
30 digs = n->used * 2 + 1;
31 if ((digs < MP_WARRAY) &&
32 n->used <
33 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
34 return fast_mp_montgomery_reduce (x, n, rho);
35 }
36
37 /* grow the input as required */
38 if (x->alloc < digs) {
39 if ((res = mp_grow (x, digs)) != MP_OKAY) {
40 return res;
41 }
42 }
43 x->used = digs;
44
45 for (ix = 0; ix < n->used; ix++) {
46 /* mu = ai * rho mod b
47 *
48 * The value of rho must be precalculated via
49 * montgomery_setup() such that
50 * it equals -1/n0 mod b this allows the
51 * following inner loop to reduce the
52 * input one digit at a time
53 */
54 mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
55
56 /* a = a + mu * m * b**i */
57 {
58 register int iy;
59 register mp_digit *tmpn, *tmpx, u;
60 register mp_word r;
61
62 /* alias for digits of the modulus */
63 tmpn = n->dp;
64
65 /* alias for the digits of x [the input] */
66 tmpx = x->dp + ix;
67
68 /* set the carry to zero */
69 u = 0;
70
71 /* Multiply and add in place */
72 for (iy = 0; iy < n->used; iy++) {
73 /* compute product and sum */
74 r = ((mp_word)mu) * ((mp_word)*tmpn++) +
75 ((mp_word) u) + ((mp_word) * tmpx);
76
77 /* get carry */
78 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
79
80 /* fix digit */
81 *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
82 }
83 /* At this point the ix'th digit of x should be zero */
84
85
86 /* propagate carries upwards as required*/
87 while (u) {
88 *tmpx += u;
89 u = *tmpx >> DIGIT_BIT;
90 *tmpx++ &= MP_MASK;
91 }
92 }
93 }
94
95 /* at this point the n.used'th least
96 * significant digits of x are all zero
97 * which means we can shift x to the
98 * right by n.used digits and the
99 * residue is unchanged.
100 */
101
102 /* x = x/b**n.used */
103 mp_clamp(x);
104 mp_rshd (x, n->used);
105
106 /* if x >= n then x = x - n */
107 if (mp_cmp_mag (x, n) != MP_LT) {
108 return s_mp_sub (x, n, x);
109 }
110
111 return MP_OKAY;
112 }
113 #endif
114
115 /* $Source$ */
116 /* $Revision$ */
117 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MONTGOMERY_SETUP_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 /* setups the montgomery reduction stuff */
18 int
19 mp_montgomery_setup (mp_int * n, mp_digit * rho)
20 {
21 mp_digit x, b;
22
23 /* fast inversion mod 2**k
24 *
25 * Based on the fact that
26 *
27 * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
28 * => 2*X*A - X*X*A*A = 1
29 * => 2*(1) - (1) = 1
30 */
31 b = n->dp[0];
32
33 if ((b & 1) == 0) {
34 return MP_VAL;
35 }
36
37 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
38 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
39 #if !defined(MP_8BIT)
40 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
41 #endif
42 #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
43 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
44 #endif
45 #ifdef MP_64BIT
46 x *= 2 - b * x; /* here x*a==1 mod 2**64 */
47 #endif
48
49 /* rho = -1/m mod b */
50 *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
51
52 return MP_OKAY;
53 }
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MUL_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 /* high level multiplication (handles sign) */
18 int mp_mul (mp_int * a, mp_int * b, mp_int * c)
19 {
20 int res, neg;
21 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
22
23 /* use Toom-Cook? */
24 #ifdef BN_MP_TOOM_MUL_C
25 if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
26 res = mp_toom_mul(a, b, c);
27 } else
28 #endif
29 #ifdef BN_MP_KARATSUBA_MUL_C
30 /* use Karatsuba? */
31 if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
32 res = mp_karatsuba_mul (a, b, c);
33 } else
34 #endif
35 {
36 /* can we use the fast multiplier?
37 *
38 * The fast multiplier can be used if the output will
39 * have less than MP_WARRAY digits and the number of
40 * digits won't affect carry propagation
41 */
42 int digs = a->used + b->used + 1;
43
44 #ifdef BN_FAST_S_MP_MUL_DIGS_C
45 if ((digs < MP_WARRAY) &&
46 MIN(a->used, b->used) <=
47 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
48 res = fast_s_mp_mul_digs (a, b, c, digs);
49 } else
50 #endif
51 #ifdef BN_S_MP_MUL_DIGS_C
52 res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
53 #else
54 res = MP_VAL;
55 #endif
56
57 }
58 c->sign = (c->used > 0) ? neg : MP_ZPOS;
59 return res;
60 }
61 #endif
62
63 /* $Source$ */
64 /* $Revision$ */
65 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MUL_2_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 /* b = a*2 */
18 int mp_mul_2(mp_int * a, mp_int * b)
19 {
20 int x, res, oldused;
21
22 /* grow to accomodate result */
23 if (b->alloc < a->used + 1) {
24 if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
25 return res;
26 }
27 }
28
29 oldused = b->used;
30 b->used = a->used;
31
32 {
33 register mp_digit r, rr, *tmpa, *tmpb;
34
35 /* alias for source */
36 tmpa = a->dp;
37
38 /* alias for dest */
39 tmpb = b->dp;
40
41 /* carry */
42 r = 0;
43 for (x = 0; x < a->used; x++) {
44
45 /* get what will be the *next* carry bit from the
46 * MSB of the current digit
47 */
48 rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
49
50 /* now shift up this digit, add in the carry [from the previous] */
51 *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
52
53 /* copy the carry that would be from the source
54 * digit into the next iteration
55 */
56 r = rr;
57 }
58
59 /* new leading digit? */
60 if (r != 0) {
61 /* add a MSB which is always 1 at this point */
62 *tmpb = 1;
63 ++(b->used);
64 }
65
66 /* now zero any excess digits on the destination
67 * that we didn't write to
68 */
69 tmpb = b->dp + b->used;
70 for (x = b->used; x < oldused; x++) {
71 *tmpb++ = 0;
72 }
73 }
74 b->sign = a->sign;
75 return MP_OKAY;
76 }
77 #endif
78
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MUL_2D_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 /* shift left by a certain bit count */
18 int mp_mul_2d (mp_int * a, int b, mp_int * c)
19 {
20 mp_digit d;
21 int res;
22
23 /* copy */
24 if (a != c) {
25 if ((res = mp_copy (a, c)) != MP_OKAY) {
26 return res;
27 }
28 }
29
30 if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
31 if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
32 return res;
33 }
34 }
35
36 /* shift by as many digits in the bit count */
37 if (b >= (int)DIGIT_BIT) {
38 if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
39 return res;
40 }
41 }
42
43 /* shift any bit count < DIGIT_BIT */
44 d = (mp_digit) (b % DIGIT_BIT);
45 if (d != 0) {
46 register mp_digit *tmpc, shift, mask, r, rr;
47 register int x;
48
49 /* bitmask for carries */
50 mask = (((mp_digit)1) << d) - 1;
51
52 /* shift for msbs */
53 shift = DIGIT_BIT - d;
54
55 /* alias */
56 tmpc = c->dp;
57
58 /* carry */
59 r = 0;
60 for (x = 0; x < c->used; x++) {
61 /* get the higher bits of the current word */
62 rr = (*tmpc >> shift) & mask;
63
64 /* shift the current word and OR in the carry */
65 *tmpc = ((*tmpc << d) | r) & MP_MASK;
66 ++tmpc;
67
68 /* set the carry to the carry bits of the current word */
69 r = rr;
70 }
71
72 /* set final carry */
73 if (r != 0) {
74 c->dp[(c->used)++] = r;
75 }
76 }
77 mp_clamp (c);
78 return MP_OKAY;
79 }
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MUL_D_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 /* multiply by a digit */
18 int
19 mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
20 {
21 mp_digit u, *tmpa, *tmpc;
22 mp_word r;
23 int ix, res, olduse;
24
25 /* make sure c is big enough to hold a*b */
26 if (c->alloc < a->used + 1) {
27 if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
28 return res;
29 }
30 }
31
32 /* get the original destinations used count */
33 olduse = c->used;
34
35 /* set the sign */
36 c->sign = a->sign;
37
38 /* alias for a->dp [source] */
39 tmpa = a->dp;
40
41 /* alias for c->dp [dest] */
42 tmpc = c->dp;
43
44 /* zero carry */
45 u = 0;
46
47 /* compute columns */
48 for (ix = 0; ix < a->used; ix++) {
49 /* compute product and carry sum for this term */
50 r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
51
52 /* mask off higher bits to get a single digit */
53 *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
54
55 /* send carry into next iteration */
56 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
57 }
58
59 /* store final carry [if any] and increment ix offset */
60 *tmpc++ = u;
61 ++ix;
62
63 /* now zero digits above the top */
64 while (ix++ < olduse) {
65 *tmpc++ = 0;
66 }
67
68 /* set used count */
69 c->used = a->used + 1;
70 mp_clamp(c);
71
72 return MP_OKAY;
73 }
74 #endif
75
76 /* $Source$ */
77 /* $Revision$ */
78 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_MULMOD_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 /* d = a * b (mod c) */
18 int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
19 {
20 int res;
21 mp_int t;
22
23 if ((res = mp_init (&t)) != MP_OKAY) {
24 return res;
25 }
26
27 if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
28 mp_clear (&t);
29 return res;
30 }
31 res = mp_mod (&t, c, d);
32 mp_clear (&t);
33 return res;
34 }
35 #endif
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_N_ROOT_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 (mp_int * a, mp_digit b, mp_int * c)
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 (&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 #endif
128
129 /* $Source$ */
130 /* $Revision$ */
131 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_NEG_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 /* b = -a */
18 int mp_neg (mp_int * a, mp_int * b)
19 {
20 int res;
21 if (a != b) {
22 if ((res = mp_copy (a, b)) != MP_OKAY) {
23 return res;
24 }
25 }
26
27 if (mp_iszero(b) != MP_YES) {
28 b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
29 } else {
30 b->sign = MP_ZPOS;
31 }
32
33 return MP_OKAY;
34 }
35 #endif
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_OR_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 /* OR two ints together */
18 int mp_or (mp_int * a, mp_int * b, mp_int * c)
19 {
20 int res, ix, px;
21 mp_int t, *x;
22
23 if (a->used > b->used) {
24 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
25 return res;
26 }
27 px = b->used;
28 x = b;
29 } else {
30 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
31 return res;
32 }
33 px = a->used;
34 x = a;
35 }
36
37 for (ix = 0; ix < px; ix++) {
38 t.dp[ix] |= x->dp[ix];
39 }
40 mp_clamp (&t);
41 mp_exch (c, &t);
42 mp_clear (&t);
43 return MP_OKAY;
44 }
45 #endif
46
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_FERMAT_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 /* performs one Fermat test.
18 *
19 * If "a" were prime then b**a == b (mod a) since the order of
20 * the multiplicative sub-group would be phi(a) = a-1. That means
21 * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
22 *
23 * Sets result to 1 if the congruence holds, or zero otherwise.
24 */
25 int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
26 {
27 mp_int t;
28 int err;
29
30 /* default to composite */
31 *result = MP_NO;
32
33 /* ensure b > 1 */
34 if (mp_cmp_d(b, 1) != MP_GT) {
35 return MP_VAL;
36 }
37
38 /* init t */
39 if ((err = mp_init (&t)) != MP_OKAY) {
40 return err;
41 }
42
43 /* compute t = b**a mod a */
44 if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
45 goto LBL_T;
46 }
47
48 /* is it equal to b? */
49 if (mp_cmp (&t, b) == MP_EQ) {
50 *result = MP_YES;
51 }
52
53 err = MP_OKAY;
54 LBL_T:mp_clear (&t);
55 return err;
56 }
57 #endif
58
59 /* $Source$ */
60 /* $Revision$ */
61 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_IS_DIVISIBLE_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 /* determines if an integers is divisible by one
18 * of the first PRIME_SIZE primes or not
19 *
20 * sets result to 0 if not, 1 if yes
21 */
22 int mp_prime_is_divisible (mp_int * a, int *result)
23 {
24 int err, ix;
25 mp_digit res;
26
27 /* default to not */
28 *result = MP_NO;
29
30 for (ix = 0; ix < PRIME_SIZE; ix++) {
31 /* what is a mod LBL_prime_tab[ix] */
32 if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
33 return err;
34 }
35
36 /* is the residue zero? */
37 if (res == 0) {
38 *result = MP_YES;
39 return MP_OKAY;
40 }
41 }
42
43 return MP_OKAY;
44 }
45 #endif
46
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_IS_PRIME_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 /* performs a variable number of rounds of Miller-Rabin
18 *
19 * Probability of error after t rounds is no more than
20
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)
25 {
26 mp_int b;
27 int ix, err, res;
28
29 /* default to no */
30 *result = MP_NO;
31
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) {
52 return MP_OKAY;
53 }
54
55 /* now perform the miller-rabin rounds */
56 if ((err = mp_init (&b)) != MP_OKAY) {
57 return err;
58 }
59
60 for (ix = 0; ix < t; ix++) {
61 /* set the prime */
62 mp_set (&b, ltm_prime_tab[ix]);
63
64 if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
65 goto LBL_B;
66 }
67
68 if (res == MP_NO) {
69 goto LBL_B;
70 }
71 }
72
73 /* passed the test */
74 *result = MP_YES;
75 LBL_B:mp_clear (&b);
76 return err;
77 }
78 #endif
79
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_MILLER_RABIN_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 /* Miller-Rabin test of "a" to the base of "b" as described in
18 * HAC pp. 139 Algorithm 4.24
19 *
20 * Sets result to 0 if definitely composite or 1 if probably prime.
21 * Randomly the chance of error is no more than 1/4 and often
22 * very much lower.
23 */
24 int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
25 {
26 mp_int n1, y, r;
27 int s, j, err;
28
29 /* default */
30 *result = MP_NO;
31
32 /* ensure b > 1 */
33 if (mp_cmp_d(b, 1) != MP_GT) {
34 return MP_VAL;
35 }
36
37 /* get n1 = a - 1 */
38 if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
39 return err;
40 }
41 if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
42 goto LBL_N1;
43 }
44
45 /* set 2**s * r = n1 */
46 if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
47 goto LBL_N1;
48 }
49
50 /* count the number of least significant bits
51 * which are zero
52 */
53 s = mp_cnt_lsb(&r);
54
55 /* now divide n - 1 by 2**s */
56 if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
57 goto LBL_R;
58 }
59
60 /* compute y = b**r mod a */
61 if ((err = mp_init (&y)) != MP_OKAY) {
62 goto LBL_R;
63 }
64 if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
65 goto LBL_Y;
66 }
67
68 /* if y != 1 and y != n1 do */
69 if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
70 j = 1;
71 /* while j <= s-1 and y != n1 */
72 while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
73 if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
74 goto LBL_Y;
75 }
76
77 /* if y == 1 then composite */
78 if (mp_cmp_d (&y, 1) == MP_EQ) {
79 goto LBL_Y;
80 }
81
82 ++j;
83 }
84
85 /* if y != n1 then composite */
86 if (mp_cmp (&y, &n1) != MP_EQ) {
87 goto LBL_Y;
88 }
89 }
90
91 /* probably prime now */
92 *result = MP_YES;
93 LBL_Y:mp_clear (&y);
94 LBL_R:mp_clear (&r);
95 LBL_N1:mp_clear (&n1);
96 return err;
97 }
98 #endif
99
100 /* $Source$ */
101 /* $Revision$ */
102 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_NEXT_PRIME_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 /* finds the next prime after the number "a" using "t" trials
18 * of Miller-Rabin.
19 *
20 * bbs_style = 1 means the prime must be congruent to 3 mod 4
21 */
22 int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
23 {
24 int err, res, x, y;
25 mp_digit res_tab[PRIME_SIZE], step, kstep;
26 mp_int b;
27
28 /* ensure t is valid */
29 if (t <= 0 || t > PRIME_SIZE) {
30 return MP_VAL;
31 }
32
33 /* force positive */
34 a->sign = MP_ZPOS;
35
36 /* simple algo if a is less than the largest prime in the table */
37 if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
38 /* find which prime it is bigger than */
39 for (x = PRIME_SIZE - 2; x >= 0; x--) {
40 if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
41 if (bbs_style == 1) {
42 /* ok we found a prime smaller or
43 * equal [so the next is larger]
44 *
45 * however, the prime must be
46 * congruent to 3 mod 4
47 */
48 if ((ltm_prime_tab[x + 1] & 3) != 3) {
49 /* scan upwards for a prime congruent to 3 mod 4 */
50 for (y = x + 1; y < PRIME_SIZE; y++) {
51 if ((ltm_prime_tab[y] & 3) == 3) {
52 mp_set(a, ltm_prime_tab[y]);
53 return MP_OKAY;
54 }
55 }
56 }
57 } else {
58 mp_set(a, ltm_prime_tab[x + 1]);
59 return MP_OKAY;
60 }
61 }
62 }
63 /* at this point a maybe 1 */
64 if (mp_cmp_d(a, 1) == MP_EQ) {
65 mp_set(a, 2);
66 return MP_OKAY;
67 }
68 /* fall through to the sieve */
69 }
70
71 /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
72 if (bbs_style == 1) {
73 kstep = 4;
74 } else {
75 kstep = 2;
76 }
77
78 /* at this point we will use a combination of a sieve and Miller-Rabin */
79
80 if (bbs_style == 1) {
81 /* if a mod 4 != 3 subtract the correct value to make it so */
82 if ((a->dp[0] & 3) != 3) {
83 if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
84 }
85 } else {
86 if (mp_iseven(a) == 1) {
87 /* force odd */
88 if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
89 return err;
90 }
91 }
92 }
93
94 /* generate the restable */
95 for (x = 1; x < PRIME_SIZE; x++) {
96 if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) {
97 return err;
98 }
99 }
100
101 /* init temp used for Miller-Rabin Testing */
102 if ((err = mp_init(&b)) != MP_OKAY) {
103 return err;
104 }
105
106 for (;;) {
107 /* skip to the next non-trivially divisible candidate */
108 step = 0;
109 do {
110 /* y == 1 if any residue was zero [e.g. cannot be prime] */
111 y = 0;
112
113 /* increase step to next candidate */
114 step += kstep;
115
116 /* compute the new residue without using division */
117 for (x = 1; x < PRIME_SIZE; x++) {
118 /* add the step to each residue */
119 res_tab[x] += kstep;
120
121 /* subtract the modulus [instead of using division] */
122 if (res_tab[x] >= ltm_prime_tab[x]) {
123 res_tab[x] -= ltm_prime_tab[x];
124 }
125
126 /* set flag if zero */
127 if (res_tab[x] == 0) {
128 y = 1;
129 }
130 }
131 } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep));
132
133 /* add the step */
134 if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
135 goto LBL_ERR;
136 }
137
138 /* if didn't pass sieve and step == MAX then skip test */
139 if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
140 continue;
141 }
142
143 /* is this prime? */
144 for (x = 0; x < t; x++) {
145 mp_set(&b, ltm_prime_tab[x]);
146 if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
147 goto LBL_ERR;
148 }
149 if (res == MP_NO) {
150 break;
151 }
152 }
153
154 if (res == MP_YES) {
155 break;
156 }
157 }
158
159 err = MP_OKAY;
160 LBL_ERR:
161 mp_clear(&b);
162 return err;
163 }
164
165 #endif
166
167 /* $Source$ */
168 /* $Revision$ */
169 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_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
18 static const struct {
19 int k, t;
20 } sizes[] = {
21 { 128, 28 },
22 { 256, 16 },
23 { 384, 10 },
24 { 512, 7 },
25 { 640, 6 },
26 { 768, 5 },
27 { 896, 4 },
28 { 1024, 4 }
29 };
30
31 /* returns # of RM trials required for a given bit size */
32 int mp_prime_rabin_miller_trials(int size)
33 {
34 int x;
35
36 for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
37 if (sizes[x].k == size) {
38 return sizes[x].t;
39 } else if (sizes[x].k > size) {
40 return (x == 0) ? sizes[0].t : sizes[x - 1].t;
41 }
42 }
43 return sizes[x-1].t + 1;
44 }
45
46
47 #endif
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_PRIME_RANDOM_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 /* makes a truly random prime of a given size (bits),
18 *
19 * Flags are as follows:
20 *
21 * LTM_PRIME_BBS - make prime congruent to 3 mod 4
22 * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
23 * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
24 *
25 * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
26 * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
27 * so it can be NULL
28 *
29 */
30
31 /* This is possibly the mother of all prime generation functions, muahahahahaha! */
32 int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat)
33 {
34 unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
35 int res, err, bsize, maskOR_msb_offset;
36
37 /* sanity check the input */
38 if (size <= 1 || t <= 0) {
39 return MP_VAL;
40 }
41
42 /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */
43 if (flags & LTM_PRIME_SAFE) {
44 flags |= LTM_PRIME_BBS;
45 }
46
47 /* calc the byte size */
48 bsize = (size>>3) + ((size&7)?1:0);
49
50 /* we need a buffer of bsize bytes */
51 tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
52 if (tmp == NULL) {
53 return MP_MEM;
54 }
55
56 /* calc the maskAND value for the MSbyte*/
57 maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7)));
58
59 /* calc the maskOR_msb */
60 maskOR_msb = 0;
61 maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
62 if (flags & LTM_PRIME_2MSB_ON) {
63 maskOR_msb |= 0x80 >> ((9 - size) & 7);
64 }
65
66 /* get the maskOR_lsb */
67 maskOR_lsb = 1;
68 if (flags & LTM_PRIME_BBS) {
69 maskOR_lsb |= 3;
70 }
71
72 do {
73 /* read the bytes */
74 if (cb(tmp, bsize, dat) != bsize) {
75 err = MP_VAL;
76 goto error;
77 }
78
79 /* work over the MSbyte */
80 tmp[0] &= maskAND;
81 tmp[0] |= 1 << ((size - 1) & 7);
82
83 /* mix in the maskORs */
84 tmp[maskOR_msb_offset] |= maskOR_msb;
85 tmp[bsize-1] |= maskOR_lsb;
86
87 /* read it in */
88 if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; }
89
90 /* is it prime? */
91 if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
92 if (res == MP_NO) {
93 continue;
94 }
95
96 if (flags & LTM_PRIME_SAFE) {
97 /* see if (a-1)/2 is prime */
98 if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; }
99 if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; }
100
101 /* is it prime? */
102 if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
103 }
104 } while (res == MP_NO);
105
106 if (flags & LTM_PRIME_SAFE) {
107 /* restore a to the original value */
108 if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; }
109 if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; }
110 }
111
112 err = MP_OKAY;
113 error:
114 XFREE(tmp);
115 return err;
116 }
117
118
119 #endif
120
121 /* $Source$ */
122 /* $Revision$ */
123 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_RADIX_SIZE_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 /* returns size of ASCII reprensentation */
18 int mp_radix_size (mp_int * a, int radix, int *size)
19 {
20 int res, digs;
21 mp_int t;
22 mp_digit d;
23
24 *size = 0;
25
26 /* make sure the radix is in range */
27 if (radix < 2 || radix > 64) {
28 return MP_VAL;
29 }
30
31 if (mp_iszero(a) == MP_YES) {
32 *size = 2;
33 return MP_OKAY;
34 }
35
36 /* special case for binary */
37 if (radix == 2) {
38 *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
39 return MP_OKAY;
40 }
41
42 /* digs is the digit count */
43 digs = 0;
44
45 /* if it's negative add one for the sign */
46 if (a->sign == MP_NEG) {
47 ++digs;
48 }
49
50 /* init a copy of the input */
51 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
52 return res;
53 }
54
55 /* force temp to positive */
56 t.sign = MP_ZPOS;
57
58 /* fetch out all of the digits */
59 while (mp_iszero (&t) == MP_NO) {
60 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
61 mp_clear (&t);
62 return res;
63 }
64 ++digs;
65 }
66 mp_clear (&t);
67
68 /* return digs + 1, the 1 is for the NULL byte that would be required. */
69 *size = digs + 1;
70 return MP_OKAY;
71 }
72
73 #endif
74
75 /* $Source$ */
76 /* $Revision$ */
77 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_RADIX_SMAP_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 /* chars used in radix conversions */
18 const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
19 #endif
20
21 /* $Source$ */
22 /* $Revision$ */
23 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_RAND_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 /* makes a pseudo-random int of a given size */
18 int
19 mp_rand (mp_int * a, int digits)
20 {
21 int res;
22 mp_digit d;
23
24 mp_zero (a);
25 if (digits <= 0) {
26 return MP_OKAY;
27 }
28
29 /* first place a random non-zero digit */
30 do {
31 d = ((mp_digit) abs (rand ())) & MP_MASK;
32 } while (d == 0);
33
34 if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
35 return res;
36 }
37
38 while (--digits > 0) {
39 if ((res = mp_lshd (a, 1)) != MP_OKAY) {
40 return res;
41 }
42
43 if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) {
44 return res;
45 }
46 }
47
48 return MP_OKAY;
49 }
50 #endif
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_READ_RADIX_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 /* read a string [ASCII] in a given radix */
18 int mp_read_radix (mp_int * a, const char *str, int radix)
19 {
20 int y, res, neg;
21 char ch;
22
23 /* zero the digit bignum */
24 mp_zero(a);
25
26 /* make sure the radix is ok */
27 if (radix < 2 || radix > 64) {
28 return MP_VAL;
29 }
30
31 /* if the leading digit is a
32 * minus set the sign to negative.
33 */
34 if (*str == '-') {
35 ++str;
36 neg = MP_NEG;
37 } else {
38 neg = MP_ZPOS;
39 }
40
41 /* set the integer to the default of zero */
42 mp_zero (a);
43
44 /* process each digit of the string */
45 while (*str) {
46 /* if the radix <= 36 the conversion is case insensitive
47 * this allows numbers like 1AB and 1ab to represent the same value
48 * [e.g. in hex]
49 */
50 ch = (char) ((radix <= 36) ? toupper ((int)*str) : *str);
51 for (y = 0; y < 64; y++) {
52 if (ch == mp_s_rmap[y]) {
53 break;
54 }
55 }
56
57 /* if the char was found in the map
58 * and is less than the given radix add it
59 * to the number, otherwise exit the loop.
60 */
61 if (y < radix) {
62 if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
63 return res;
64 }
65 if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
66 return res;
67 }
68 } else {
69 break;
70 }
71 ++str;
72 }
73
74 /* set the sign only if a != 0 */
75 if (mp_iszero(a) != 1) {
76 a->sign = neg;
77 }
78 return MP_OKAY;
79 }
80 #endif
81
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_READ_SIGNED_BIN_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 /* read signed bin, big endian, first byte is 0==positive or 1==negative */
18 int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c)
19 {
20 int res;
21
22 /* read magnitude */
23 if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
24 return res;
25 }
26
27 /* first byte is 0 for positive, non-zero for negative */
28 if (b[0] == 0) {
29 a->sign = MP_ZPOS;
30 } else {
31 a->sign = MP_NEG;
32 }
33
34 return MP_OKAY;
35 }
36 #endif
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_READ_UNSIGNED_BIN_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 /* reads a unsigned char array, assumes the msb is stored first [big endian] */
18 int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
19 {
20 int res;
21
22 /* make sure there are at least two digits */
23 if (a->alloc < 2) {
24 if ((res = mp_grow(a, 2)) != MP_OKAY) {
25 return res;
26 }
27 }
28
29 /* zero the int */
30 mp_zero (a);
31
32 /* read the bytes in */
33 while (c-- > 0) {
34 if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
35 return res;
36 }
37
38 #ifndef MP_8BIT
39 a->dp[0] |= *b++;
40 a->used += 1;
41 #else
42 a->dp[0] = (*b & MP_MASK);
43 a->dp[1] |= ((*b++ >> 7U) & 1);
44 a->used += 2;
45 #endif
46 }
47 mp_clamp (a);
48 return MP_OKAY;
49 }
50 #endif
51
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_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 /* reduces x mod m, assumes 0 < x < m**2, mu is
18 * precomputed via mp_reduce_setup.
19 * From HAC pp.604 Algorithm 14.42
20 */
21 int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
22 {
23 mp_int q;
24 int res, um = m->used;
25
26 /* q = x */
27 if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
28 return res;
29 }
30
31 /* q1 = x / b**(k-1) */
32 mp_rshd (&q, um - 1);
33
34 /* according to HAC this optimization is ok */
35 if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
36 if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
37 goto CLEANUP;
38 }
39 } else {
40 #ifdef BN_S_MP_MUL_HIGH_DIGS_C
41 if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
42 goto CLEANUP;
43 }
44 #elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
45 if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
46 goto CLEANUP;
47 }
48 #else
49 {
50 res = MP_VAL;
51 goto CLEANUP;
52 }
53 #endif
54 }
55
56 /* q3 = q2 / b**(k+1) */
57 mp_rshd (&q, um + 1);
58
59 /* x = x mod b**(k+1), quick (no division) */
60 if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
61 goto CLEANUP;
62 }
63
64 /* q = q * m mod b**(k+1), quick (no division) */
65 if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
66 goto CLEANUP;
67 }
68
69 /* x = x - q */
70 if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
71 goto CLEANUP;
72 }
73
74 /* If x < 0, add b**(k+1) to it */
75 if (mp_cmp_d (x, 0) == MP_LT) {
76 mp_set (&q, 1);
77 if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
78 goto CLEANUP;
79 if ((res = mp_add (x, &q, x)) != MP_OKAY)
80 goto CLEANUP;
81 }
82
83 /* Back off if it's too big */
84 while (mp_cmp (x, m) != MP_LT) {
85 if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
86 goto CLEANUP;
87 }
88 }
89
90 CLEANUP:
91 mp_clear (&q);
92
93 return res;
94 }
95 #endif
96
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_2K_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 /* reduces a modulo n where n is of the form 2**p - d */
18 int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
19 {
20 mp_int q;
21 int p, res;
22
23 if ((res = mp_init(&q)) != MP_OKAY) {
24 return res;
25 }
26
27 p = mp_count_bits(n);
28 top:
29 /* q = a/2**p, a = a mod 2**p */
30 if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
31 goto ERR;
32 }
33
34 if (d != 1) {
35 /* q = q * d */
36 if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
37 goto ERR;
38 }
39 }
40
41 /* a = a + q */
42 if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
43 goto ERR;
44 }
45
46 if (mp_cmp_mag(a, n) != MP_LT) {
47 s_mp_sub(a, n, a);
48 goto top;
49 }
50
51 ERR:
52 mp_clear(&q);
53 return res;
54 }
55
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_2K_L_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 /* reduces a modulo n where n is of the form 2**p - d
18 This differs from reduce_2k since "d" can be larger
19 than a single digit.
20 */
21 int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
22 {
23 mp_int q;
24 int p, res;
25
26 if ((res = mp_init(&q)) != MP_OKAY) {
27 return res;
28 }
29
30 p = mp_count_bits(n);
31 top:
32 /* q = a/2**p, a = a mod 2**p */
33 if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
34 goto ERR;
35 }
36
37 /* q = q * d */
38 if ((res = mp_mul(&q, d, &q)) != MP_OKAY) {
39 goto ERR;
40 }
41
42 /* a = a + q */
43 if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
44 goto ERR;
45 }
46
47 if (mp_cmp_mag(a, n) != MP_LT) {
48 s_mp_sub(a, n, a);
49 goto top;
50 }
51
52 ERR:
53 mp_clear(&q);
54 return res;
55 }
56
57 #endif
58
59 /* $Source$ */
60 /* $Revision$ */
61 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_2K_SETUP_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 /* determines the setup value */
18 int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
19 {
20 int res, p;
21 mp_int tmp;
22
23 if ((res = mp_init(&tmp)) != MP_OKAY) {
24 return res;
25 }
26
27 p = mp_count_bits(a);
28 if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
29 mp_clear(&tmp);
30 return res;
31 }
32
33 if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
34 mp_clear(&tmp);
35 return res;
36 }
37
38 *d = tmp.dp[0];
39 mp_clear(&tmp);
40 return MP_OKAY;
41 }
42 #endif
43
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_2K_SETUP_L_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 /* determines the setup value */
18 int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
19 {
20 int res;
21 mp_int tmp;
22
23 if ((res = mp_init(&tmp)) != MP_OKAY) {
24 return res;
25 }
26
27 if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
28 goto ERR;
29 }
30
31 if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
32 goto ERR;
33 }
34
35 ERR:
36 mp_clear(&tmp);
37 return res;
38 }
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_IS_2K_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 /* determines if mp_reduce_2k can be used */
18 int mp_reduce_is_2k(mp_int *a)
19 {
20 int ix, iy, iw;
21 mp_digit iz;
22
23 if (a->used == 0) {
24 return MP_NO;
25 } else if (a->used == 1) {
26 return MP_YES;
27 } else if (a->used > 1) {
28 iy = mp_count_bits(a);
29 iz = 1;
30 iw = 1;
31
32 /* Test every bit from the second digit up, must be 1 */
33 for (ix = DIGIT_BIT; ix < iy; ix++) {
34 if ((a->dp[iw] & iz) == 0) {
35 return MP_NO;
36 }
37 iz <<= 1;
38 if (iz > (mp_digit)MP_MASK) {
39 ++iw;
40 iz = 1;
41 }
42 }
43 }
44 return MP_YES;
45 }
46
47 #endif
48
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_IS_2K_L_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 /* determines if reduce_2k_l can be used */
18 int mp_reduce_is_2k_l(mp_int *a)
19 {
20 int ix, iy;
21
22 if (a->used == 0) {
23 return MP_NO;
24 } else if (a->used == 1) {
25 return MP_YES;
26 } else if (a->used > 1) {
27 /* if more than half of the digits are -1 we're sold */
28 for (iy = ix = 0; ix < a->used; ix++) {
29 if (a->dp[ix] == MP_MASK) {
30 ++iy;
31 }
32 }
33 return (iy >= (a->used/2)) ? MP_YES : MP_NO;
34
35 }
36 return MP_NO;
37 }
38
39 #endif
40
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_REDUCE_SETUP_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 /* pre-calculate the value required for Barrett reduction
18 * For a given modulus "b" it calulates the value required in "a"
19 */
20 int mp_reduce_setup (mp_int * a, mp_int * b)
21 {
22 int res;
23
24 if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
25 return res;
26 }
27 return mp_div (a, b, a, NULL);
28 }
29 #endif
30
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_RSHD_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 /* shift right a certain amount of digits */
18 void mp_rshd (mp_int * a, int b)
19 {
20 int x;
21
22 /* if b <= 0 then ignore it */
23 if (b <= 0) {
24 return;
25 }
26
27 /* if b > used then simply zero it and return */
28 if (a->used <= b) {
29 mp_zero (a);
30 return;
31 }
32
33 {
34 register mp_digit *bottom, *top;
35
36 /* shift the digits down */
37
38 /* bottom */
39 bottom = a->dp;
40
41 /* top [offset into digits] */
42 top = a->dp + b;
43
44 /* this is implemented as a sliding window where
45 * the window is b-digits long and digits from
46 * the top of the window are copied to the bottom
47 *
48 * e.g.
49
50 b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
51 /\ | ---->
52 \-------------------/ ---->
53 */
54 for (x = 0; x < (a->used - b); x++) {
55 *bottom++ = *top++;
56 }
57
58 /* zero the top digits */
59 for (; x < a->used; x++) {
60 *bottom++ = 0;
61 }
62 }
63
64 /* remove excess digits */
65 a->used -= b;
66 }
67 #endif
68
69 /* $Source$ */
70 /* $Revision$ */
71 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SET_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 to a digit */
18 void mp_set (mp_int * a, mp_digit b)
19 {
20 mp_zero (a);
21 a->dp[0] = b & MP_MASK;
22 a->used = (a->dp[0] != 0) ? 1 : 0;
23 }
24 #endif
25
26 /* $Source$ */
27 /* $Revision$ */
28 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SET_INT_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 32-bit const */
18 int mp_set_int (mp_int * a, unsigned long b)
19 {
20 int x, res;
21
22 mp_zero (a);
23
24 /* set four bits at a time */
25 for (x = 0; x < 8; x++) {
26 /* shift the number up four bits */
27 if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
28 return res;
29 }
30
31 /* OR in the top four bits of the source */
32 a->dp[0] |= (b >> 28) & 15;
33
34 /* shift the source up to the next four bits */
35 b <<= 4;
36
37 /* ensure that digits are not clamped off */
38 a->used += 1;
39 }
40 mp_clamp (a);
41 return MP_OKAY;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SHRINK_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 /* shrink a bignum */
18 int mp_shrink (mp_int * a)
19 {
20 mp_digit *tmp;
21 int used = 1;
22
23 if(a->used > 0)
24 used = a->used;
25
26 if (a->alloc != used) {
27 if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) {
28 return MP_MEM;
29 }
30 a->dp = tmp;
31 a->alloc = used;
32 }
33 return MP_OKAY;
34 }
35 #endif
36
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SIGNED_BIN_SIZE_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 size for an signed equivalent */
18 int mp_signed_bin_size (mp_int * a)
19 {
20 return 1 + mp_unsigned_bin_size (a);
21 }
22 #endif
23
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SQR_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 /* computes b = a*a */
18 int
19 mp_sqr (mp_int * a, mp_int * b)
20 {
21 int res;
22
23 #ifdef BN_MP_TOOM_SQR_C
24 /* use Toom-Cook? */
25 if (a->used >= TOOM_SQR_CUTOFF) {
26 res = mp_toom_sqr(a, b);
27 /* Karatsuba? */
28 } else
29 #endif
30 #ifdef BN_MP_KARATSUBA_SQR_C
31 if (a->used >= KARATSUBA_SQR_CUTOFF) {
32 res = mp_karatsuba_sqr (a, b);
33 } else
34 #endif
35 {
36 #ifdef BN_FAST_S_MP_SQR_C
37 /* can we use the fast comba multiplier? */
38 if ((a->used * 2 + 1) < MP_WARRAY &&
39 a->used <
40 (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
41 res = fast_s_mp_sqr (a, b);
42 } else
43 #endif
44 #ifdef BN_S_MP_SQR_C
45 res = s_mp_sqr (a, b);
46 #else
47 res = MP_VAL;
48 #endif
49 }
50 b->sign = MP_ZPOS;
51 return res;
52 }
53 #endif
54
55 /* $Source$ */
56 /* $Revision$ */
57 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SQRMOD_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 /* c = a * a (mod b) */
18 int
19 mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int res;
22 mp_int t;
23
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
27
28 if ((res = mp_sqr (a, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
32 res = mp_mod (&t, b, c);
33 mp_clear (&t);
34 return res;
35 }
36 #endif
37
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SQRT_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 /* this function is less generic than mp_n_root, simpler and faster */
18 int mp_sqrt(mp_int *arg, mp_int *ret)
19 {
20 int res;
21 mp_int t1,t2;
22
23 /* must be positive */
24 if (arg->sign == MP_NEG) {
25 return MP_VAL;
26 }
27
28 /* easy out */
29 if (mp_iszero(arg) == MP_YES) {
30 mp_zero(ret);
31 return MP_OKAY;
32 }
33
34 if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
35 return res;
36 }
37
38 if ((res = mp_init(&t2)) != MP_OKAY) {
39 goto E2;
40 }
41
42 /* First approx. (not very bad for large arg) */
43 mp_rshd (&t1,t1.used/2);
44
45 /* t1 > 0 */
46 if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
47 goto E1;
48 }
49 if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
50 goto E1;
51 }
52 if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
53 goto E1;
54 }
55 /* And now t1 > sqrt(arg) */
56 do {
57 if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
58 goto E1;
59 }
60 if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
61 goto E1;
62 }
63 if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
64 goto E1;
65 }
66 /* t1 >= sqrt(arg) >= t2 at this point */
67 } while (mp_cmp_mag(&t1,&t2) == MP_GT);
68
69 mp_exch(&t1,ret);
70
71 E1: mp_clear(&t2);
72 E2: mp_clear(&t1);
73 return res;
74 }
75
76 #endif
77
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SUB_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 /* high level subtraction (handles signs) */
18 int
19 mp_sub (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int sa, sb, res;
22
23 sa = a->sign;
24 sb = b->sign;
25
26 if (sa != sb) {
27 /* subtract a negative from a positive, OR */
28 /* subtract a positive from a negative. */
29 /* In either case, ADD their magnitudes, */
30 /* and use the sign of the first number. */
31 c->sign = sa;
32 res = s_mp_add (a, b, c);
33 } else {
34 /* subtract a positive from a positive, OR */
35 /* subtract a negative from a negative. */
36 /* First, take the difference between their */
37 /* magnitudes, then... */
38 if (mp_cmp_mag (a, b) != MP_LT) {
39 /* Copy the sign from the first */
40 c->sign = sa;
41 /* The first has a larger or equal magnitude */
42 res = s_mp_sub (a, b, c);
43 } else {
44 /* The result has the *opposite* sign from */
45 /* the first number. */
46 c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
47 /* The second has a larger magnitude */
48 res = s_mp_sub (b, a, c);
49 }
50 }
51 return res;
52 }
53
54 #endif
55
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SUB_D_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 /* single digit subtraction */
18 int
19 mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
20 {
21 mp_digit *tmpa, *tmpc, mu;
22 int res, ix, oldused;
23
24 /* grow c as required */
25 if (c->alloc < a->used + 1) {
26 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27 return res;
28 }
29 }
30
31 /* if a is negative just do an unsigned
32 * addition [with fudged signs]
33 */
34 if (a->sign == MP_NEG) {
35 a->sign = MP_ZPOS;
36 res = mp_add_d(a, b, c);
37 a->sign = c->sign = MP_NEG;
38
39 /* clamp */
40 mp_clamp(c);
41
42 return res;
43 }
44
45 /* setup regs */
46 oldused = c->used;
47 tmpa = a->dp;
48 tmpc = c->dp;
49
50 /* if a <= b simply fix the single digit */
51 if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
52 if (a->used == 1) {
53 *tmpc++ = b - *tmpa;
54 } else {
55 *tmpc++ = b;
56 }
57 ix = 1;
58
59 /* negative/1digit */
60 c->sign = MP_NEG;
61 c->used = 1;
62 } else {
63 /* positive/size */
64 c->sign = MP_ZPOS;
65 c->used = a->used;
66
67 /* subtract first digit */
68 *tmpc = *tmpa++ - b;
69 mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
70 *tmpc++ &= MP_MASK;
71
72 /* handle rest of the digits */
73 for (ix = 1; ix < a->used; ix++) {
74 *tmpc = *tmpa++ - mu;
75 mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
76 *tmpc++ &= MP_MASK;
77 }
78 }
79
80 /* zero excess digits */
81 while (ix++ < oldused) {
82 *tmpc++ = 0;
83 }
84 mp_clamp(c);
85 return MP_OKAY;
86 }
87
88 #endif
89
90 /* $Source$ */
91 /* $Revision$ */
92 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_SUBMOD_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 /* d = a - b (mod c) */
18 int
19 mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
20 {
21 int res;
22 mp_int t;
23
24
25 if ((res = mp_init (&t)) != MP_OKAY) {
26 return res;
27 }
28
29 if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
30 mp_clear (&t);
31 return res;
32 }
33 res = mp_mod (&t, c, d);
34 mp_clear (&t);
35 return res;
36 }
37 #endif
38
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_TO_SIGNED_BIN_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 /* store in signed [big endian] format */
18 int mp_to_signed_bin (mp_int * a, unsigned char *b)
19 {
20 int res;
21
22 if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
23 return res;
24 }
25 b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1);
26 return MP_OKAY;
27 }
28 #endif
29
30 /* $Source$ */
31 /* $Revision$ */
32 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_TO_SIGNED_BIN_N_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 /* store in signed [big endian] format */
18 int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
19 {
20 if (*outlen < (unsigned long)mp_signed_bin_size(a)) {
21 return MP_VAL;
22 }
23 *outlen = mp_signed_bin_size(a);
24 return mp_to_signed_bin(a, b);
25 }
26 #endif
27
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_TO_UNSIGNED_BIN_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 /* store in unsigned [big endian] format */
18 int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
19 {
20 int x, res;
21 mp_int t;
22
23 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
24 return res;
25 }
26
27 x = 0;
28 while (mp_iszero (&t) == 0) {
29 #ifndef MP_8BIT
30 b[x++] = (unsigned char) (t.dp[0] & 255);
31 #else
32 b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
33 #endif
34 if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
35 mp_clear (&t);
36 return res;
37 }
38 }
39 bn_reverse (b, x);
40 mp_clear (&t);
41 return MP_OKAY;
42 }
43 #endif
44
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_TO_UNSIGNED_BIN_N_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 /* store in unsigned [big endian] format */
18 int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
19 {
20 if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
21 return MP_VAL;
22 }
23 *outlen = mp_unsigned_bin_size(a);
24 return mp_to_unsigned_bin(a, b);
25 }
26 #endif
27
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_TOOM_MUL_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 /* multiplication using the Toom-Cook 3-way algorithm
18 *
19 * Much more complicated than Karatsuba but has a lower
20 * asymptotic running time of O(N**1.464). This algorithm is
21 * only particularly useful on VERY large inputs
22 * (we're talking 1000s of digits here...).
23 */
24 int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
25 {
26 mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
27 int res, B;
28
29 /* init temps */
30 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
31 &a0, &a1, &a2, &b0, &b1,
32 &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
33 return res;
34 }
35
36 /* B */
37 B = MIN(a->used, b->used) / 3;
38
39 /* a = a2 * B**2 + a1 * B + a0 */
40 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
41 goto ERR;
42 }
43
44 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
45 goto ERR;
46 }
47 mp_rshd(&a1, B);
48 mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
49
50 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
51 goto ERR;
52 }
53 mp_rshd(&a2, B*2);
54
55 /* b = b2 * B**2 + b1 * B + b0 */
56 if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
57 goto ERR;
58 }
59
60 if ((res = mp_copy(b, &b1)) != MP_OKAY) {
61 goto ERR;
62 }
63 mp_rshd(&b1, B);
64 mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
65
66 if ((res = mp_copy(b, &b2)) != MP_OKAY) {
67 goto ERR;
68 }
69 mp_rshd(&b2, B*2);
70
71 /* w0 = a0*b0 */
72 if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
73 goto ERR;
74 }
75
76 /* w4 = a2 * b2 */
77 if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
78 goto ERR;
79 }
80
81 /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
82 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
83 goto ERR;
84 }
85 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
86 goto ERR;
87 }
88 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
89 goto ERR;
90 }
91 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
92 goto ERR;
93 }
94
95 if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
96 goto ERR;
97 }
98 if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
99 goto ERR;
100 }
101 if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
102 goto ERR;
103 }
104 if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
105 goto ERR;
106 }
107
108 if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
109 goto ERR;
110 }
111
112 /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
113 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
114 goto ERR;
115 }
116 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
117 goto ERR;
118 }
119 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
120 goto ERR;
121 }
122 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
123 goto ERR;
124 }
125
126 if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
127 goto ERR;
128 }
129 if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
130 goto ERR;
131 }
132 if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
133 goto ERR;
134 }
135 if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
136 goto ERR;
137 }
138
139 if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
140 goto ERR;
141 }
142
143
144 /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
145 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
146 goto ERR;
147 }
148 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
149 goto ERR;
150 }
151 if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
152 goto ERR;
153 }
154 if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
155 goto ERR;
156 }
157 if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
158 goto ERR;
159 }
160
161 /* now solve the matrix
162
163 0 0 0 0 1
164 1 2 4 8 16
165 1 1 1 1 1
166 16 8 4 2 1
167 1 0 0 0 0
168
169 using 12 subtractions, 4 shifts,
170 2 small divisions and 1 small multiplication
171 */
172
173 /* r1 - r4 */
174 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
175 goto ERR;
176 }
177 /* r3 - r0 */
178 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
179 goto ERR;
180 }
181 /* r1/2 */
182 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
183 goto ERR;
184 }
185 /* r3/2 */
186 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
187 goto ERR;
188 }
189 /* r2 - r0 - r4 */
190 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
191 goto ERR;
192 }
193 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
194 goto ERR;
195 }
196 /* r1 - r2 */
197 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
198 goto ERR;
199 }
200 /* r3 - r2 */
201 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
202 goto ERR;
203 }
204 /* r1 - 8r0 */
205 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
206 goto ERR;
207 }
208 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
209 goto ERR;
210 }
211 /* r3 - 8r4 */
212 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
213 goto ERR;
214 }
215 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
216 goto ERR;
217 }
218 /* 3r2 - r1 - r3 */
219 if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
220 goto ERR;
221 }
222 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
223 goto ERR;
224 }
225 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
226 goto ERR;
227 }
228 /* r1 - r2 */
229 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
230 goto ERR;
231 }
232 /* r3 - r2 */
233 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
234 goto ERR;
235 }
236 /* r1/3 */
237 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
238 goto ERR;
239 }
240 /* r3/3 */
241 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
242 goto ERR;
243 }
244
245 /* at this point shift W[n] by B*n */
246 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
247 goto ERR;
248 }
249 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
250 goto ERR;
251 }
252 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
253 goto ERR;
254 }
255 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
256 goto ERR;
257 }
258
259 if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
260 goto ERR;
261 }
262 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
263 goto ERR;
264 }
265 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
266 goto ERR;
267 }
268 if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
269 goto ERR;
270 }
271
272 ERR:
273 mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
274 &a0, &a1, &a2, &b0, &b1,
275 &b2, &tmp1, &tmp2, NULL);
276 return res;
277 }
278
279 #endif
280
281 /* $Source$ */
282 /* $Revision$ */
283 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_TOOM_SQR_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 /* squaring using Toom-Cook 3-way algorithm */
18 int
19 mp_toom_sqr(mp_int *a, mp_int *b)
20 {
21 mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
22 int res, B;
23
24 /* init temps */
25 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
26 return res;
27 }
28
29 /* B */
30 B = a->used / 3;
31
32 /* a = a2 * B**2 + a1 * B + a0 */
33 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
34 goto ERR;
35 }
36
37 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
38 goto ERR;
39 }
40 mp_rshd(&a1, B);
41 mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
42
43 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
44 goto ERR;
45 }
46 mp_rshd(&a2, B*2);
47
48 /* w0 = a0*a0 */
49 if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
50 goto ERR;
51 }
52
53 /* w4 = a2 * a2 */
54 if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
55 goto ERR;
56 }
57
58 /* w1 = (a2 + 2(a1 + 2a0))**2 */
59 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
60 goto ERR;
61 }
62 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
63 goto ERR;
64 }
65 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
66 goto ERR;
67 }
68 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
69 goto ERR;
70 }
71
72 if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
73 goto ERR;
74 }
75
76 /* w3 = (a0 + 2(a1 + 2a2))**2 */
77 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
78 goto ERR;
79 }
80 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
81 goto ERR;
82 }
83 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
84 goto ERR;
85 }
86 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
87 goto ERR;
88 }
89
90 if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
91 goto ERR;
92 }
93
94
95 /* w2 = (a2 + a1 + a0)**2 */
96 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
97 goto ERR;
98 }
99 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
100 goto ERR;
101 }
102 if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
103 goto ERR;
104 }
105
106 /* now solve the matrix
107
108 0 0 0 0 1
109 1 2 4 8 16
110 1 1 1 1 1
111 16 8 4 2 1
112 1 0 0 0 0
113
114 using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
115 */
116
117 /* r1 - r4 */
118 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
119 goto ERR;
120 }
121 /* r3 - r0 */
122 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
123 goto ERR;
124 }
125 /* r1/2 */
126 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
127 goto ERR;
128 }
129 /* r3/2 */
130 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
131 goto ERR;
132 }
133 /* r2 - r0 - r4 */
134 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
135 goto ERR;
136 }
137 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
138 goto ERR;
139 }
140 /* r1 - r2 */
141 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
142 goto ERR;
143 }
144 /* r3 - r2 */
145 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
146 goto ERR;
147 }
148 /* r1 - 8r0 */
149 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
150 goto ERR;
151 }
152 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
153 goto ERR;
154 }
155 /* r3 - 8r4 */
156 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
157 goto ERR;
158 }
159 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
160 goto ERR;
161 }
162 /* 3r2 - r1 - r3 */
163 if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
164 goto ERR;
165 }
166 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
167 goto ERR;
168 }
169 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
170 goto ERR;
171 }
172 /* r1 - r2 */
173 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
174 goto ERR;
175 }
176 /* r3 - r2 */
177 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
178 goto ERR;
179 }
180 /* r1/3 */
181 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
182 goto ERR;
183 }
184 /* r3/3 */
185 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
186 goto ERR;
187 }
188
189 /* at this point shift W[n] by B*n */
190 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
191 goto ERR;
192 }
193 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
194 goto ERR;
195 }
196 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
197 goto ERR;
198 }
199 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
200 goto ERR;
201 }
202
203 if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
204 goto ERR;
205 }
206 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
207 goto ERR;
208 }
209 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
210 goto ERR;
211 }
212 if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
213 goto ERR;
214 }
215
216 ERR:
217 mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
218 return res;
219 }
220
221 #endif
222
223 /* $Source$ */
224 /* $Revision$ */
225 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_TORADIX_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 /* stores a bignum as a ASCII string in a given radix (2..64) */
18 int mp_toradix (mp_int * a, char *str, int radix)
19 {
20 int res, digs;
21 mp_int t;
22 mp_digit d;
23 char *_s = str;
24
25 /* check range of the radix */
26 if (radix < 2 || radix > 64) {
27 return MP_VAL;
28 }
29
30 /* quick out if its zero */
31 if (mp_iszero(a) == 1) {
32 *str++ = '0';
33 *str = '\0';
34 return MP_OKAY;
35 }
36
37 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
38 return res;
39 }
40
41 /* if it is negative output a - */
42 if (t.sign == MP_NEG) {
43 ++_s;
44 *str++ = '-';
45 t.sign = MP_ZPOS;
46 }
47
48 digs = 0;
49 while (mp_iszero (&t) == 0) {
50 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
51 mp_clear (&t);
52 return res;
53 }
54 *str++ = mp_s_rmap[d];
55 ++digs;
56 }
57
58 /* reverse the digits of the string. In this case _s points
59 * to the first digit [exluding the sign] of the number]
60 */
61 bn_reverse ((unsigned char *)_s, digs);
62
63 /* append a NULL so the string is properly terminated */
64 *str = '\0';
65
66 mp_clear (&t);
67 return MP_OKAY;
68 }
69
70 #endif
71
72 /* $Source$ */
73 /* $Revision$ */
74 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_TORADIX_N_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 /* stores a bignum as a ASCII string in a given radix (2..64)
18 *
19 * Stores upto maxlen-1 chars and always a NULL byte
20 */
21 int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
22 {
23 int res, digs;
24 mp_int t;
25 mp_digit d;
26 char *_s = str;
27
28 /* check range of the maxlen, radix */
29 if (maxlen < 2 || radix < 2 || radix > 64) {
30 return MP_VAL;
31 }
32
33 /* quick out if its zero */
34 if (mp_iszero(a) == MP_YES) {
35 *str++ = '0';
36 *str = '\0';
37 return MP_OKAY;
38 }
39
40 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
41 return res;
42 }
43
44 /* if it is negative output a - */
45 if (t.sign == MP_NEG) {
46 /* we have to reverse our digits later... but not the - sign!! */
47 ++_s;
48
49 /* store the flag and mark the number as positive */
50 *str++ = '-';
51 t.sign = MP_ZPOS;
52
53 /* subtract a char */
54 --maxlen;
55 }
56
57 digs = 0;
58 while (mp_iszero (&t) == 0) {
59 if (--maxlen < 1) {
60 /* no more room */
61 break;
62 }
63 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
64 mp_clear (&t);
65 return res;
66 }
67 *str++ = mp_s_rmap[d];
68 ++digs;
69 }
70
71 /* reverse the digits of the string. In this case _s points
72 * to the first digit [exluding the sign] of the number
73 */
74 bn_reverse ((unsigned char *)_s, digs);
75
76 /* append a NULL so the string is properly terminated */
77 *str = '\0';
78
79 mp_clear (&t);
80 return MP_OKAY;
81 }
82
83 #endif
84
85 /* $Source$ */
86 /* $Revision$ */
87 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_UNSIGNED_BIN_SIZE_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 size for an unsigned equivalent */
18 int mp_unsigned_bin_size (mp_int * a)
19 {
20 int size = mp_count_bits (a);
21 return (size / 8 + ((size & 7) != 0 ? 1 : 0));
22 }
23 #endif
24
25 /* $Source$ */
26 /* $Revision$ */
27 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_XOR_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 /* XOR two ints together */
18 int
19 mp_xor (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int res, ix, px;
22 mp_int t, *x;
23
24 if (a->used > b->used) {
25 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
37
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] ^= x->dp[ix];
40 }
41 mp_clamp (&t);
42 mp_exch (c, &t);
43 mp_clear (&t);
44 return MP_OKAY;
45 }
46 #endif
47
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_MP_ZERO_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 to zero */
18 void mp_zero (mp_int * a)
19 {
20 int n;
21 mp_digit *tmp;
22
23 a->sign = MP_ZPOS;
24 a->used = 0;
25
26 tmp = a->dp;
27 for (n = 0; n < a->alloc; n++) {
28 *tmp++ = 0;
29 }
30 }
31 #endif
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_PRIME_TAB_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 const mp_digit ltm_prime_tab[] = {
17 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
18 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
19 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
20 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
21 #ifndef MP_8BIT
22 0x0083,
23 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
24 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
25 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
26 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
27
28 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
29 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
30 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
31 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
32 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
33 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
34 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
35 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
36
37 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
38 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
39 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
40 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
41 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
42 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
43 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
44 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
45
46 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
47 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
48 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
49 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
50 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
51 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
52 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
53 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
54 #endif
55 };
56 #endif
57
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_REVERSE_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 /* reverse an array, used for radix code */
18 void
19 bn_reverse (unsigned char *s, int len)
20 {
21 int ix, iy;
22 unsigned char t;
23
24 ix = 0;
25 iy = len - 1;
26 while (ix < iy) {
27 t = s[ix];
28 s[ix] = s[iy];
29 s[iy] = t;
30 ++ix;
31 --iy;
32 }
33 }
34 #endif
35
36 /* $Source$ */
37 /* $Revision$ */
38 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_S_MP_ADD_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 /* low level addition, based on HAC pp.594, Algorithm 14.7 */
18 int
19 s_mp_add (mp_int * a, mp_int * b, mp_int * c)
20 {
21 mp_int *x;
22 int olduse, res, min, max;
23
24 /* find sizes, we let |a| <= |b| which means we have to sort
25 * them. "x" will point to the input with the most digits
26 */
27 if (a->used > b->used) {
28 min = b->used;
29 max = a->used;
30 x = a;
31 } else {
32 min = a->used;
33 max = b->used;
34 x = b;
35 }
36
37 /* init result */
38 if (c->alloc < max + 1) {
39 if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
40 return res;
41 }
42 }
43
44 /* get old used digit count and set new one */
45 olduse = c->used;
46 c->used = max + 1;
47
48 {
49 register mp_digit u, *tmpa, *tmpb, *tmpc;
50 register int i;
51
52 /* alias for digit pointers */
53
54 /* first input */
55 tmpa = a->dp;
56
57 /* second input */
58 tmpb = b->dp;
59
60 /* destination */
61 tmpc = c->dp;
62
63 /* zero the carry */
64 u = 0;
65 for (i = 0; i < min; i++) {
66 /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
67 *tmpc = *tmpa++ + *tmpb++ + u;
68
69 /* U = carry bit of T[i] */
70 u = *tmpc >> ((mp_digit)DIGIT_BIT);
71
72 /* take away carry bit from T[i] */
73 *tmpc++ &= MP_MASK;
74 }
75
76 /* now copy higher words if any, that is in A+B
77 * if A or B has more digits add those in
78 */
79 if (min != max) {
80 for (; i < max; i++) {
81 /* T[i] = X[i] + U */
82 *tmpc = x->dp[i] + u;
83
84 /* U = carry bit of T[i] */
85 u = *tmpc >> ((mp_digit)DIGIT_BIT);
86
87 /* take away carry bit from T[i] */
88 *tmpc++ &= MP_MASK;
89 }
90 }
91
92 /* add carry */
93 *tmpc++ = u;
94
95 /* clear digits above oldused */
96 for (i = c->used; i < olduse; i++) {
97 *tmpc++ = 0;
98 }
99 }
100
101 mp_clamp (c);
102 return MP_OKAY;
103 }
104 #endif
105
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_S_MP_EXPTMOD_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 #ifdef MP_LOW_MEM
17 #define TAB_SIZE 32
18 #else
19 #define TAB_SIZE 256
20 #endif
21
22 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
23 {
24 mp_int M[TAB_SIZE], res, mu;
25 mp_digit buf;
26 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
27 int (*redux)(mp_int*,mp_int*,mp_int*);
28
29 /* find window size */
30 x = mp_count_bits (X);
31 if (x <= 7) {
32 winsize = 2;
33 } else if (x <= 36) {
34 winsize = 3;
35 } else if (x <= 140) {
36 winsize = 4;
37 } else if (x <= 450) {
38 winsize = 5;
39 } else if (x <= 1303) {
40 winsize = 6;
41 } else if (x <= 3529) {
42 winsize = 7;
43 } else {
44 winsize = 8;
45 }
46
47 #ifdef MP_LOW_MEM
48 if (winsize > 5) {
49 winsize = 5;
50 }
51 #endif
52
53 /* init M array */
54 /* init first cell */
55 if ((err = mp_init(&M[1])) != MP_OKAY) {
56 return err;
57 }
58
59 /* now init the second half of the array */
60 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
61 if ((err = mp_init(&M[x])) != MP_OKAY) {
62 for (y = 1<<(winsize-1); y < x; y++) {
63 mp_clear (&M[y]);
64 }
65 mp_clear(&M[1]);
66 return err;
67 }
68 }
69
70 /* create mu, used for Barrett reduction */
71 if ((err = mp_init (&mu)) != MP_OKAY) {
72 goto LBL_M;
73 }
74
75 if (redmode == 0) {
76 if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
77 goto LBL_MU;
78 }
79 redux = mp_reduce;
80 } else {
81 if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
82 goto LBL_MU;
83 }
84 redux = mp_reduce_2k_l;
85 }
86
87 /* create M table
88 *
89 * The M table contains powers of the base,
90 * e.g. M[x] = G**x mod P
91 *
92 * The first half of the table is not
93 * computed though accept for M[0] and M[1]
94 */
95 if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
96 goto LBL_MU;
97 }
98
99 /* compute the value at M[1<<(winsize-1)] by squaring
100 * M[1] (winsize-1) times
101 */
102 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
103 goto LBL_MU;
104 }
105
106 for (x = 0; x < (winsize - 1); x++) {
107 /* square it */
108 if ((err = mp_sqr (&M[1 << (winsize - 1)],
109 &M[1 << (winsize - 1)])) != MP_OKAY) {
110 goto LBL_MU;
111 }
112
113 /* reduce modulo P */
114 if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
115 goto LBL_MU;
116 }
117 }
118
119 /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
120 * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
121 */
122 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
123 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
124 goto LBL_MU;
125 }
126 if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
127 goto LBL_MU;
128 }
129 }
130
131 /* setup result */
132 if ((err = mp_init (&res)) != MP_OKAY) {
133 goto LBL_MU;
134 }
135 mp_set (&res, 1);
136
137 /* set initial mode and bit cnt */
138 mode = 0;
139 bitcnt = 1;
140 buf = 0;
141 digidx = X->used - 1;
142 bitcpy = 0;
143 bitbuf = 0;
144
145 for (;;) {
146 /* grab next digit as required */
147 if (--bitcnt == 0) {
148 /* if digidx == -1 we are out of digits */
149 if (digidx == -1) {
150 break;
151 }
152 /* read next digit and reset the bitcnt */
153 buf = X->dp[digidx--];
154 bitcnt = (int) DIGIT_BIT;
155 }
156
157 /* grab the next msb from the exponent */
158 y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
159 buf <<= (mp_digit)1;
160
161 /* if the bit is zero and mode == 0 then we ignore it
162 * These represent the leading zero bits before the first 1 bit
163 * in the exponent. Technically this opt is not required but it
164 * does lower the # of trivial squaring/reductions used
165 */
166 if (mode == 0 && y == 0) {
167 continue;
168 }
169
170 /* if the bit is zero and mode == 1 then we square */
171 if (mode == 1 && y == 0) {
172 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
173 goto LBL_RES;
174 }
175 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
176 goto LBL_RES;
177 }
178 continue;
179 }
180
181 /* else we add it to the window */
182 bitbuf |= (y << (winsize - ++bitcpy));
183 mode = 2;
184
185 if (bitcpy == winsize) {
186 /* ok window is filled so square as required and multiply */
187 /* square first */
188 for (x = 0; x < winsize; x++) {
189 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
190 goto LBL_RES;
191 }
192 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
193 goto LBL_RES;
194 }
195 }
196
197 /* then multiply */
198 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
199 goto LBL_RES;
200 }
201 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
202 goto LBL_RES;
203 }
204
205 /* empty window and reset */
206 bitcpy = 0;
207 bitbuf = 0;
208 mode = 1;
209 }
210 }
211
212 /* if bits remain then square/multiply */
213 if (mode == 2 && bitcpy > 0) {
214 /* square then multiply if the bit is set */
215 for (x = 0; x < bitcpy; x++) {
216 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
217 goto LBL_RES;
218 }
219 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
220 goto LBL_RES;
221 }
222
223 bitbuf <<= 1;
224 if ((bitbuf & (1 << winsize)) != 0) {
225 /* then multiply */
226 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
227 goto LBL_RES;
228 }
229 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
230 goto LBL_RES;
231 }
232 }
233 }
234 }
235
236 mp_exch (&res, Y);
237 err = MP_OKAY;
238 LBL_RES:mp_clear (&res);
239 LBL_MU:mp_clear (&mu);
240 LBL_M:
241 mp_clear(&M[1]);
242 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
243 mp_clear (&M[x]);
244 }
245 return err;
246 }
247 #endif
248
249 /* $Source$ */
250 /* $Revision$ */
251 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_S_MP_MUL_DIGS_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 /* multiplies |a| * |b| and only computes upto digs digits of result
18 * HAC pp. 595, Algorithm 14.12 Modified so you can control how
19 * many digits of output are created.
20 */
21 int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
22 {
23 mp_int t;
24 int res, pa, pb, ix, iy;
25 mp_digit u;
26 mp_word r;
27 mp_digit tmpx, *tmpt, *tmpy;
28
29 /* can we use the fast multiplier? */
30 if (((digs) < MP_WARRAY) &&
31 MIN (a->used, b->used) <
32 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
33 return fast_s_mp_mul_digs (a, b, c, digs);
34 }
35
36 if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
37 return res;
38 }
39 t.used = digs;
40
41 /* compute the digits of the product directly */
42 pa = a->used;
43 for (ix = 0; ix < pa; ix++) {
44 /* set the carry to zero */
45 u = 0;
46
47 /* limit ourselves to making digs digits of output */
48 pb = MIN (b->used, digs - ix);
49
50 /* setup some aliases */
51 /* copy of the digit from a used within the nested loop */
52 tmpx = a->dp[ix];
53
54 /* an alias for the destination shifted ix places */
55 tmpt = t.dp + ix;
56
57 /* an alias for the digits of b */
58 tmpy = b->dp;
59
60 /* compute the columns of the output and propagate the carry */
61 for (iy = 0; iy < pb; iy++) {
62 /* compute the column as a mp_word */
63 r = ((mp_word)*tmpt) +
64 ((mp_word)tmpx) * ((mp_word)*tmpy++) +
65 ((mp_word) u);
66
67 /* the new column is the lower part of the result */
68 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
69
70 /* get the carry word from the result */
71 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
72 }
73 /* set carry if it is placed below digs */
74 if (ix + iy < digs) {
75 *tmpt = u;
76 }
77 }
78
79 mp_clamp (&t);
80 mp_exch (&t, c);
81
82 mp_clear (&t);
83 return MP_OKAY;
84 }
85 #endif
86
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_S_MP_MUL_HIGH_DIGS_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 /* multiplies |a| * |b| and does not compute the lower digs digits
18 * [meant to get the higher part of the product]
19 */
20 int
21 s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
22 {
23 mp_int t;
24 int res, pa, pb, ix, iy;
25 mp_digit u;
26 mp_word r;
27 mp_digit tmpx, *tmpt, *tmpy;
28
29 /* can we use the fast multiplier? */
30 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
31 if (((a->used + b->used + 1) < MP_WARRAY)
32 && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
33 return fast_s_mp_mul_high_digs (a, b, c, digs);
34 }
35 #endif
36
37 if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
38 return res;
39 }
40 t.used = a->used + b->used + 1;
41
42 pa = a->used;
43 pb = b->used;
44 for (ix = 0; ix < pa; ix++) {
45 /* clear the carry */
46 u = 0;
47
48 /* left hand side of A[ix] * B[iy] */
49 tmpx = a->dp[ix];
50
51 /* alias to the address of where the digits will be stored */
52 tmpt = &(t.dp[digs]);
53
54 /* alias for where to read the right hand side from */
55 tmpy = b->dp + (digs - ix);
56
57 for (iy = digs - ix; iy < pb; iy++) {
58 /* calculate the double precision result */
59 r = ((mp_word)*tmpt) +
60 ((mp_word)tmpx) * ((mp_word)*tmpy++) +
61 ((mp_word) u);
62
63 /* get the lower part */
64 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
65
66 /* carry the carry */
67 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
68 }
69 *tmpt = u;
70 }
71 mp_clamp (&t);
72 mp_exch (&t, c);
73 mp_clear (&t);
74 return MP_OKAY;
75 }
76 #endif
77
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_S_MP_SQR_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 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
18 int s_mp_sqr (mp_int * a, mp_int * b)
19 {
20 mp_int t;
21 int res, ix, iy, pa;
22 mp_word r;
23 mp_digit u, tmpx, *tmpt;
24
25 pa = a->used;
26 if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
27 return res;
28 }
29
30 /* default used is maximum possible size */
31 t.used = 2*pa + 1;
32
33 for (ix = 0; ix < pa; ix++) {
34 /* first calculate the digit at 2*ix */
35 /* calculate double precision result */
36 r = ((mp_word) t.dp[2*ix]) +
37 ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
38
39 /* store lower part in result */
40 t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
41
42 /* get the carry */
43 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
44
45 /* left hand side of A[ix] * A[iy] */
46 tmpx = a->dp[ix];
47
48 /* alias for where to store the results */
49 tmpt = t.dp + (2*ix + 1);
50
51 for (iy = ix + 1; iy < pa; iy++) {
52 /* first calculate the product */
53 r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
54
55 /* now calculate the double precision result, note we use
56 * addition instead of *2 since it's easier to optimize
57 */
58 r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
59
60 /* store lower part */
61 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
62
63 /* get carry */
64 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
65 }
66 /* propagate upwards */
67 while (u != ((mp_digit) 0)) {
68 r = ((mp_word) *tmpt) + ((mp_word) u);
69 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
70 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
71 }
72 }
73
74 mp_clamp (&t);
75 mp_exch (&t, b);
76 mp_clear (&t);
77 return MP_OKAY;
78 }
79 #endif
80
81 /* $Source$ */
82 /* $Revision$ */
83 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BN_S_MP_SUB_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 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
18 int
19 s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
20 {
21 int olduse, res, min, max;
22
23 /* find sizes */
24 min = b->used;
25 max = a->used;
26
27 /* init result */
28 if (c->alloc < max) {
29 if ((res = mp_grow (c, max)) != MP_OKAY) {
30 return res;
31 }
32 }
33 olduse = c->used;
34 c->used = max;
35
36 {
37 register mp_digit u, *tmpa, *tmpb, *tmpc;
38 register int i;
39
40 /* alias for digit pointers */
41 tmpa = a->dp;
42 tmpb = b->dp;
43 tmpc = c->dp;
44
45 /* set carry to zero */
46 u = 0;
47 for (i = 0; i < min; i++) {
48 /* T[i] = A[i] - B[i] - U */
49 *tmpc = *tmpa++ - *tmpb++ - u;
50
51 /* U = carry bit of T[i]
52 * Note this saves performing an AND operation since
53 * if a carry does occur it will propagate all the way to the
54 * MSB. As a result a single shift is enough to get the carry
55 */
56 u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
57
58 /* Clear carry from T[i] */
59 *tmpc++ &= MP_MASK;
60 }
61
62 /* now copy higher words if any, e.g. if A has more digits than B */
63 for (; i < max; i++) {
64 /* T[i] = A[i] - U */
65 *tmpc = *tmpa++ - u;
66
67 /* U = carry bit of T[i] */
68 u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
69
70 /* Clear carry from T[i] */
71 *tmpc++ &= MP_MASK;
72 }
73
74 /* clear digits above used (since we may not have grown result above) */
75 for (i = c->used; i < olduse; i++) {
76 *tmpc++ = 0;
77 }
78 }
79
80 mp_clamp (c);
81 return MP_OKAY;
82 }
83
84 #endif
85
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
0 #include <tommath.h>
1 #ifdef BNCORE_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 /* Known optimal configurations
18
19 CPU /Compiler /MUL CUTOFF/SQR CUTOFF
20 -------------------------------------------------------------
21 Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-)
22 AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35
23
24 */
25
26 int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */
27 KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */
28
29 TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
30 TOOM_SQR_CUTOFF = 400;
31 #endif
32
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
0 /* LibTomMath, multiple-precision integer library -- Tom St Denis
1 *
2 * LibTomMath is a library that provides multiple-precision
3 * integer arithmetic as well as number theoretic functionality.
4 *
5 * The library was designed directly after the MPI library by
6 * Michael Fromberger but has been written from scratch with
7 * additional optimizations in place.
8 *
9 * The library is free for all purposes without any express
10 * guarantee it works.
11 *
12 * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
13 */
14 #ifndef BN_H_
15 #define BN_H_
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <ctype.h>
21 #include <limits.h>
22
23 #include <tommath_class.h>
24
25 #ifndef MIN
26 #define MIN(x,y) ((x)<(y)?(x):(y))
27 #endif
28
29 #ifndef MAX
30 #define MAX(x,y) ((x)>(y)?(x):(y))
31 #endif
32
33 #ifdef __cplusplus
34 extern "C" {
35
36 /* C++ compilers don't like assigning void * to mp_digit * */
37 #define OPT_CAST(x) (x *)
38
39 #else
40
41 /* C on the other hand doesn't care */
42 #define OPT_CAST(x)
43
44 #endif
45
46
47 /* detect 64-bit mode if possible */
48 #if defined(__x86_64__)
49 #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
50 #define MP_64BIT
51 #endif
52 #endif
53
54 /* some default configurations.
55 *
56 * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
57 * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
58 *
59 * At the very least a mp_digit must be able to hold 7 bits
60 * [any size beyond that is ok provided it doesn't overflow the data type]
61 */
62 #ifdef MP_8BIT
63 typedef unsigned char mp_digit;
64 typedef unsigned short mp_word;
65 #elif defined(MP_16BIT)
66 typedef unsigned short mp_digit;
67 typedef unsigned long mp_word;
68 #elif defined(MP_64BIT)
69 /* for GCC only on supported platforms */
70 #ifndef CRYPT
71 typedef unsigned long long ulong64;
72 typedef signed long long long64;
73 #endif
74
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;
82 typedef unsigned long mp_word __attribute__ ((mode(TI)));
83 #define DIGIT_BIT 60
84 #endif
85
86
87 #else
88 /* this is the default case, 28-bit digits */
89
90 /* this is to make porting into LibTomCrypt easier :-) */
91 #ifndef CRYPT
92 #if defined(_MSC_VER) || defined(__BORLANDC__)
93 typedef unsigned __int64 ulong64;
94 typedef signed __int64 long64;
95 #else
96 typedef unsigned long long ulong64;
97 typedef signed long long long64;
98 #endif
99 #endif
100
101 typedef unsigned long mp_digit;
102 typedef ulong64 mp_word;
103
104 #ifdef MP_31BIT
105 /* this is an extension that uses 31-bit digits */
106 #define DIGIT_BIT 31
107 #else
108 /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
109 #define DIGIT_BIT 28
110 #define MP_28BIT
111 #endif
112 #endif
113
114 /* define heap macros */
115 #ifndef CRYPT
116 /* default to libc stuff */
117 #ifndef XMALLOC
118 #define XMALLOC malloc
119 #define XFREE free
120 #define XREALLOC realloc
121 #define XCALLOC calloc
122 #else
123 /* prototypes for our heap functions */
124 extern void *XMALLOC(size_t n);
125 extern void *XREALLOC(void *p, size_t n);
126 extern void *XCALLOC(size_t n, size_t s);
127 extern void XFREE(void *p);
128 #endif
129 #endif
130
131
132 /* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
133 #ifndef DIGIT_BIT
134 #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
135 #endif
136
137 #define MP_DIGIT_BIT DIGIT_BIT
138 #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
139 #define MP_DIGIT_MAX MP_MASK
140
141 /* equalities */
142 #define MP_LT -1 /* less than */
143 #define MP_EQ 0 /* equal to */
144 #define MP_GT 1 /* greater than */
145
146 #define MP_ZPOS 0 /* positive integer */
147 #define MP_NEG 1 /* negative */
148
149 #define MP_OKAY 0 /* ok result */
150 #define MP_MEM -2 /* out of mem */
151 #define MP_VAL -3 /* invalid input */
152 #define MP_RANGE MP_VAL
153
154 #define MP_YES 1 /* yes response */
155 #define MP_NO 0 /* no response */
156
157 /* Primality generation flags */
158 #define LTM_PRIME_BBS 0x0001 /* BBS style prime */
159 #define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
160 #define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
161
162 typedef int mp_err;
163
164 /* you'll have to tune these... */
165 extern int KARATSUBA_MUL_CUTOFF,
166 KARATSUBA_SQR_CUTOFF,
167 TOOM_MUL_CUTOFF,
168 TOOM_SQR_CUTOFF;
169
170 /* define this to use lower memory usage routines (exptmods mostly) */
171 /* #define MP_LOW_MEM */
172
173 /* default precision */
174 #ifndef MP_PREC
175 #ifndef MP_LOW_MEM
176 #define MP_PREC 32 /* default digits of precision */
177 #else
178 #define MP_PREC 8 /* default digits of precision */
179 #endif
180 #endif
181
182 /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
183 #define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
184
185 /* the infamous mp_int structure */
186 typedef struct {
187 int used, alloc, sign;
188 mp_digit *dp;
189 } mp_int;
190
191 /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
192 typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
193
194
195 #define USED(m) ((m)->used)
196 #define DIGIT(m,k) ((m)->dp[(k)])
197 #define SIGN(m) ((m)->sign)
198
199 /* error code to char* string */
200 const char *mp_error_to_string(int code);
201
202 /* ---> init and deinit bignum functions <--- */
203 /* init a bignum */
204 int mp_init(mp_int *a);
205
206 /* free a bignum */
207 void mp_clear(mp_int *a);
208
209 /* init a null terminated series of arguments */
210 int mp_init_multi(mp_int *mp, ...);
211
212 /* clear a null terminated series of arguments */
213 void mp_clear_multi(mp_int *mp, ...);
214
215 /* exchange two ints */
216 void mp_exch(mp_int *a, mp_int *b);
217
218 /* shrink ram required for a bignum */
219 int mp_shrink(mp_int *a);
220
221 /* grow an int to a given size */
222 int mp_grow(mp_int *a, int size);
223
224 /* init to a given number of digits */
225 int mp_init_size(mp_int *a, int size);
226
227 /* ---> Basic Manipulations <--- */
228 #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
229 #define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
230 #define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
231
232 /* set to zero */
233 void mp_zero(mp_int *a);
234
235 /* set to a digit */
236 void mp_set(mp_int *a, mp_digit b);
237
238 /* set a 32-bit const */
239 int mp_set_int(mp_int *a, unsigned long b);
240
241 /* get a 32-bit value */
242 unsigned long mp_get_int(mp_int * a);
243
244 /* initialize and set a digit */
245 int mp_init_set (mp_int * a, mp_digit b);
246
247 /* initialize and set 32-bit value */
248 int mp_init_set_int (mp_int * a, unsigned long b);
249
250 /* copy, b = a */
251 int mp_copy(mp_int *a, mp_int *b);
252
253 /* inits and copies, a = b */
254 int mp_init_copy(mp_int *a, mp_int *b);
255
256 /* trim unused digits */
257 void mp_clamp(mp_int *a);
258
259 /* ---> digit manipulation <--- */
260
261 /* right shift by "b" digits */
262 void mp_rshd(mp_int *a, int b);
263
264 /* left shift by "b" digits */
265 int mp_lshd(mp_int *a, int b);
266
267 /* c = a / 2**b */
268 int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
269
270 /* b = a/2 */
271 int mp_div_2(mp_int *a, mp_int *b);
272
273 /* c = a * 2**b */
274 int mp_mul_2d(mp_int *a, int b, mp_int *c);
275
276 /* b = a*2 */
277 int mp_mul_2(mp_int *a, mp_int *b);
278
279 /* c = a mod 2**d */
280 int mp_mod_2d(mp_int *a, int b, mp_int *c);
281
282 /* computes a = 2**b */
283 int mp_2expt(mp_int *a, int b);
284
285 /* Counts the number of lsbs which are zero before the first zero bit */
286 int mp_cnt_lsb(mp_int *a);
287
288 /* I Love Earth! */
289
290 /* makes a pseudo-random int of a given size */
291 int mp_rand(mp_int *a, int digits);
292
293 /* ---> binary operations <--- */
294 /* c = a XOR b */
295 int mp_xor(mp_int *a, mp_int *b, mp_int *c);
296
297 /* c = a OR b */
298 int mp_or(mp_int *a, mp_int *b, mp_int *c);
299
300 /* c = a AND b */
301 int mp_and(mp_int *a, mp_int *b, mp_int *c);
302
303 /* ---> Basic arithmetic <--- */
304
305 /* b = -a */
306 int mp_neg(mp_int *a, mp_int *b);
307
308 /* b = |a| */
309 int mp_abs(mp_int *a, mp_int *b);
310
311 /* compare a to b */
312 int mp_cmp(mp_int *a, mp_int *b);
313
314 /* compare |a| to |b| */
315 int mp_cmp_mag(mp_int *a, mp_int *b);
316
317 /* c = a + b */
318 int mp_add(mp_int *a, mp_int *b, mp_int *c);
319
320 /* c = a - b */
321 int mp_sub(mp_int *a, mp_int *b, mp_int *c);
322
323 /* c = a * b */
324 int mp_mul(mp_int *a, mp_int *b, mp_int *c);
325
326 /* b = a*a */
327 int mp_sqr(mp_int *a, mp_int *b);
328
329 /* a/b => cb + d == a */
330 int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
331
332 /* c = a mod b, 0 <= c < b */
333 int mp_mod(mp_int *a, mp_int *b, mp_int *c);
334
335 /* ---> single digit functions <--- */
336
337 /* compare against a single digit */
338 int mp_cmp_d(mp_int *a, mp_digit b);
339
340 /* c = a + b */
341 int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
342
343 /* c = a - b */
344 int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
345
346 /* c = a * b */
347 int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
348
349 /* a/b => cb + d == a */
350 int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
351
352 /* a/3 => 3c + d == a */
353 int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
354
355 /* c = a**b */
356 int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
357
358 /* c = a mod b, 0 <= c < b */
359 int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
360
361 /* ---> number theory <--- */
362
363 /* d = a + b (mod c) */
364 int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
365
366 /* d = a - b (mod c) */
367 int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
368
369 /* d = a * b (mod c) */
370 int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
371
372 /* c = a * a (mod b) */
373 int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
374
375 /* c = 1/a (mod b) */
376 int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
377
378 /* c = (a, b) */
379 int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
380
381 /* produces value such that U1*a + U2*b = U3 */
382 int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
383
384 /* c = [a, b] or (a*b)/(a, b) */
385 int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
386
387 /* finds one of the b'th root of a, such that |c|**b <= |a|
388 *
389 * returns error if a < 0 and b is even
390 */
391 int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
392
393 /* special sqrt algo */
394 int mp_sqrt(mp_int *arg, mp_int *ret);
395
396 /* is number a square? */
397 int mp_is_square(mp_int *arg, int *ret);
398
399 /* computes the jacobi c = (a | n) (or Legendre if b is prime) */
400 int mp_jacobi(mp_int *a, mp_int *n, int *c);
401
402 /* used to setup the Barrett reduction for a given modulus b */
403 int mp_reduce_setup(mp_int *a, mp_int *b);
404
405 /* Barrett Reduction, computes a (mod b) with a precomputed value c
406 *
407 * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
408 * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
409 */
410 int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
411
412 /* setups the montgomery reduction */
413 int mp_montgomery_setup(mp_int *a, mp_digit *mp);
414
415 /* computes a = B**n mod b without division or multiplication useful for
416 * normalizing numbers in a Montgomery system.
417 */
418 int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
419
420 /* computes x/R == x (mod N) via Montgomery Reduction */
421 int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
422
423 /* returns 1 if a is a valid DR modulus */
424 int mp_dr_is_modulus(mp_int *a);
425
426 /* sets the value of "d" required for mp_dr_reduce */
427 void mp_dr_setup(mp_int *a, mp_digit *d);
428
429 /* reduces a modulo b using the Diminished Radix method */
430 int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
431
432 /* returns true if a can be reduced with mp_reduce_2k */
433 int mp_reduce_is_2k(mp_int *a);
434
435 /* determines k value for 2k reduction */
436 int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
437
438 /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
439 int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
440
441 /* returns true if a can be reduced with mp_reduce_2k_l */
442 int mp_reduce_is_2k_l(mp_int *a);
443
444 /* determines k value for 2k reduction */
445 int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
446
447 /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
448 int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
449
450 /* d = a**b (mod c) */
451 int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
452
453 /* ---> Primes <--- */
454
455 /* number of primes */
456 #ifdef MP_8BIT
457 #define PRIME_SIZE 31
458 #else
459 #define PRIME_SIZE 256
460 #endif
461
462 /* table of first PRIME_SIZE primes */
463 extern const mp_digit ltm_prime_tab[];
464
465 /* result=1 if a is divisible by one of the first PRIME_SIZE primes */
466 int mp_prime_is_divisible(mp_int *a, int *result);
467
468 /* performs one Fermat test of "a" using base "b".
469 * Sets result to 0 if composite or 1 if probable prime
470 */
471 int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
472
473 /* performs one Miller-Rabin test of "a" using base "b".
474 * Sets result to 0 if composite or 1 if probable prime
475 */
476 int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
477
478 /* This gives [for a given bit size] the number of trials required
479 * such that Miller-Rabin gives a prob of failure lower than 2^-96
480 */
481 int mp_prime_rabin_miller_trials(int size);
482
483 /* performs t rounds of Miller-Rabin on "a" using the first
484 * t prime bases. Also performs an initial sieve of trial
485 * division. Determines if "a" is prime with probability
486 * of error no more than (1/4)**t.
487 *
488 * Sets result to 1 if probably prime, 0 otherwise
489 */
490 int mp_prime_is_prime(mp_int *a, int t, int *result);
491
492 /* finds the next prime after the number "a" using "t" trials
493 * of Miller-Rabin.
494 *
495 * bbs_style = 1 means the prime must be congruent to 3 mod 4
496 */
497 int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
498
499 /* makes a truly random prime of a given size (bytes),
500 * call with bbs = 1 if you want it to be congruent to 3 mod 4
501 *
502 * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
503 * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
504 * so it can be NULL
505 *
506 * The prime generated will be larger than 2^(8*size).
507 */
508 #define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
509
510 /* makes a truly random prime of a given size (bits),
511 *
512 * Flags are as follows:
513 *
514 * LTM_PRIME_BBS - make prime congruent to 3 mod 4
515 * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
516 * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
517 *
518 * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
519 * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
520 * so it can be NULL
521 *
522 */
523 int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
524
525 /* ---> radix conversion <--- */
526 int mp_count_bits(mp_int *a);
527
528 int mp_unsigned_bin_size(mp_int *a);
529 int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
530 int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
531 int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
532
533 int mp_signed_bin_size(mp_int *a);
534 int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
535 int mp_to_signed_bin(mp_int *a, unsigned char *b);
536 int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
537
538 int mp_read_radix(mp_int *a, const char *str, int radix);
539 int mp_toradix(mp_int *a, char *str, int radix);
540 int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
541 int mp_radix_size(mp_int *a, int radix, int *size);
542
543 int mp_fread(mp_int *a, int radix, FILE *stream);
544 int mp_fwrite(mp_int *a, int radix, FILE *stream);
545
546 #define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
547 #define mp_raw_size(mp) mp_signed_bin_size(mp)
548 #define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
549 #define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
550 #define mp_mag_size(mp) mp_unsigned_bin_size(mp)
551 #define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
552
553 #define mp_tobinary(M, S) mp_toradix((M), (S), 2)
554 #define mp_tooctal(M, S) mp_toradix((M), (S), 8)
555 #define mp_todecimal(M, S) mp_toradix((M), (S), 10)
556 #define mp_tohex(M, S) mp_toradix((M), (S), 16)
557
558 /* lowlevel functions, do not call! */
559 int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
560 int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
561 #define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
562 int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
563 int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
564 int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
565 int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
566 int fast_s_mp_sqr(mp_int *a, mp_int *b);
567 int s_mp_sqr(mp_int *a, mp_int *b);
568 int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
569 int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
570 int mp_karatsuba_sqr(mp_int *a, mp_int *b);
571 int mp_toom_sqr(mp_int *a, mp_int *b);
572 int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
573 int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
574 int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
575 int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
576 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
577 void bn_reverse(unsigned char *s, int len);
578
579 extern const char *mp_s_rmap;
580
581 #ifdef __cplusplus
582 }
583 #endif
584
585 #endif
586
587
588 /* $Source$ */
589 /* $Revision$ */
590 /* $Date$ */
0 #if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
1 #if defined(LTM2)
2 #define LTM3
3 #endif
4 #if defined(LTM1)
5 #define LTM2
6 #endif
7 #define LTM1
8
9 #if defined(LTM_ALL)
10 #define BN_ERROR_C
11 #define BN_FAST_MP_INVMOD_C
12 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
13 #define BN_FAST_S_MP_MUL_DIGS_C
14 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
15 #define BN_FAST_S_MP_SQR_C
16 #define BN_MP_2EXPT_C
17 #define BN_MP_ABS_C
18 #define BN_MP_ADD_C
19 #define BN_MP_ADD_D_C
20 #define BN_MP_ADDMOD_C
21 #define BN_MP_AND_C
22 #define BN_MP_CLAMP_C
23 #define BN_MP_CLEAR_C
24 #define BN_MP_CLEAR_MULTI_C
25 #define BN_MP_CMP_C
26 #define BN_MP_CMP_D_C
27 #define BN_MP_CMP_MAG_C
28 #define BN_MP_CNT_LSB_C
29 #define BN_MP_COPY_C
30 #define BN_MP_COUNT_BITS_C
31 #define BN_MP_DIV_C
32 #define BN_MP_DIV_2_C
33 #define BN_MP_DIV_2D_C
34 #define BN_MP_DIV_3_C
35 #define BN_MP_DIV_D_C
36 #define BN_MP_DR_IS_MODULUS_C
37 #define BN_MP_DR_REDUCE_C
38 #define BN_MP_DR_SETUP_C
39 #define BN_MP_EXCH_C
40 #define BN_MP_EXPT_D_C
41 #define BN_MP_EXPTMOD_C
42 #define BN_MP_EXPTMOD_FAST_C
43 #define BN_MP_EXTEUCLID_C
44 #define BN_MP_FREAD_C
45 #define BN_MP_FWRITE_C
46 #define BN_MP_GCD_C
47 #define BN_MP_GET_INT_C
48 #define BN_MP_GROW_C
49 #define BN_MP_INIT_C
50 #define BN_MP_INIT_COPY_C
51 #define BN_MP_INIT_MULTI_C
52 #define BN_MP_INIT_SET_C
53 #define BN_MP_INIT_SET_INT_C
54 #define BN_MP_INIT_SIZE_C
55 #define BN_MP_INVMOD_C
56 #define BN_MP_INVMOD_SLOW_C
57 #define BN_MP_IS_SQUARE_C
58 #define BN_MP_JACOBI_C
59 #define BN_MP_KARATSUBA_MUL_C
60 #define BN_MP_KARATSUBA_SQR_C
61 #define BN_MP_LCM_C
62 #define BN_MP_LSHD_C
63 #define BN_MP_MOD_C
64 #define BN_MP_MOD_2D_C
65 #define BN_MP_MOD_D_C
66 #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
67 #define BN_MP_MONTGOMERY_REDUCE_C
68 #define BN_MP_MONTGOMERY_SETUP_C
69 #define BN_MP_MUL_C
70 #define BN_MP_MUL_2_C
71 #define BN_MP_MUL_2D_C
72 #define BN_MP_MUL_D_C
73 #define BN_MP_MULMOD_C
74 #define BN_MP_N_ROOT_C
75 #define BN_MP_NEG_C
76 #define BN_MP_OR_C
77 #define BN_MP_PRIME_FERMAT_C
78 #define BN_MP_PRIME_IS_DIVISIBLE_C
79 #define BN_MP_PRIME_IS_PRIME_C
80 #define BN_MP_PRIME_MILLER_RABIN_C
81 #define BN_MP_PRIME_NEXT_PRIME_C
82 #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
83 #define BN_MP_PRIME_RANDOM_EX_C
84 #define BN_MP_RADIX_SIZE_C
85 #define BN_MP_RADIX_SMAP_C
86 #define BN_MP_RAND_C
87 #define BN_MP_READ_RADIX_C
88 #define BN_MP_READ_SIGNED_BIN_C
89 #define BN_MP_READ_UNSIGNED_BIN_C
90 #define BN_MP_REDUCE_C
91 #define BN_MP_REDUCE_2K_C
92 #define BN_MP_REDUCE_2K_L_C
93 #define BN_MP_REDUCE_2K_SETUP_C
94 #define BN_MP_REDUCE_2K_SETUP_L_C
95 #define BN_MP_REDUCE_IS_2K_C
96 #define BN_MP_REDUCE_IS_2K_L_C
97 #define BN_MP_REDUCE_SETUP_C
98 #define BN_MP_RSHD_C
99 #define BN_MP_SET_C
100 #define BN_MP_SET_INT_C
101 #define BN_MP_SHRINK_C
102 #define BN_MP_SIGNED_BIN_SIZE_C
103 #define BN_MP_SQR_C
104 #define BN_MP_SQRMOD_C
105 #define BN_MP_SQRT_C
106 #define BN_MP_SUB_C
107 #define BN_MP_SUB_D_C
108 #define BN_MP_SUBMOD_C
109 #define BN_MP_TO_SIGNED_BIN_C
110 #define BN_MP_TO_SIGNED_BIN_N_C
111 #define BN_MP_TO_UNSIGNED_BIN_C
112 #define BN_MP_TO_UNSIGNED_BIN_N_C
113 #define BN_MP_TOOM_MUL_C
114 #define BN_MP_TOOM_SQR_C
115 #define BN_MP_TORADIX_C
116 #define BN_MP_TORADIX_N_C
117 #define BN_MP_UNSIGNED_BIN_SIZE_C
118 #define BN_MP_XOR_C
119 #define BN_MP_ZERO_C
120 #define BN_PRIME_TAB_C
121 #define BN_REVERSE_C
122 #define BN_S_MP_ADD_C
123 #define BN_S_MP_EXPTMOD_C
124 #define BN_S_MP_MUL_DIGS_C
125 #define BN_S_MP_MUL_HIGH_DIGS_C
126 #define BN_S_MP_SQR_C
127 #define BN_S_MP_SUB_C
128 #define BNCORE_C
129 #endif
130
131 #if defined(BN_ERROR_C)
132 #define BN_MP_ERROR_TO_STRING_C
133 #endif
134
135 #if defined(BN_FAST_MP_INVMOD_C)
136 #define BN_MP_ISEVEN_C
137 #define BN_MP_INIT_MULTI_C
138 #define BN_MP_COPY_C
139 #define BN_MP_MOD_C
140 #define BN_MP_SET_C
141 #define BN_MP_DIV_2_C
142 #define BN_MP_ISODD_C
143 #define BN_MP_SUB_C
144 #define BN_MP_CMP_C
145 #define BN_MP_ISZERO_C
146 #define BN_MP_CMP_D_C
147 #define BN_MP_ADD_C
148 #define BN_MP_EXCH_C
149 #define BN_MP_CLEAR_MULTI_C
150 #endif
151
152 #if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
153 #define BN_MP_GROW_C
154 #define BN_MP_RSHD_C
155 #define BN_MP_CLAMP_C
156 #define BN_MP_CMP_MAG_C
157 #define BN_S_MP_SUB_C
158 #endif
159
160 #if defined(BN_FAST_S_MP_MUL_DIGS_C)
161 #define BN_MP_GROW_C
162 #define BN_MP_CLAMP_C
163 #endif
164
165 #if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
166 #define BN_MP_GROW_C
167 #define BN_MP_CLAMP_C
168 #endif
169
170 #if defined(BN_FAST_S_MP_SQR_C)
171 #define BN_MP_GROW_C
172 #define BN_MP_CLAMP_C
173 #endif
174
175 #if defined(BN_MP_2EXPT_C)
176 #define BN_MP_ZERO_C
177 #define BN_MP_GROW_C
178 #endif
179
180 #if defined(BN_MP_ABS_C)
181 #define BN_MP_COPY_C
182 #endif
183
184 #if defined(BN_MP_ADD_C)
185 #define BN_S_MP_ADD_C
186 #define BN_MP_CMP_MAG_C
187 #define BN_S_MP_SUB_C
188 #endif
189
190 #if defined(BN_MP_ADD_D_C)
191 #define BN_MP_GROW_C
192 #define BN_MP_SUB_D_C
193 #define BN_MP_CLAMP_C
194 #endif
195
196 #if defined(BN_MP_ADDMOD_C)
197 #define BN_MP_INIT_C
198 #define BN_MP_ADD_C
199 #define BN_MP_CLEAR_C
200 #define BN_MP_MOD_C
201 #endif
202
203 #if defined(BN_MP_AND_C)
204 #define BN_MP_INIT_COPY_C
205 #define BN_MP_CLAMP_C
206 #define BN_MP_EXCH_C
207 #define BN_MP_CLEAR_C
208 #endif
209
210 #if defined(BN_MP_CLAMP_C)
211 #endif
212
213 #if defined(BN_MP_CLEAR_C)
214 #endif
215
216 #if defined(BN_MP_CLEAR_MULTI_C)
217 #define BN_MP_CLEAR_C
218 #endif
219
220 #if defined(BN_MP_CMP_C)
221 #define BN_MP_CMP_MAG_C
222 #endif
223
224 #if defined(BN_MP_CMP_D_C)
225 #endif
226
227 #if defined(BN_MP_CMP_MAG_C)
228 #endif
229
230 #if defined(BN_MP_CNT_LSB_C)
231 #define BN_MP_ISZERO_C
232 #endif
233
234 #if defined(BN_MP_COPY_C)
235 #define BN_MP_GROW_C
236 #endif
237
238 #if defined(BN_MP_COUNT_BITS_C)
239 #endif
240
241 #if defined(BN_MP_DIV_C)
242 #define BN_MP_ISZERO_C
243 #define BN_MP_CMP_MAG_C
244 #define BN_MP_COPY_C
245 #define BN_MP_ZERO_C
246 #define BN_MP_INIT_MULTI_C
247 #define BN_MP_SET_C
248 #define BN_MP_COUNT_BITS_C
249 #define BN_MP_ABS_C
250 #define BN_MP_MUL_2D_C
251 #define BN_MP_CMP_C
252 #define BN_MP_SUB_C
253 #define BN_MP_ADD_C
254 #define BN_MP_DIV_2D_C
255 #define BN_MP_EXCH_C
256 #define BN_MP_CLEAR_MULTI_C
257 #define BN_MP_INIT_SIZE_C
258 #define BN_MP_INIT_C
259 #define BN_MP_INIT_COPY_C
260 #define BN_MP_LSHD_C
261 #define BN_MP_RSHD_C
262 #define BN_MP_MUL_D_C
263 #define BN_MP_CLAMP_C
264 #define BN_MP_CLEAR_C
265 #endif
266
267 #if defined(BN_MP_DIV_2_C)
268 #define BN_MP_GROW_C
269 #define BN_MP_CLAMP_C
270 #endif
271
272 #if defined(BN_MP_DIV_2D_C)
273 #define BN_MP_COPY_C
274 #define BN_MP_ZERO_C
275 #define BN_MP_INIT_C
276 #define BN_MP_MOD_2D_C
277 #define BN_MP_CLEAR_C
278 #define BN_MP_RSHD_C
279 #define BN_MP_CLAMP_C
280 #define BN_MP_EXCH_C
281 #endif
282
283 #if defined(BN_MP_DIV_3_C)
284 #define BN_MP_INIT_SIZE_C
285 #define BN_MP_CLAMP_C
286 #define BN_MP_EXCH_C
287 #define BN_MP_CLEAR_C
288 #endif
289
290 #if defined(BN_MP_DIV_D_C)
291 #define BN_MP_ISZERO_C
292 #define BN_MP_COPY_C
293 #define BN_MP_DIV_2D_C
294 #define BN_MP_DIV_3_C
295 #define BN_MP_INIT_SIZE_C
296 #define BN_MP_CLAMP_C
297 #define BN_MP_EXCH_C
298 #define BN_MP_CLEAR_C
299 #endif
300
301 #if defined(BN_MP_DR_IS_MODULUS_C)
302 #endif
303
304 #if defined(BN_MP_DR_REDUCE_C)
305 #define BN_MP_GROW_C
306 #define BN_MP_CLAMP_C
307 #define BN_MP_CMP_MAG_C
308 #define BN_S_MP_SUB_C
309 #endif
310
311 #if defined(BN_MP_DR_SETUP_C)
312 #endif
313
314 #if defined(BN_MP_EXCH_C)
315 #endif
316
317 #if defined(BN_MP_EXPT_D_C)
318 #define BN_MP_INIT_COPY_C
319 #define BN_MP_SET_C
320 #define BN_MP_SQR_C
321 #define BN_MP_CLEAR_C
322 #define BN_MP_MUL_C
323 #endif
324
325 #if defined(BN_MP_EXPTMOD_C)
326 #define BN_MP_INIT_C
327 #define BN_MP_INVMOD_C
328 #define BN_MP_CLEAR_C
329 #define BN_MP_ABS_C
330 #define BN_MP_CLEAR_MULTI_C
331 #define BN_MP_REDUCE_IS_2K_L_C
332 #define BN_S_MP_EXPTMOD_C
333 #define BN_MP_DR_IS_MODULUS_C
334 #define BN_MP_REDUCE_IS_2K_C
335 #define BN_MP_ISODD_C
336 #define BN_MP_EXPTMOD_FAST_C
337 #endif
338
339 #if defined(BN_MP_EXPTMOD_FAST_C)
340 #define BN_MP_COUNT_BITS_C
341 #define BN_MP_INIT_C
342 #define BN_MP_CLEAR_C
343 #define BN_MP_MONTGOMERY_SETUP_C
344 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
345 #define BN_MP_MONTGOMERY_REDUCE_C
346 #define BN_MP_DR_SETUP_C
347 #define BN_MP_DR_REDUCE_C
348 #define BN_MP_REDUCE_2K_SETUP_C
349 #define BN_MP_REDUCE_2K_C
350 #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
351 #define BN_MP_MULMOD_C
352 #define BN_MP_SET_C
353 #define BN_MP_MOD_C
354 #define BN_MP_COPY_C
355 #define BN_MP_SQR_C
356 #define BN_MP_MUL_C
357 #define BN_MP_EXCH_C
358 #endif
359
360 #if defined(BN_MP_EXTEUCLID_C)
361 #define BN_MP_INIT_MULTI_C
362 #define BN_MP_SET_C
363 #define BN_MP_COPY_C
364 #define BN_MP_ISZERO_C
365 #define BN_MP_DIV_C
366 #define BN_MP_MUL_C
367 #define BN_MP_SUB_C
368 #define BN_MP_NEG_C
369 #define BN_MP_EXCH_C
370 #define BN_MP_CLEAR_MULTI_C
371 #endif
372
373 #if defined(BN_MP_FREAD_C)
374 #define BN_MP_ZERO_C
375 #define BN_MP_S_RMAP_C
376 #define BN_MP_MUL_D_C
377 #define BN_MP_ADD_D_C
378 #define BN_MP_CMP_D_C
379 #endif
380
381 #if defined(BN_MP_FWRITE_C)
382 #define BN_MP_RADIX_SIZE_C
383 #define BN_MP_TORADIX_C
384 #endif
385
386 #if defined(BN_MP_GCD_C)
387 #define BN_MP_ISZERO_C
388 #define BN_MP_ABS_C
389 #define BN_MP_ZERO_C
390 #define BN_MP_INIT_COPY_C
391 #define BN_MP_CNT_LSB_C
392 #define BN_MP_DIV_2D_C
393 #define BN_MP_CMP_MAG_C
394 #define BN_MP_EXCH_C
395 #define BN_S_MP_SUB_C
396 #define BN_MP_MUL_2D_C
397 #define BN_MP_CLEAR_C
398 #endif
399
400 #if defined(BN_MP_GET_INT_C)
401 #endif
402
403 #if defined(BN_MP_GROW_C)
404 #endif
405
406 #if defined(BN_MP_INIT_C)
407 #endif
408
409 #if defined(BN_MP_INIT_COPY_C)
410 #define BN_MP_COPY_C
411 #endif
412
413 #if defined(BN_MP_INIT_MULTI_C)
414 #define BN_MP_ERR_C
415 #define BN_MP_INIT_C
416 #define BN_MP_CLEAR_C
417 #endif
418
419 #if defined(BN_MP_INIT_SET_C)
420 #define BN_MP_INIT_C
421 #define BN_MP_SET_C
422 #endif
423
424 #if defined(BN_MP_INIT_SET_INT_C)
425 #define BN_MP_INIT_C
426 #define BN_MP_SET_INT_C
427 #endif
428
429 #if defined(BN_MP_INIT_SIZE_C)
430 #define BN_MP_INIT_C
431 #endif
432
433 #if defined(BN_MP_INVMOD_C)
434 #define BN_MP_ISZERO_C
435 #define BN_MP_ISODD_C
436 #define BN_FAST_MP_INVMOD_C
437 #define BN_MP_INVMOD_SLOW_C
438 #endif
439
440 #if defined(BN_MP_INVMOD_SLOW_C)
441 #define BN_MP_ISZERO_C
442 #define BN_MP_INIT_MULTI_C
443 #define BN_MP_MOD_C
444 #define BN_MP_COPY_C
445 #define BN_MP_ISEVEN_C
446 #define BN_MP_SET_C
447 #define BN_MP_DIV_2_C
448 #define BN_MP_ISODD_C
449 #define BN_MP_ADD_C
450 #define BN_MP_SUB_C
451 #define BN_MP_CMP_C
452 #define BN_MP_CMP_D_C
453 #define BN_MP_CMP_MAG_C
454 #define BN_MP_EXCH_C
455 #define BN_MP_CLEAR_MULTI_C
456 #endif
457
458 #if defined(BN_MP_IS_SQUARE_C)
459 #define BN_MP_MOD_D_C
460 #define BN_MP_INIT_SET_INT_C
461 #define BN_MP_MOD_C
462 #define BN_MP_GET_INT_C
463 #define BN_MP_SQRT_C
464 #define BN_MP_SQR_C
465 #define BN_MP_CMP_MAG_C
466 #define BN_MP_CLEAR_C
467 #endif
468
469 #if defined(BN_MP_JACOBI_C)
470 #define BN_MP_CMP_D_C
471 #define BN_MP_ISZERO_C
472 #define BN_MP_INIT_COPY_C
473 #define BN_MP_CNT_LSB_C
474 #define BN_MP_DIV_2D_C
475 #define BN_MP_MOD_C
476 #define BN_MP_CLEAR_C
477 #endif
478
479 #if defined(BN_MP_KARATSUBA_MUL_C)
480 #define BN_MP_MUL_C
481 #define BN_MP_INIT_SIZE_C
482 #define BN_MP_CLAMP_C
483 #define BN_MP_SUB_C
484 #define BN_MP_ADD_C
485 #define BN_MP_LSHD_C
486 #define BN_MP_CLEAR_C
487 #endif
488
489 #if defined(BN_MP_KARATSUBA_SQR_C)
490 #define BN_MP_INIT_SIZE_C
491 #define BN_MP_CLAMP_C
492 #define BN_MP_SQR_C
493 #define BN_MP_SUB_C
494 #define BN_S_MP_ADD_C
495 #define BN_MP_LSHD_C
496 #define BN_MP_ADD_C
497 #define BN_MP_CLEAR_C
498 #endif
499
500 #if defined(BN_MP_LCM_C)
501 #define BN_MP_INIT_MULTI_C
502 #define BN_MP_GCD_C
503 #define BN_MP_CMP_MAG_C
504 #define BN_MP_DIV_C
505 #define BN_MP_MUL_C
506 #define BN_MP_CLEAR_MULTI_C
507 #endif
508
509 #if defined(BN_MP_LSHD_C)
510 #define BN_MP_GROW_C
511 #define BN_MP_RSHD_C
512 #endif
513
514 #if defined(BN_MP_MOD_C)
515 #define BN_MP_INIT_C
516 #define BN_MP_DIV_C
517 #define BN_MP_CLEAR_C
518 #define BN_MP_ADD_C
519 #define BN_MP_EXCH_C
520 #endif
521
522 #if defined(BN_MP_MOD_2D_C)
523 #define BN_MP_ZERO_C
524 #define BN_MP_COPY_C
525 #define BN_MP_CLAMP_C
526 #endif
527
528 #if defined(BN_MP_MOD_D_C)
529 #define BN_MP_DIV_D_C
530 #endif
531
532 #if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
533 #define BN_MP_COUNT_BITS_C
534 #define BN_MP_2EXPT_C
535 #define BN_MP_SET_C
536 #define BN_MP_MUL_2_C
537 #define BN_MP_CMP_MAG_C
538 #define BN_S_MP_SUB_C
539 #endif
540
541 #if defined(BN_MP_MONTGOMERY_REDUCE_C)
542 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
543 #define BN_MP_GROW_C
544 #define BN_MP_CLAMP_C
545 #define BN_MP_RSHD_C
546 #define BN_MP_CMP_MAG_C
547 #define BN_S_MP_SUB_C
548 #endif
549
550 #if defined(BN_MP_MONTGOMERY_SETUP_C)
551 #endif
552
553 #if defined(BN_MP_MUL_C)
554 #define BN_MP_TOOM_MUL_C
555 #define BN_MP_KARATSUBA_MUL_C
556 #define BN_FAST_S_MP_MUL_DIGS_C
557 #define BN_S_MP_MUL_C
558 #define BN_S_MP_MUL_DIGS_C
559 #endif
560
561 #if defined(BN_MP_MUL_2_C)
562 #define BN_MP_GROW_C
563 #endif
564
565 #if defined(BN_MP_MUL_2D_C)
566 #define BN_MP_COPY_C
567 #define BN_MP_GROW_C
568 #define BN_MP_LSHD_C
569 #define BN_MP_CLAMP_C
570 #endif
571
572 #if defined(BN_MP_MUL_D_C)
573 #define BN_MP_GROW_C
574 #define BN_MP_CLAMP_C
575 #endif
576
577 #if defined(BN_MP_MULMOD_C)
578 #define BN_MP_INIT_C
579 #define BN_MP_MUL_C
580 #define BN_MP_CLEAR_C
581 #define BN_MP_MOD_C
582 #endif
583
584 #if defined(BN_MP_N_ROOT_C)
585 #define BN_MP_INIT_C
586 #define BN_MP_SET_C
587 #define BN_MP_COPY_C
588 #define BN_MP_EXPT_D_C
589 #define BN_MP_MUL_C
590 #define BN_MP_SUB_C
591 #define BN_MP_MUL_D_C
592 #define BN_MP_DIV_C
593 #define BN_MP_CMP_C
594 #define BN_MP_SUB_D_C
595 #define BN_MP_EXCH_C
596 #define BN_MP_CLEAR_C
597 #endif
598
599 #if defined(BN_MP_NEG_C)
600 #define BN_MP_COPY_C
601 #define BN_MP_ISZERO_C
602 #endif
603
604 #if defined(BN_MP_OR_C)
605 #define BN_MP_INIT_COPY_C
606 #define BN_MP_CLAMP_C
607 #define BN_MP_EXCH_C
608 #define BN_MP_CLEAR_C
609 #endif
610
611 #if defined(BN_MP_PRIME_FERMAT_C)
612 #define BN_MP_CMP_D_C
613 #define BN_MP_INIT_C
614 #define BN_MP_EXPTMOD_C
615 #define BN_MP_CMP_C
616 #define BN_MP_CLEAR_C
617 #endif
618
619 #if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
620 #define BN_MP_MOD_D_C
621 #endif
622
623 #if defined(BN_MP_PRIME_IS_PRIME_C)
624 #define BN_MP_CMP_D_C
625 #define BN_MP_PRIME_IS_DIVISIBLE_C
626 #define BN_MP_INIT_C
627 #define BN_MP_SET_C
628 #define BN_MP_PRIME_MILLER_RABIN_C
629 #define BN_MP_CLEAR_C
630 #endif
631
632 #if defined(BN_MP_PRIME_MILLER_RABIN_C)
633 #define BN_MP_CMP_D_C
634 #define BN_MP_INIT_COPY_C
635 #define BN_MP_SUB_D_C
636 #define BN_MP_CNT_LSB_C
637 #define BN_MP_DIV_2D_C
638 #define BN_MP_EXPTMOD_C
639 #define BN_MP_CMP_C
640 #define BN_MP_SQRMOD_C
641 #define BN_MP_CLEAR_C
642 #endif
643
644 #if defined(BN_MP_PRIME_NEXT_PRIME_C)
645 #define BN_MP_CMP_D_C
646 #define BN_MP_SET_C
647 #define BN_MP_SUB_D_C
648 #define BN_MP_ISEVEN_C
649 #define BN_MP_MOD_D_C
650 #define BN_MP_INIT_C
651 #define BN_MP_ADD_D_C
652 #define BN_MP_PRIME_MILLER_RABIN_C
653 #define BN_MP_CLEAR_C
654 #endif
655
656 #if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
657 #endif
658
659 #if defined(BN_MP_PRIME_RANDOM_EX_C)
660 #define BN_MP_READ_UNSIGNED_BIN_C
661 #define BN_MP_PRIME_IS_PRIME_C
662 #define BN_MP_SUB_D_C
663 #define BN_MP_DIV_2_C
664 #define BN_MP_MUL_2_C
665 #define BN_MP_ADD_D_C
666 #endif
667
668 #if defined(BN_MP_RADIX_SIZE_C)
669 #define BN_MP_COUNT_BITS_C
670 #define BN_MP_INIT_COPY_C
671 #define BN_MP_ISZERO_C
672 #define BN_MP_DIV_D_C
673 #define BN_MP_CLEAR_C
674 #endif
675
676 #if defined(BN_MP_RADIX_SMAP_C)
677 #define BN_MP_S_RMAP_C
678 #endif
679
680 #if defined(BN_MP_RAND_C)
681 #define BN_MP_ZERO_C
682 #define BN_MP_ADD_D_C
683 #define BN_MP_LSHD_C
684 #endif
685
686 #if defined(BN_MP_READ_RADIX_C)
687 #define BN_MP_ZERO_C
688 #define BN_MP_S_RMAP_C
689 #define BN_MP_RADIX_SMAP_C
690 #define BN_MP_MUL_D_C
691 #define BN_MP_ADD_D_C
692 #define BN_MP_ISZERO_C
693 #endif
694
695 #if defined(BN_MP_READ_SIGNED_BIN_C)
696 #define BN_MP_READ_UNSIGNED_BIN_C
697 #endif
698
699 #if defined(BN_MP_READ_UNSIGNED_BIN_C)
700 #define BN_MP_GROW_C
701 #define BN_MP_ZERO_C
702 #define BN_MP_MUL_2D_C
703 #define BN_MP_CLAMP_C
704 #endif
705
706 #if defined(BN_MP_REDUCE_C)
707 #define BN_MP_REDUCE_SETUP_C
708 #define BN_MP_INIT_COPY_C
709 #define BN_MP_RSHD_C
710 #define BN_MP_MUL_C
711 #define BN_S_MP_MUL_HIGH_DIGS_C
712 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
713 #define BN_MP_MOD_2D_C
714 #define BN_S_MP_MUL_DIGS_C
715 #define BN_MP_SUB_C
716 #define BN_MP_CMP_D_C
717 #define BN_MP_SET_C
718 #define BN_MP_LSHD_C
719 #define BN_MP_ADD_C
720 #define BN_MP_CMP_C
721 #define BN_S_MP_SUB_C
722 #define BN_MP_CLEAR_C
723 #endif
724
725 #if defined(BN_MP_REDUCE_2K_C)
726 #define BN_MP_INIT_C
727 #define BN_MP_COUNT_BITS_C
728 #define BN_MP_DIV_2D_C
729 #define BN_MP_MUL_D_C
730 #define BN_S_MP_ADD_C
731 #define BN_MP_CMP_MAG_C
732 #define BN_S_MP_SUB_C
733 #define BN_MP_CLEAR_C
734 #endif
735
736 #if defined(BN_MP_REDUCE_2K_L_C)
737 #define BN_MP_INIT_C
738 #define BN_MP_COUNT_BITS_C
739 #define BN_MP_DIV_2D_C
740 #define BN_MP_MUL_C
741 #define BN_S_MP_ADD_C
742 #define BN_MP_CMP_MAG_C
743 #define BN_S_MP_SUB_C
744 #define BN_MP_CLEAR_C
745 #endif
746
747 #if defined(BN_MP_REDUCE_2K_SETUP_C)
748 #define BN_MP_INIT_C
749 #define BN_MP_COUNT_BITS_C
750 #define BN_MP_2EXPT_C
751 #define BN_MP_CLEAR_C
752 #define BN_S_MP_SUB_C
753 #endif
754
755 #if defined(BN_MP_REDUCE_2K_SETUP_L_C)
756 #define BN_MP_INIT_C
757 #define BN_MP_2EXPT_C
758 #define BN_MP_COUNT_BITS_C
759 #define BN_S_MP_SUB_C
760 #define BN_MP_CLEAR_C
761 #endif
762
763 #if defined(BN_MP_REDUCE_IS_2K_C)
764 #define BN_MP_REDUCE_2K_C
765 #define BN_MP_COUNT_BITS_C
766 #endif
767
768 #if defined(BN_MP_REDUCE_IS_2K_L_C)
769 #endif
770
771 #if defined(BN_MP_REDUCE_SETUP_C)
772 #define BN_MP_2EXPT_C
773 #define BN_MP_DIV_C
774 #endif
775
776 #if defined(BN_MP_RSHD_C)
777 #define BN_MP_ZERO_C
778 #endif
779
780 #if defined(BN_MP_SET_C)
781 #define BN_MP_ZERO_C
782 #endif
783
784 #if defined(BN_MP_SET_INT_C)
785 #define BN_MP_ZERO_C
786 #define BN_MP_MUL_2D_C
787 #define BN_MP_CLAMP_C
788 #endif
789
790 #if defined(BN_MP_SHRINK_C)
791 #endif
792
793 #if defined(BN_MP_SIGNED_BIN_SIZE_C)
794 #define BN_MP_UNSIGNED_BIN_SIZE_C
795 #endif
796
797 #if defined(BN_MP_SQR_C)
798 #define BN_MP_TOOM_SQR_C
799 #define BN_MP_KARATSUBA_SQR_C
800 #define BN_FAST_S_MP_SQR_C
801 #define BN_S_MP_SQR_C
802 #endif
803
804 #if defined(BN_MP_SQRMOD_C)
805 #define BN_MP_INIT_C
806 #define BN_MP_SQR_C
807 #define BN_MP_CLEAR_C
808 #define BN_MP_MOD_C
809 #endif
810
811 #if defined(BN_MP_SQRT_C)
812 #define BN_MP_N_ROOT_C
813 #define BN_MP_ISZERO_C
814 #define BN_MP_ZERO_C
815 #define BN_MP_INIT_COPY_C
816 #define BN_MP_RSHD_C
817 #define BN_MP_DIV_C
818 #define BN_MP_ADD_C
819 #define BN_MP_DIV_2_C
820 #define BN_MP_CMP_MAG_C
821 #define BN_MP_EXCH_C
822 #define BN_MP_CLEAR_C
823 #endif
824
825 #if defined(BN_MP_SUB_C)
826 #define BN_S_MP_ADD_C
827 #define BN_MP_CMP_MAG_C
828 #define BN_S_MP_SUB_C
829 #endif
830
831 #if defined(BN_MP_SUB_D_C)
832 #define BN_MP_GROW_C
833 #define BN_MP_ADD_D_C
834 #define BN_MP_CLAMP_C
835 #endif
836
837 #if defined(BN_MP_SUBMOD_C)
838 #define BN_MP_INIT_C
839 #define BN_MP_SUB_C
840 #define BN_MP_CLEAR_C
841 #define BN_MP_MOD_C
842 #endif
843
844 #if defined(BN_MP_TO_SIGNED_BIN_C)
845 #define BN_MP_TO_UNSIGNED_BIN_C
846 #endif
847
848 #if defined(BN_MP_TO_SIGNED_BIN_N_C)
849 #define BN_MP_SIGNED_BIN_SIZE_C
850 #define BN_MP_TO_SIGNED_BIN_C
851 #endif
852
853 #if defined(BN_MP_TO_UNSIGNED_BIN_C)
854 #define BN_MP_INIT_COPY_C
855 #define BN_MP_ISZERO_C
856 #define BN_MP_DIV_2D_C
857 #define BN_MP_CLEAR_C
858 #endif
859
860 #if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
861 #define BN_MP_UNSIGNED_BIN_SIZE_C
862 #define BN_MP_TO_UNSIGNED_BIN_C
863 #endif
864
865 #if defined(BN_MP_TOOM_MUL_C)
866 #define BN_MP_INIT_MULTI_C
867 #define BN_MP_MOD_2D_C
868 #define BN_MP_COPY_C
869 #define BN_MP_RSHD_C
870 #define BN_MP_MUL_C
871 #define BN_MP_MUL_2_C
872 #define BN_MP_ADD_C
873 #define BN_MP_SUB_C
874 #define BN_MP_DIV_2_C
875 #define BN_MP_MUL_2D_C
876 #define BN_MP_MUL_D_C
877 #define BN_MP_DIV_3_C
878 #define BN_MP_LSHD_C
879 #define BN_MP_CLEAR_MULTI_C
880 #endif
881
882 #if defined(BN_MP_TOOM_SQR_C)
883 #define BN_MP_INIT_MULTI_C
884 #define BN_MP_MOD_2D_C
885 #define BN_MP_COPY_C
886 #define BN_MP_RSHD_C
887 #define BN_MP_SQR_C
888 #define BN_MP_MUL_2_C
889 #define BN_MP_ADD_C
890 #define BN_MP_SUB_C
891 #define BN_MP_DIV_2_C
892 #define BN_MP_MUL_2D_C
893 #define BN_MP_MUL_D_C
894 #define BN_MP_DIV_3_C
895 #define BN_MP_LSHD_C
896 #define BN_MP_CLEAR_MULTI_C
897 #endif
898
899 #if defined(BN_MP_TORADIX_C)
900 #define BN_MP_ISZERO_C
901 #define BN_MP_INIT_COPY_C
902 #define BN_MP_DIV_D_C
903 #define BN_MP_CLEAR_C
904 #define BN_MP_S_RMAP_C
905 #endif
906
907 #if defined(BN_MP_TORADIX_N_C)
908 #define BN_MP_ISZERO_C
909 #define BN_MP_INIT_COPY_C
910 #define BN_MP_DIV_D_C
911 #define BN_MP_CLEAR_C
912 #define BN_MP_S_RMAP_C
913 #endif
914
915 #if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
916 #define BN_MP_COUNT_BITS_C
917 #endif
918
919 #if defined(BN_MP_XOR_C)
920 #define BN_MP_INIT_COPY_C
921 #define BN_MP_CLAMP_C
922 #define BN_MP_EXCH_C
923 #define BN_MP_CLEAR_C
924 #endif
925
926 #if defined(BN_MP_ZERO_C)
927 #endif
928
929 #if defined(BN_PRIME_TAB_C)
930 #endif
931
932 #if defined(BN_REVERSE_C)
933 #endif
934
935 #if defined(BN_S_MP_ADD_C)
936 #define BN_MP_GROW_C
937 #define BN_MP_CLAMP_C
938 #endif
939
940 #if defined(BN_S_MP_EXPTMOD_C)
941 #define BN_MP_COUNT_BITS_C
942 #define BN_MP_INIT_C
943 #define BN_MP_CLEAR_C
944 #define BN_MP_REDUCE_SETUP_C
945 #define BN_MP_REDUCE_C
946 #define BN_MP_REDUCE_2K_SETUP_L_C
947 #define BN_MP_REDUCE_2K_L_C
948 #define BN_MP_MOD_C
949 #define BN_MP_COPY_C
950 #define BN_MP_SQR_C
951 #define BN_MP_MUL_C
952 #define BN_MP_SET_C
953 #define BN_MP_EXCH_C
954 #endif
955
956 #if defined(BN_S_MP_MUL_DIGS_C)
957 #define BN_FAST_S_MP_MUL_DIGS_C
958 #define BN_MP_INIT_SIZE_C
959 #define BN_MP_CLAMP_C
960 #define BN_MP_EXCH_C
961 #define BN_MP_CLEAR_C
962 #endif
963
964 #if defined(BN_S_MP_MUL_HIGH_DIGS_C)
965 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
966 #define BN_MP_INIT_SIZE_C
967 #define BN_MP_CLAMP_C
968 #define BN_MP_EXCH_C
969 #define BN_MP_CLEAR_C
970 #endif
971
972 #if defined(BN_S_MP_SQR_C)
973 #define BN_MP_INIT_SIZE_C
974 #define BN_MP_CLAMP_C
975 #define BN_MP_EXCH_C
976 #define BN_MP_CLEAR_C
977 #endif
978
979 #if defined(BN_S_MP_SUB_C)
980 #define BN_MP_GROW_C
981 #define BN_MP_CLAMP_C
982 #endif
983
984 #if defined(BNCORE_C)
985 #endif
986
987 #ifdef LTM3
988 #define LTM_LAST
989 #endif
990 #include <tommath_superclass.h>
991 #include <tommath_class.h>
992 #else
993 #define LTM_LAST
994 #endif
995
996 /* $Source$ */
997 /* $Revision$ */
998 /* $Date$ */
0 /* super class file for PK algos */
1
2 /* default ... include all MPI */
3 #define LTM_ALL
4
5 /* RSA only (does not support DH/DSA/ECC) */
6 /* #define SC_RSA_1 */
7
8 /* For reference.... On an Athlon64 optimizing for speed...
9
10 LTM's mpi.o with all functions [striped] is 142KiB in size.
11
12 */
13
14 /* Works for RSA only, mpi.o is 68KiB */
15 #ifdef SC_RSA_1
16 #define BN_MP_SHRINK_C
17 #define BN_MP_LCM_C
18 #define BN_MP_PRIME_RANDOM_EX_C
19 #define BN_MP_INVMOD_C
20 #define BN_MP_GCD_C
21 #define BN_MP_MOD_C
22 #define BN_MP_MULMOD_C
23 #define BN_MP_ADDMOD_C
24 #define BN_MP_EXPTMOD_C
25 #define BN_MP_SET_INT_C
26 #define BN_MP_INIT_MULTI_C
27 #define BN_MP_CLEAR_MULTI_C
28 #define BN_MP_UNSIGNED_BIN_SIZE_C
29 #define BN_MP_TO_UNSIGNED_BIN_C
30 #define BN_MP_MOD_D_C
31 #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
32 #define BN_REVERSE_C
33 #define BN_PRIME_TAB_C
34
35 /* other modifiers */
36 #define BN_MP_DIV_SMALL /* Slower division, not critical */
37
38 /* here we are on the last pass so we turn things off. The functions classes are still there
39 * but we remove them specifically from the build. This also invokes tweaks in functions
40 * like removing support for even moduli, etc...
41 */
42 #ifdef LTM_LAST
43 #undef BN_MP_TOOM_MUL_C
44 #undef BN_MP_TOOM_SQR_C
45 #undef BN_MP_KARATSUBA_MUL_C
46 #undef BN_MP_KARATSUBA_SQR_C
47 #undef BN_MP_REDUCE_C
48 #undef BN_MP_REDUCE_SETUP_C
49 #undef BN_MP_DR_IS_MODULUS_C
50 #undef BN_MP_DR_SETUP_C
51 #undef BN_MP_DR_REDUCE_C
52 #undef BN_MP_REDUCE_IS_2K_C
53 #undef BN_MP_REDUCE_2K_SETUP_C
54 #undef BN_MP_REDUCE_2K_C
55 #undef BN_S_MP_EXPTMOD_C
56 #undef BN_MP_DIV_3_C
57 #undef BN_S_MP_MUL_HIGH_DIGS_C
58 #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
59 #undef BN_FAST_MP_INVMOD_C
60
61 /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
62 * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
63 * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
64 * trouble.
65 */
66 #undef BN_S_MP_MUL_DIGS_C
67 #undef BN_S_MP_SQR_C
68 #undef BN_MP_MONTGOMERY_REDUCE_C
69 #endif
70
71 #endif
72
73 /* $Source$ */
74 /* $Revision$ */
75 /* $Date$ */