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 FILE_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  */
26 static 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;
33  long discard_c;
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  */
60 static 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  */
92 static inline __attribute__ (( always_inline )) int
93 bigint_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;
100  int borrow;
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  */
124 static inline __attribute__ (( always_inline )) int
125 bigint_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  */
150 static inline __attribute__ (( always_inline )) int
151 bigint_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 
157  __asm__ __volatile__ ( "clc\n\t"
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  */
174 static inline __attribute__ (( always_inline, pure )) int
175 bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
176  void *discard_D;
177  long discard_c;
178  int result;
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  */
197 static inline __attribute__ (( always_inline, pure )) int
199  unsigned int size ) {
200  long discard_c;
202  int result;
203 
204  __asm__ __volatile__ ( "\n1:\n\t"
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  */
223 static inline __attribute__ (( always_inline )) int
224 bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
225  long discard_c;
226  int result;
227 
228  __asm__ __volatile__ ( "\n1:\n\t"
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  */
250 static inline __attribute__ (( always_inline )) void
251 bigint_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  */
279 static inline __attribute__ (( always_inline )) void
280 bigint_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  */
304 static inline __attribute__ (( always_inline )) void
305 bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
306  void *out, size_t len ) {
307  struct {
308  uint8_t bytes[len];
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  */
334 static inline __attribute__ (( always_inline )) void
335 bigint_multiply_one ( const uint32_t multiplicand, const uint32_t multiplier,
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 */
void bigint_grow_raw(const bigint_element_t *source0, unsigned int source_size, bigint_element_t *dest0, unsigned int dest_size)
static const uint32_t * reference0
Definition: bigint.h:198
int carry
Definition: bigint.h:68
FILE_SECBOOT(PERMITTED)
void * discard_S
Definition: bigint.h:66
int bigint_max_set_bit_raw(const bigint_element_t *value0, unsigned int size)
long index
Definition: bigint.h:65
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:255
static uint32_t * value0
Definition: bigint.h:61
long discard_tmp
Definition: bigint.h:201
static unsigned int const void size_t len
Definition: bigint.h:28
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static unsigned int const void * data
Definition: bigint.h:27
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int result
Definition: bigint.h:178
uint32_t bigint_element_t
Element of a big integer.
Definition: bigint.h:16
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:252
int borrow
Definition: bigint.h:100
static __attribute__((always_inline)) void bigint_init_raw(uint32_t *value0
Initialise big integer.
unsigned char uint8_t
Definition: stdint.h:10
void * discard_D
Definition: bigint.h:32
unsigned int uint32_t
Definition: stdint.h:12
int bigint_shl_raw(bigint_element_t *value0, unsigned int size)
static unsigned int source_size __unused
Definition: bigint.h:280
long pad_len
Definition: bigint.h:31
__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:335
static unsigned int source_size
Definition: bigint.h:251
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)
int out
Definition: bigint.h:130
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:151
Optimised string operations.
long discard_c
Definition: bigint.h:33
int bigint_shr_raw(bigint_element_t *value0, unsigned int size)
int bigint_subtract_raw(const bigint_element_t *subtrahend0, bigint_element_t *value0, unsigned int size)
uint8_t bytes[64]
Definition: ib_mad.h:17
int bigint_is_zero_raw(const bigint_element_t *value0, unsigned int size)
static unsigned int uint32_t * dest0
Definition: bigint.h:251
static unsigned int size
Definition: bigint.h:27
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.
__asm__ __volatile__("jecxz 2f\n\t" "\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "\n2:\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")