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