iPXE
bigint.h
Go to the documentation of this file.
1#ifndef _BITS_BIGINT_H
2#define _BITS_BIGINT_H
3
4/** @file
5 *
6 * Big integer support
7 */
8
9FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
10FILE_SECBOOT ( PERMITTED );
11
12#include <stdint.h>
13#include <string.h>
14
15/** Element of a big integer */
17
18/**
19 * Initialise big integer
20 *
21 * @v value0 Element 0 of big integer to initialise
22 * @v size Number of elements
23 * @v data Raw data
24 * @v len Length of raw data
25 */
26static inline __attribute__ (( always_inline )) void
28 const void *data, size_t len ) {
29 bigint_t ( size ) __attribute__ (( may_alias )) *value =
30 ( ( void * ) value0 );
31 long pad_len = ( sizeof ( *value ) - len );
32 void *discard_D;
34
35 /* Copy raw data in reverse order, padding with zeros */
36 __asm__ __volatile__ ( "jecxz 2f\n\t"
37 "\n1:\n\t"
38 "movb -1(%3,%1), %%al\n\t"
39 "stosb\n\t"
40 "loop 1b\n\t"
41 "\n2:\n\t"
42 "xorl %%eax, %%eax\n\t"
43 "mov %4, %1\n\t"
44 "rep stosb\n\t"
45 : "=&D" ( discard_D ), "=&c" ( discard_c ),
46 "+m" ( *value )
47 : "r" ( data ), "g" ( pad_len ), "0" ( value0 ),
48 "1" ( len )
49 : "eax" );
50}
51
52/**
53 * Add big integers
54 *
55 * @v addend0 Element 0 of big integer to add
56 * @v value0 Element 0 of big integer to be added to
57 * @v size Number of elements
58 * @ret carry Carry flag
59 */
60static inline __attribute__ (( always_inline )) int
62 unsigned int size ) {
63 bigint_t ( size ) __attribute__ (( may_alias )) *value =
64 ( ( void * ) value0 );
65 long index;
66 void *discard_S;
67 long discard_c;
68 int carry;
69
70 __asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
71 "\n1:\n\t"
72 "lodsl\n\t"
73 "adcl %%eax, (%5,%0,4)\n\t"
74 "inc %0\n\t" /* Does not affect CF */
75 "loop 1b\n\t"
76 : "=&r" ( index ), "=&S" ( discard_S ),
77 "=&c" ( discard_c ), "=@ccc" ( carry ),
78 "+m" ( *value )
79 : "r" ( value0 ), "1" ( addend0 ), "2" ( size )
80 : "eax" );
81 return carry;
82}
83
84/**
85 * Subtract big integers
86 *
87 * @v subtrahend0 Element 0 of big integer to subtract
88 * @v value0 Element 0 of big integer to be subtracted from
89 * @v size Number of elements
90 * @ret borrow Borrow flag
91 */
92static inline __attribute__ (( always_inline )) int
93bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
94 unsigned int size ) {
95 bigint_t ( size ) __attribute__ (( may_alias )) *value =
96 ( ( void * ) value0 );
97 long index;
98 void *discard_S;
99 long discard_c;
101
102 __asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
103 "\n1:\n\t"
104 "lodsl\n\t"
105 "sbbl %%eax, (%5,%0,4)\n\t"
106 "inc %0\n\t" /* Does not affect CF */
107 "loop 1b\n\t"
108 : "=&r" ( index ), "=&S" ( discard_S ),
109 "=&c" ( discard_c ), "=@ccc" ( borrow ),
110 "+m" ( *value )
111 : "r" ( value0 ), "1" ( subtrahend0 ),
112 "2" ( size )
113 : "eax" );
114 return borrow;
115}
116
117/**
118 * Shift big integer left
119 *
120 * @v value0 Element 0 of big integer
121 * @v size Number of elements
122 * @ret out Bit shifted out
123 */
124static inline __attribute__ (( always_inline )) int
125bigint_shl_raw ( uint32_t *value0, unsigned int size ) {
126 bigint_t ( size ) __attribute__ (( may_alias )) *value =
127 ( ( void * ) value0 );
128 long index;
129 long discard_c;
130 int out;
131
132 __asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
133 "\n1:\n\t"
134 "rcll $1, (%4,%0,4)\n\t"
135 "inc %0\n\t" /* Does not affect CF */
136 "loop 1b\n\t"
137 : "=&r" ( index ), "=&c" ( discard_c ),
138 "=@ccc" ( out ), "+m" ( *value )
139 : "r" ( value0 ), "1" ( size ) );
140 return out;
141}
142
143/**
144 * Shift big integer right
145 *
146 * @v value0 Element 0 of big integer
147 * @v size Number of elements
148 * @ret out Bit shifted out
149 */
150static inline __attribute__ (( always_inline )) int
151bigint_shr_raw ( uint32_t *value0, unsigned int size ) {
152 bigint_t ( size ) __attribute__ (( may_alias )) *value =
153 ( ( void * ) value0 );
154 long discard_c;
155 int out;
156
158 "\n1:\n\t"
159 "rcrl $1, -4(%3,%0,4)\n\t"
160 "loop 1b\n\t"
161 : "=&c" ( discard_c ), "=@ccc" ( out ),
162 "+m" ( *value )
163 : "r" ( value0 ), "0" ( size ) );
164 return out;
165}
166
167/**
168 * Test if big integer is equal to zero
169 *
170 * @v value0 Element 0 of big integer
171 * @v size Number of elements
172 * @ret is_zero Big integer is equal to zero
173 */
174static inline __attribute__ (( always_inline, pure )) int
175bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
176 void *discard_D;
177 long discard_c;
179
180 __asm__ __volatile__ ( "xor %0, %0\n\t" /* Set ZF */
181 "repe scasl\n\t"
182 "sete %b0\n\t"
183 : "=&a" ( result ), "=&D" ( discard_D ),
184 "=&c" ( discard_c )
185 : "1" ( value0 ), "2" ( size ) );
186 return result;
187}
188
189/**
190 * Compare big integers
191 *
192 * @v value0 Element 0 of big integer
193 * @v reference0 Element 0 of reference big integer
194 * @v size Number of elements
195 * @ret geq Big integer is greater than or equal to the reference
196 */
197static inline __attribute__ (( always_inline, pure )) int
199 unsigned int size ) {
200 long discard_c;
202 int result;
203
205 "movl -4(%3, %1, 4), %k2\n\t"
206 "cmpl -4(%4, %1, 4), %k2\n\t"
207 "loope 1b\n\t"
208 "setae %b0\n\t"
209 : "=q" ( result ), "=&c" ( discard_c ),
210 "=&r" ( discard_tmp )
211 : "r" ( value0 ), "r" ( reference0 ),
212 "0" ( 0 ), "1" ( size ) );
213 return result;
214}
215
216/**
217 * Find highest bit set in big integer
218 *
219 * @v value0 Element 0 of big integer
220 * @v size Number of elements
221 * @ret max_bit Highest bit set + 1 (or 0 if no bits set)
222 */
223static inline __attribute__ (( always_inline )) int
224bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
225 long discard_c;
226 int result;
227
229 "bsrl -4(%2,%1,4), %0\n\t"
230 "loopz 1b\n\t"
231 "rol %1\n\t" /* Does not affect ZF */
232 "rol %1\n\t"
233 "leal 1(%k0,%k1,8), %k0\n\t"
234 "jnz 2f\n\t"
235 "xor %0, %0\n\t"
236 "\n2:\n\t"
237 : "=&r" ( result ), "=&c" ( discard_c )
238 : "r" ( value0 ), "1" ( size ) );
239 return result;
240}
241
242/**
243 * Grow big integer
244 *
245 * @v source0 Element 0 of source big integer
246 * @v source_size Number of elements in source big integer
247 * @v dest0 Element 0 of destination big integer
248 * @v dest_size Number of elements in destination big integer
249 */
250static inline __attribute__ (( always_inline )) void
251bigint_grow_raw ( const uint32_t *source0, unsigned int source_size,
252 uint32_t *dest0, unsigned int dest_size ) {
253 bigint_t ( dest_size ) __attribute__ (( may_alias )) *dest =
254 ( ( void * ) dest0 );
256 void *discard_D;
257 void *discard_S;
258 long discard_c;
259
260 __asm__ __volatile__ ( "rep movsl\n\t"
261 "xorl %%eax, %%eax\n\t"
262 "mov %4, %2\n\t"
263 "rep stosl\n\t"
264 : "=&D" ( discard_D ), "=&S" ( discard_S ),
265 "=&c" ( discard_c ), "+m" ( *dest )
266 : "g" ( pad_size ), "0" ( dest0 ),
267 "1" ( source0 ), "2" ( source_size )
268 : "eax" );
269}
270
271/**
272 * Shrink big integer
273 *
274 * @v source0 Element 0 of source big integer
275 * @v source_size Number of elements in source big integer
276 * @v dest0 Element 0 of destination big integer
277 * @v dest_size Number of elements in destination big integer
278 */
279static inline __attribute__ (( always_inline )) void
280bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused,
281 uint32_t *dest0, unsigned int dest_size ) {
282 bigint_t ( dest_size ) __attribute__ (( may_alias )) *dest =
283 ( ( void * ) dest0 );
284 void *discard_D;
285 void *discard_S;
286 long discard_c;
287
288 __asm__ __volatile__ ( "rep movsl\n\t"
289 : "=&D" ( discard_D ), "=&S" ( discard_S ),
290 "=&c" ( discard_c ), "+m" ( *dest )
291 : "0" ( dest0 ), "1" ( source0 ),
292 "2" ( dest_size )
293 : "eax" );
294}
295
296/**
297 * Finalise big integer
298 *
299 * @v value0 Element 0 of big integer to finalise
300 * @v size Number of elements
301 * @v out Output buffer
302 * @v len Length of output buffer
303 */
304static inline __attribute__ (( always_inline )) void
305bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
306 void *out, size_t len ) {
307 struct {
309 } __attribute__ (( may_alias )) *out_bytes = out;
310 void *discard_D;
311 long discard_c;
312
313 /* Copy raw data in reverse order */
314 __asm__ __volatile__ ( "jecxz 2f\n\t"
315 "\n1:\n\t"
316 "movb -1(%3,%1), %%al\n\t"
317 "stosb\n\t"
318 "loop 1b\n\t"
319 "\n2:\n\t"
320 : "=&D" ( discard_D ), "=&c" ( discard_c ),
321 "+m" ( *out_bytes )
322 : "r" ( value0 ), "0" ( out ), "1" ( len )
323 : "eax" );
324}
325
326/**
327 * Multiply big integer elements
328 *
329 * @v multiplicand Multiplicand element
330 * @v multiplier Multiplier element
331 * @v result Result element
332 * @v carry Carry element
333 */
334static inline __attribute__ (( always_inline )) void
337 uint32_t discard_a;
338
339 __asm__ __volatile__ ( /* Perform multiplication */
340 "mull %3\n\t"
341 /* Accumulate carry */
342 "addl %5, %0\n\t"
343 "adcl $0, %1\n\t"
344 /* Accumulate result */
345 "addl %0, %2\n\t"
346 "adcl $0, %1\n\t"
347 : "=&a" ( discard_a ),
348 "=&d" ( *carry ),
349 "+m" ( *result )
350 : "g" ( multiplicand ),
351 "0" ( multiplier ),
352 "r" ( *carry ) );
353}
354
355#endif /* _BITS_BIGINT_H */
__be32 out[4]
Definition CIB_PRM.h:8
pseudo_bit_t value[0x00020]
Definition arbel.h:2
uint16_t result
Definition hyperv.h:33
unsigned int uint32_t
Definition stdint.h:12
unsigned char uint8_t
Definition stdint.h:10
__asm__ __volatile__("rep movsl\n\t" :"=&D"(discard_D), "=&S"(discard_S), "=&c"(discard_c), "+m"(*dest) :"0"(dest0), "1"(source0), "2"(dest_size) :"eax")
long pad_size
Definition bigint.h:255
static const uint32_t multiplier
Port multiplier number.
Definition bigint.h:335
static const uint32_t * reference0
Definition bigint.h:198
long discard_tmp
Definition bigint.h:201
long index
Definition bigint.h:65
long pad_len
Definition bigint.h:31
void * discard_D
Definition bigint.h:32
uint32_t bigint_element_t
Element of a big integer.
Definition bigint.h:16
int carry
Definition bigint.h:68
static uint32_t * value0
Definition bigint.h:61
long discard_c
Definition bigint.h:33
static unsigned int source_size
Definition bigint.h:251
static unsigned int uint32_t unsigned int dest_size
Definition bigint.h:252
static unsigned int uint32_t * dest0
Definition bigint.h:252
int borrow
Definition bigint.h:100
void * discard_S
Definition bigint.h:66
Optimised string operations.
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
uint16_t size
Buffer size.
Definition dwmac.h:3
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
uint8_t bytes[64]
Definition ib_mad.h:5
#define __attribute__(x)
Definition compiler.h:10
int bigint_is_geq_raw(const bigint_element_t *value0, const bigint_element_t *reference0, unsigned int size)
void bigint_shrink_raw(const bigint_element_t *source0, unsigned int source_size, bigint_element_t *dest0, unsigned int dest_size)
int bigint_subtract_raw(const bigint_element_t *subtrahend0, bigint_element_t *value0, unsigned int size)
void bigint_grow_raw(const bigint_element_t *source0, unsigned int source_size, bigint_element_t *dest0, unsigned int dest_size)
void bigint_done_raw(const bigint_element_t *value0, unsigned int size, void *out, size_t len)
void bigint_multiply_one(const bigint_element_t multiplicand, const bigint_element_t multiplier, bigint_element_t *result, bigint_element_t *carry)
int bigint_add_raw(const bigint_element_t *addend0, bigint_element_t *value0, unsigned int size)
int bigint_is_zero_raw(const bigint_element_t *value0, unsigned int size)
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:20
void bigint_init_raw(bigint_element_t *value0, unsigned int size, const void *data, size_t len)
int bigint_max_set_bit_raw(const bigint_element_t *value0, unsigned int size)
int bigint_shl_raw(bigint_element_t *value0, unsigned int size)
int bigint_shr_raw(bigint_element_t *value0, unsigned int size)
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")