Przeglądaj źródła

[crypto] Add big-integer library for RSA calculations

RSA requires modular exponentiation using arbitrarily large integers.
Given the sizes of the modulus and exponent, all required calculations
can be done without any further dynamic storage allocation.  The x86
architecture allows for efficient large integer support via inline
assembly using the instructions that take advantage of the carry flag
(e.g. "adcl", "rcrl").

This implemention is approximately 80% smaller than the (more generic)
AXTLS implementation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 lat temu
rodzic
commit
071184a6e4

+ 90
- 0
src/arch/x86/core/x86_bigint.c Wyświetl plik

@@ -0,0 +1,90 @@
1
+/*
2
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <stdint.h>
22
+#include <string.h>
23
+#include <ipxe/bigint.h>
24
+
25
+/** @file
26
+ *
27
+ * Big integer support
28
+ */
29
+
30
+/**
31
+ * Multiply big integers
32
+ *
33
+ * @v multiplicand0	Element 0 of big integer to be multiplied
34
+ * @v multiplier0	Element 0 of big integer to be multiplied
35
+ * @v result0		Element 0 of big integer to hold result
36
+ * @v size		Number of elements
37
+ */
38
+void bigint_multiply_raw ( const uint32_t *multiplicand0,
39
+			   const uint32_t *multiplier0,
40
+			   uint32_t *result0, unsigned int size ) {
41
+	const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
42
+		( ( const void * ) multiplicand0 );
43
+	const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
44
+		( ( const void * ) multiplier0 );
45
+	bigint_t ( size * 2 ) __attribute__ (( may_alias )) *result =
46
+		( ( void * ) result0 );
47
+	unsigned int i;
48
+	unsigned int j;
49
+	uint32_t multiplicand_element;
50
+	uint32_t multiplier_element;
51
+	uint32_t *result_elements;
52
+	uint32_t discard_a;
53
+	uint32_t discard_d;
54
+	long index;
55
+
56
+	/* Zero result */
57
+	memset ( result, 0, sizeof ( *result ) );
58
+
59
+	/* Multiply integers one element at a time */
60
+	for ( i = 0 ; i < size ; i++ ) {
61
+		multiplicand_element = multiplicand->element[i];
62
+		for ( j = 0 ; j < size ; j++ ) {
63
+			multiplier_element = multiplier->element[j];
64
+			result_elements = &result->element[ i + j ];
65
+			/* Perform a single multiply, and add the
66
+			 * resulting double-element into the result,
67
+			 * carrying as necessary.  The carry can
68
+			 * never overflow beyond the end of the
69
+			 * result, since:
70
+			 *
71
+			 *     a < 2^{n}, b < 2^{n} => ab < 2^{2n}
72
+			 */
73
+			__asm__ __volatile__ ( "mull %4\n\t"
74
+					       "addl %%eax, (%5,%2,4)\n\t"
75
+					       "adcl %%edx, 4(%5,%2,4)\n\t"
76
+					       "\n1:\n\t"
77
+					       "adcl $0, 8(%5,%2,4)\n\t"
78
+					       "inc %2\n\t"
79
+						       /* Does not affect CF */
80
+					       "jc 1b\n\t"
81
+					       : "=&a" ( discard_a ),
82
+						 "=&d" ( discard_d ),
83
+						 "=&r" ( index )
84
+					       : "0" ( multiplicand_element ),
85
+						 "g" ( multiplier_element ),
86
+						 "r" ( result_elements ),
87
+						 "2" ( 0 ) );
88
+		}
89
+	}
90
+}

+ 318
- 0
src/arch/x86/include/bits/bigint.h Wyświetl plik

@@ -0,0 +1,318 @@
1
+#ifndef _BITS_BIGINT_H
2
+#define _BITS_BIGINT_H
3
+
4
+/** @file
5
+ *
6
+ * Big integer support
7
+ */
8
+
9
+FILE_LICENCE ( GPL2_OR_LATER );
10
+
11
+#include <stdint.h>
12
+#include <string.h>
13
+
14
+/** Element of a big integer */
15
+typedef uint32_t bigint_element_t;
16
+
17
+/**
18
+ * Initialise big integer
19
+ *
20
+ * @v value0		Element 0 of big integer to initialise
21
+ * @v size		Number of elements
22
+ * @v data		Raw data
23
+ * @v len		Length of raw data
24
+ */
25
+static inline __attribute__ (( always_inline )) void
26
+bigint_init_raw ( uint32_t *value0, unsigned int size,
27
+		  const void *data, size_t len ) {
28
+	long pad_len = ( sizeof ( bigint_t ( size ) ) - len );
29
+	void *discard_D;
30
+	long discard_c;
31
+
32
+	/* Copy raw data in reverse order, padding with zeros */
33
+	__asm__ __volatile__ ( "\n1:\n\t"
34
+			       "movb -1(%2,%1), %%al\n\t"
35
+			       "stosb\n\t"
36
+			       "loop 1b\n\t"
37
+			       "xorl %%eax, %%eax\n\t"
38
+			       "mov %3, %1\n\t"
39
+			       "rep stosb\n\t"
40
+			       : "=&D" ( discard_D ), "=&c" ( discard_c )
41
+			       : "r" ( data ), "g" ( pad_len ), "0" ( value0 ),
42
+				 "1" ( len )
43
+			       : "eax" );
44
+}
45
+
46
+/**
47
+ * Add big integers
48
+ *
49
+ * @v addend0		Element 0 of big integer to add
50
+ * @v value0		Element 0 of big integer to be added to
51
+ * @v size		Number of elements
52
+ */
53
+static inline __attribute__ (( always_inline )) void
54
+bigint_add_raw ( const uint32_t *addend0, uint32_t *value0,
55
+		 unsigned int size ) {
56
+	long index;
57
+	void *discard_S;
58
+	long discard_c;
59
+
60
+	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
61
+			       "\n1:\n\t"
62
+			       "lodsl\n\t"
63
+			       "adcl %%eax, (%3,%0,4)\n\t"
64
+			       "inc %0\n\t" /* Does not affect CF */
65
+			       "loop 1b\n\t"
66
+			       : "=&r" ( index ), "=&S" ( discard_S ),
67
+				 "=&c" ( discard_c )
68
+			       : "r" ( value0 ), "1" ( addend0 ), "2" ( size )
69
+			       : "eax" );
70
+}
71
+
72
+/**
73
+ * Subtract big integers
74
+ *
75
+ * @v subtrahend0	Element 0 of big integer to subtract
76
+ * @v value0		Element 0 of big integer to be subtracted from
77
+ * @v size		Number of elements
78
+ */
79
+static inline __attribute__ (( always_inline )) void
80
+bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
81
+		      unsigned int size ) {
82
+	long index;
83
+	void *discard_S;
84
+	long discard_c;
85
+
86
+	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
87
+			       "\n1:\n\t"
88
+			       "lodsl\n\t"
89
+			       "sbbl %%eax, (%3,%0,4)\n\t"
90
+			       "inc %0\n\t" /* Does not affect CF */
91
+			       "loop 1b\n\t"
92
+			       : "=&r" ( index ), "=&S" ( discard_S ),
93
+				 "=&c" ( discard_c )
94
+			       : "r" ( value0 ), "1" ( subtrahend0 ),
95
+				 "2" ( size )
96
+			       : "eax" );
97
+}
98
+
99
+/**
100
+ * Rotate big integer left
101
+ *
102
+ * @v value0		Element 0 of big integer
103
+ * @v size		Number of elements
104
+ */
105
+static inline __attribute__ (( always_inline )) void
106
+bigint_rol_raw ( uint32_t *value0, unsigned int size ) {
107
+	long index;
108
+	long discard_c;
109
+
110
+	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
111
+			       "\n1:\n\t"
112
+			       "rcll $1, (%2,%0,4)\n\t"
113
+			       "inc %0\n\t" /* Does not affect CF */
114
+			       "loop 1b\n\t"
115
+			       : "=&r" ( index ), "=&c" ( discard_c )
116
+			       : "r" ( value0 ), "1" ( size ) );
117
+}
118
+
119
+/**
120
+ * Rotate big integer right
121
+ *
122
+ * @v value0		Element 0 of big integer
123
+ * @v size		Number of elements
124
+ */
125
+static inline __attribute__ (( always_inline )) void
126
+bigint_ror_raw ( uint32_t *value0, unsigned int size ) {
127
+	long discard_c;
128
+
129
+	__asm__ __volatile__ ( "clc\n\t"
130
+			       "\n1:\n\t"
131
+			       "rcrl $1, -4(%1,%0,4)\n\t"
132
+			       "loop 1b\n\t"
133
+			       : "=&c" ( discard_c )
134
+			       : "r" ( value0 ), "0" ( size ) );
135
+}
136
+
137
+/**
138
+ * Test if big integer is equal to zero
139
+ *
140
+ * @v value0		Element 0 of big integer
141
+ * @v size		Number of elements
142
+ * @ret is_zero		Big integer is equal to zero
143
+ */
144
+static inline __attribute__ (( always_inline, pure )) int
145
+bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
146
+	void *discard_D;
147
+	long discard_c;
148
+	int result;
149
+
150
+	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Set ZF */
151
+			       "repe scasl\n\t"
152
+			       "sete %b0\n\t"
153
+			       : "=&a" ( result ), "=&D" ( discard_D ),
154
+				 "=&c" ( discard_c )
155
+			       : "1" ( value0 ), "2" ( size ) );
156
+	return result;
157
+}
158
+
159
+/**
160
+ * Compare big integers
161
+ *
162
+ * @v value0		Element 0 of big integer
163
+ * @v reference0	Element 0 of reference big integer
164
+ * @v size		Number of elements
165
+ * @ret geq		Big integer is greater than or equal to the reference
166
+ */
167
+static inline __attribute__ (( always_inline, pure )) int
168
+bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0,
169
+		    unsigned int size ) {
170
+	const bigint_t ( size ) __attribute__ (( may_alias )) *value =
171
+		( ( const void * ) value0 );
172
+	const bigint_t ( size ) __attribute__ (( may_alias )) *reference =
173
+		( ( const void * ) reference0 );
174
+	void *discard_S;
175
+	void *discard_D;
176
+	long discard_c;
177
+	int result;
178
+
179
+	__asm__ __volatile__ ( "std\n\t"
180
+			       "\n1:\n\t"
181
+			       "lodsl\n\t"
182
+			       "scasl\n\t"
183
+			       "loope 1b\n\t"
184
+			       "setae %b0\n\t"
185
+			       "cld\n\t"
186
+			       : "=r" ( result ), "=&S" ( discard_S ),
187
+				 "=&D" ( discard_D ), "=&c" ( discard_c )
188
+			       : "0" ( 0 ), "1" ( &value->element[ size - 1 ] ),
189
+				 "2" ( &reference->element[ size - 1 ] ),
190
+				 "3" ( size )
191
+			       : "eax" );
192
+	return result;
193
+}
194
+
195
+/**
196
+ * Test if bit is set in big integer
197
+ *
198
+ * @v value0		Element 0 of big integer
199
+ * @v size		Number of elements
200
+ * @v bit		Bit to test
201
+ * @ret is_set		Bit is set
202
+ */
203
+static inline __attribute__ (( always_inline )) int
204
+bigint_bit_is_set_raw ( const uint32_t *value0, unsigned int size,
205
+			unsigned int bit ) {
206
+	const bigint_t ( size ) __attribute__ (( may_alias )) *value =
207
+		( ( const void * ) value0 );
208
+	unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
209
+	unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
210
+
211
+	return ( value->element[index] & ( 1 << subindex ) );
212
+}
213
+
214
+/**
215
+ * Find highest bit set in big integer
216
+ *
217
+ * @v value0		Element 0 of big integer
218
+ * @v size		Number of elements
219
+ * @ret max_bit		Highest bit set + 1 (or 0 if no bits set)
220
+ */
221
+static inline __attribute__ (( always_inline )) int
222
+bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
223
+	long discard_c;
224
+	int result;
225
+
226
+	__asm__ __volatile__ ( "\n1:\n\t"
227
+			       "bsrl -4(%2,%1,4), %0\n\t"
228
+			       "loopz 1b\n\t"
229
+			       "rol %1\n\t" /* Does not affect ZF */
230
+			       "rol %1\n\t"
231
+			       "leal 1(%k0,%k1,8), %k0\n\t"
232
+			       "jnz 2f\n\t"
233
+			       "xor %0, %0\n\t"
234
+			       "\n2:\n\t"
235
+			       : "=&r" ( result ), "=&c" ( discard_c )
236
+			       : "r" ( value0 ), "1" ( size ) );
237
+	return result;
238
+}
239
+
240
+/**
241
+ * Grow big integer
242
+ *
243
+ * @v source0		Element 0 of source big integer
244
+ * @v source_size	Number of elements in source big integer
245
+ * @v dest0		Element 0 of destination big integer
246
+ * @v dest_size		Number of elements in destination big integer
247
+ */
248
+static inline __attribute__ (( always_inline )) void
249
+bigint_grow_raw ( const uint32_t *source0, unsigned int source_size,
250
+		  uint32_t *dest0, unsigned int dest_size ) {
251
+	long pad_size = ( dest_size - source_size );
252
+	void *discard_D;
253
+	void *discard_S;
254
+	long discard_c;
255
+
256
+	__asm__ __volatile__ ( "rep movsl\n\t"
257
+			       "xorl %%eax, %%eax\n\t"
258
+			       "mov %3, %2\n\t"
259
+			       "rep stosl\n\t"
260
+			       : "=&D" ( discard_D ), "=&S" ( discard_S ),
261
+				 "=&c" ( discard_c )
262
+			       : "g" ( pad_size ), "0" ( dest0 ),
263
+				 "1" ( source0 ), "2" ( source_size )
264
+			       : "eax" );
265
+}
266
+
267
+/**
268
+ * Shrink big integer
269
+ *
270
+ * @v source0		Element 0 of source big integer
271
+ * @v source_size	Number of elements in source big integer
272
+ * @v dest0		Element 0 of destination big integer
273
+ * @v dest_size		Number of elements in destination big integer
274
+ */
275
+static inline __attribute__ (( always_inline )) void
276
+bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused,
277
+		    uint32_t *dest0, unsigned int dest_size ) {
278
+	void *discard_D;
279
+	void *discard_S;
280
+	long discard_c;
281
+
282
+	__asm__ __volatile__ ( "rep movsl\n\t"
283
+			       : "=&D" ( discard_D ), "=&S" ( discard_S ),
284
+				 "=&c" ( discard_c )
285
+			       : "0" ( dest0 ), "1" ( source0 ),
286
+				 "2" ( dest_size )
287
+			       : "eax" );
288
+}
289
+
290
+/**
291
+ * Finalise big integer
292
+ *
293
+ * @v value0		Element 0 of big integer to finalise
294
+ * @v size		Number of elements
295
+ * @v out		Output buffer
296
+ * @v len		Length of output buffer
297
+ */
298
+static inline __attribute__ (( always_inline )) void
299
+bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
300
+		  void *out, size_t len ) {
301
+	void *discard_D;
302
+	long discard_c;
303
+
304
+	/* Copy raw data in reverse order */
305
+	__asm__ __volatile__ ( "\n1:\n\t"
306
+			       "movb -1(%2,%1), %%al\n\t"
307
+			       "stosb\n\t"
308
+			       "loop 1b\n\t"
309
+			       : "=&D" ( discard_D ), "=&c" ( discard_c )
310
+			       : "r" ( value0 ), "0" ( out ), "1" ( len )
311
+			       : "eax" );
312
+}
313
+
314
+extern void bigint_multiply_raw ( const uint32_t *multiplicand0,
315
+				  const uint32_t *multiplier0,
316
+				  uint32_t *value0, unsigned int size );
317
+
318
+#endif /* _BITS_BIGINT_H */

src/crypto/axtls/bigint.c → src/crypto/axtls/axtls_bigint.c Wyświetl plik


+ 122
- 0
src/crypto/bigint.c Wyświetl plik

@@ -0,0 +1,122 @@
1
+/*
2
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <stdint.h>
22
+#include <string.h>
23
+#include <assert.h>
24
+#include <ipxe/bigint.h>
25
+
26
+/** @file
27
+ *
28
+ * Big integer support
29
+ */
30
+
31
+/**
32
+ * Perform modular multiplication of big integers
33
+ *
34
+ * @v multiplicand0	Element 0 of big integer to be multiplied
35
+ * @v multiplier0	Element 0 of big integer to be multiplied
36
+ * @v modulus0		Element 0 of big integer modulus
37
+ * @v result0		Element 0 of big integer to hold result
38
+ */
39
+void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0,
40
+			       const bigint_element_t *multiplier0,
41
+			       const bigint_element_t *modulus0,
42
+			       bigint_element_t *result0,
43
+			       unsigned int size ) {
44
+	const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
45
+		( ( const void * ) multiplicand0 );
46
+	const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
47
+		( ( const void * ) multiplier0 );
48
+	const bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
49
+		( ( const void * ) modulus0 );
50
+	bigint_t ( size ) __attribute__ (( may_alias )) *result =
51
+		( ( void * ) result0 );
52
+	bigint_t ( size * 2 ) temp_result;
53
+	bigint_t ( size * 2 ) temp_modulus;
54
+	int rotation;
55
+	int i;
56
+
57
+	/* Perform multiplication */
58
+	bigint_multiply ( multiplicand, multiplier, &temp_result );
59
+
60
+	/* Rescale modulus to match result */
61
+	bigint_grow ( modulus, &temp_modulus );
62
+	rotation = ( bigint_max_set_bit ( &temp_result ) -
63
+		     bigint_max_set_bit ( &temp_modulus ) );
64
+	for ( i = 0 ; i < rotation ; i++ )
65
+		bigint_rol ( &temp_modulus );
66
+
67
+	/* Subtract multiples of modulus */
68
+	for ( i = 0 ; i <= rotation ; i++ ) {
69
+		if ( bigint_is_geq ( &temp_result, &temp_modulus ) )
70
+			bigint_subtract ( &temp_modulus, &temp_result );
71
+		bigint_ror ( &temp_modulus );
72
+	}
73
+
74
+	/* Resize result */
75
+	bigint_shrink ( &temp_result, result );
76
+
77
+	/* Sanity check */
78
+	assert ( bigint_is_geq ( modulus, result ) );
79
+}
80
+
81
+/**
82
+ * Perform modular exponentiation of big integers
83
+ *
84
+ * @v base0		Element 0 of big integer base
85
+ * @v modulus0		Element 0 of big integer modulus
86
+ * @v exponent0		Element 0 of big integer exponent
87
+ * @v result0		Element 0 of big integer to hold result
88
+ * @v size		Number of elements in base, modulus, and result
89
+ * @v exponent_size	Number of elements in exponent
90
+ */
91
+void bigint_mod_exp_raw ( const bigint_element_t *base0,
92
+			  const bigint_element_t *modulus0,
93
+			  const bigint_element_t *exponent0,
94
+			  bigint_element_t *result0,
95
+			  unsigned int size,
96
+			  unsigned int exponent_size ) {
97
+	const bigint_t ( size ) __attribute__ (( may_alias )) *base =
98
+		( ( const void * ) base0 );
99
+	const bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
100
+		( ( const void * ) modulus0 );
101
+	const bigint_t ( exponent_size ) __attribute__ (( may_alias ))
102
+		*exponent = ( ( const void * ) exponent0 );
103
+	bigint_t ( size ) __attribute__ (( may_alias )) *result =
104
+		( ( void * ) result0 );
105
+	bigint_t ( size ) temp_base;
106
+	bigint_t ( exponent_size ) temp_exponent;
107
+	static const uint8_t start[1] = { 0x01 };
108
+
109
+	memcpy ( &temp_base, base, sizeof ( temp_base ) );
110
+	memcpy ( &temp_exponent, exponent, sizeof ( temp_exponent ) );
111
+	bigint_init ( result, start, sizeof ( start ) );
112
+
113
+	while ( ! bigint_is_zero ( &temp_exponent ) ) {
114
+		if ( bigint_bit_is_set ( &temp_exponent, 0 ) ) {
115
+			bigint_mod_multiply ( result, &temp_base,
116
+					      modulus, result );
117
+		}
118
+		bigint_ror ( &temp_exponent );
119
+		bigint_mod_multiply ( &temp_base, &temp_base, modulus,
120
+				      &temp_base );
121
+	}
122
+}

+ 268
- 0
src/include/ipxe/bigint.h Wyświetl plik

@@ -0,0 +1,268 @@
1
+#ifndef _IPXE_BIGINT_H
2
+#define _IPXE_BIGINT_H
3
+
4
+/** @file
5
+ *
6
+ * Big integer support
7
+ */
8
+
9
+FILE_LICENCE ( GPL2_OR_LATER );
10
+
11
+/**
12
+ * Define a big-integer type
13
+ *
14
+ * @v size		Number of elements
15
+ * @ret bigint_t	Big integer type
16
+ */
17
+#define bigint_t( size )						\
18
+	struct {							\
19
+		bigint_element_t element[ (size) ];			\
20
+	}
21
+
22
+/**
23
+ * Determine number of elements required for a big-integer type
24
+ *
25
+ * @v len		Maximum length of big integer, in bytes
26
+ * @ret size		Number of elements
27
+ */
28
+#define bigint_required_size( len )					\
29
+	( ( (len) + sizeof ( bigint_element_t ) - 1 ) /			\
30
+	  sizeof ( bigint_element_t ) )
31
+
32
+/**
33
+ * Determine number of elements in big-integer type
34
+ *
35
+ * @v bigint		Big integer
36
+ * @ret size		Number of elements
37
+ */
38
+#define bigint_size( bigint )						\
39
+	( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) )
40
+
41
+/**
42
+ * Initialise big integer
43
+ *
44
+ * @v value		Big integer to initialise
45
+ * @v data		Raw data
46
+ * @v len		Length of raw data
47
+ */
48
+#define bigint_init( value, data, len ) do {				\
49
+	unsigned int size = bigint_size (value);			\
50
+	assert ( (len) <= ( size * sizeof ( (value)->element[0] ) ) );	\
51
+	bigint_init_raw ( (value)->element, size, (data), (len) );	\
52
+	} while ( 0 )
53
+
54
+/**
55
+ * Finalise big integer
56
+ *
57
+ * @v value		Big integer to finalise
58
+ * @v out		Output buffer
59
+ * @v len		Length of output buffer
60
+ */
61
+#define bigint_done( value, out, len ) do {				\
62
+	unsigned int size = bigint_size (value);			\
63
+	bigint_done_raw ( (value)->element, size, (out), (len) );	\
64
+	} while ( 0 )
65
+
66
+/**
67
+ * Add big integers
68
+ *
69
+ * @v addend		Big integer to add
70
+ * @v value		Big integer to be added to
71
+ */
72
+#define bigint_add( addend, value ) do {				\
73
+	unsigned int size = bigint_size (addend);			\
74
+	bigint_add_raw ( (addend)->element, (value)->element, size );	\
75
+	} while ( 0 )
76
+
77
+/**
78
+ * Subtract big integers
79
+ *
80
+ * @v subtrahend	Big integer to subtract
81
+ * @v value		Big integer to be subtracted from
82
+ */
83
+#define bigint_subtract( subtrahend, value ) do {			\
84
+	unsigned int size = bigint_size (subtrahend);			\
85
+	bigint_subtract_raw ( (subtrahend)->element, (value)->element,	\
86
+			      size );					\
87
+	} while ( 0 )
88
+
89
+/**
90
+ * Rotate big integer left
91
+ *
92
+ * @v value		Big integer
93
+ */
94
+#define bigint_rol( value ) do {					\
95
+	unsigned int size = bigint_size (value);			\
96
+	bigint_rol_raw ( (value)->element, size );			\
97
+	} while ( 0 )
98
+
99
+/**
100
+ * Rotate big integer right
101
+ *
102
+ * @v value		Big integer
103
+ */
104
+#define bigint_ror( value ) do {					\
105
+	unsigned int size = bigint_size (value);			\
106
+	bigint_ror_raw ( (value)->element, size );			\
107
+	} while ( 0 )
108
+
109
+/**
110
+ * Test if big integer is equal to zero
111
+ *
112
+ * @v value		Big integer
113
+ * @v size		Number of elements
114
+ * @ret is_zero		Big integer is equal to zero
115
+ */
116
+#define bigint_is_zero( value ) ( {					\
117
+	unsigned int size = bigint_size (value);			\
118
+	bigint_is_zero_raw ( (value)->element, size ); } )
119
+
120
+/**
121
+ * Compare big integers
122
+ *
123
+ * @v value		Big integer
124
+ * @v reference		Reference big integer
125
+ * @ret geq		Big integer is greater than or equal to the reference
126
+ */
127
+#define bigint_is_geq( value, reference ) ( {				\
128
+	unsigned int size = bigint_size (value);			\
129
+	bigint_is_geq_raw ( (value)->element, (reference)->element,	\
130
+			    size ); } )
131
+
132
+/**
133
+ * Test if bit is set in big integer
134
+ *
135
+ * @v value		Big integer
136
+ * @v bit		Bit to test
137
+ * @ret is_set		Bit is set
138
+ */
139
+#define bigint_bit_is_set( value, bit ) ( {				\
140
+	unsigned int size = bigint_size (value);			\
141
+	bigint_bit_is_set_raw ( (value)->element, size, bit ); } )
142
+
143
+/**
144
+ * Find highest bit set in big integer
145
+ *
146
+ * @v value		Big integer
147
+ * @ret max_bit		Highest bit set + 1 (or 0 if no bits set)
148
+ */
149
+#define bigint_max_set_bit( value ) ( {					\
150
+	unsigned int size = bigint_size (value);			\
151
+	bigint_max_set_bit_raw ( (value)->element, size ); } )
152
+
153
+/**
154
+ * Grow big integer
155
+ *
156
+ * @v source		Source big integer
157
+ * @v dest		Destination big integer
158
+ */
159
+#define bigint_grow( source, dest ) do {				\
160
+	unsigned int source_size = bigint_size (source);		\
161
+	unsigned int dest_size = bigint_size (dest);			\
162
+	bigint_grow_raw ( (source)->element, source_size,		\
163
+			  (dest)->element, dest_size );			\
164
+	} while ( 0 )
165
+
166
+/**
167
+ * Shrink big integer
168
+ *
169
+ * @v source		Source big integer
170
+ * @v dest		Destination big integer
171
+ */
172
+#define bigint_shrink( source, dest ) do {				\
173
+	unsigned int source_size = bigint_size (source);		\
174
+	unsigned int dest_size = bigint_size (dest);			\
175
+	bigint_shrink_raw ( (source)->element, source_size,		\
176
+			    (dest)->element, dest_size );		\
177
+	} while ( 0 )
178
+
179
+/**
180
+ * Multiply big integers
181
+ *
182
+ * @v multiplicand	Big integer to be multiplied
183
+ * @v multiplier	Big integer to be multiplied
184
+ * @v result		Big integer to hold result
185
+ */
186
+#define bigint_multiply( multiplicand, multiplier, result ) do {	\
187
+	unsigned int size = bigint_size (multiplicand);			\
188
+	bigint_multiply_raw ( (multiplicand)->element,			\
189
+			      (multiplier)->element, (result)->element,	\
190
+			      size );					\
191
+	} while ( 0 )
192
+
193
+/**
194
+ * Perform modular multiplication of big integers
195
+ *
196
+ * @v multiplicand	Big integer to be multiplied
197
+ * @v multiplier	Big integer to be multiplied
198
+ * @v modulus		Big integer modulus
199
+ * @v result		Big integer to hold result
200
+ */
201
+#define bigint_mod_multiply( multiplicand, multiplier, modulus,		\
202
+			     result ) do {				\
203
+	unsigned int size = bigint_size (multiplicand);			\
204
+	bigint_mod_multiply_raw ( (multiplicand)->element,		\
205
+				  (multiplier)->element,		\
206
+				  (modulus)->element,			\
207
+				  (result)->element, size );		\
208
+	} while ( 0 )
209
+
210
+/**
211
+ * Perform modular exponentiation of big integers
212
+ *
213
+ * @v base		Big integer base
214
+ * @v modulus		Big integer modulus
215
+ * @v exponent		Big integer exponent
216
+ * @v result		Big integer to hold result
217
+ */
218
+#define bigint_mod_exp( base, modulus, exponent, result ) do {		\
219
+	unsigned int size = bigint_size (base);				\
220
+	unsigned int exponent_size = bigint_size (exponent);		\
221
+	bigint_mod_exp_raw ( (base)->element, (modulus)->element,	\
222
+			  (exponent)->element, (result)->element,	\
223
+			  size, exponent_size );			\
224
+	} while ( 0 )
225
+
226
+#include <bits/bigint.h>
227
+
228
+void bigint_init_raw ( bigint_element_t *value0, unsigned int size,
229
+		       const void *data, size_t len );
230
+void bigint_done_raw ( const bigint_element_t *value0, unsigned int size,
231
+		       void *out, size_t len );
232
+void bigint_add_raw ( const bigint_element_t *addend0,
233
+		      bigint_element_t *value0, unsigned int size );
234
+void bigint_subtract_raw ( const bigint_element_t *subtrahend0,
235
+			   bigint_element_t *value0, unsigned int size );
236
+void bigint_rol_raw ( bigint_element_t *value0, unsigned int size );
237
+void bigint_ror_raw ( bigint_element_t *value0, unsigned int size );
238
+int bigint_is_zero_raw ( const bigint_element_t *value0, unsigned int size );
239
+int bigint_is_geq_raw ( const bigint_element_t *value0,
240
+			const bigint_element_t *reference0,
241
+			unsigned int size );
242
+int bigint_bit_is_set_raw ( const bigint_element_t *value0, unsigned int size,
243
+			    unsigned int bit );
244
+int bigint_max_set_bit_raw ( const bigint_element_t *value0,
245
+			     unsigned int size );
246
+void bigint_grow_raw ( const bigint_element_t *source0,
247
+		       unsigned int source_size, bigint_element_t *dest0,
248
+		       unsigned int dest_size );
249
+void bigint_shrink_raw ( const bigint_element_t *source0,
250
+			 unsigned int source_size, bigint_element_t *dest0,
251
+			 unsigned int dest_size );
252
+void bigint_multiply_raw ( const bigint_element_t *multiplicand0,
253
+			   const bigint_element_t *multiplier0,
254
+			   bigint_element_t *result0,
255
+			   unsigned int size );
256
+void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0,
257
+			       const bigint_element_t *multiplier0,
258
+			       const bigint_element_t *modulus0,
259
+			       bigint_element_t *result0,
260
+			       unsigned int size );
261
+void bigint_mod_exp_raw ( const bigint_element_t *base0,
262
+			  const bigint_element_t *modulus0,
263
+			  const bigint_element_t *exponent0,
264
+			  bigint_element_t *result0,
265
+			  unsigned int size,
266
+			  unsigned int exponent_size );
267
+
268
+#endif /* _IPXE_BIGINT_H */

Ładowanie…
Anuluj
Zapisz