Skip to content

Commit e68ca57

Browse files
committed
[crypto] Use generic implementations of slow-path big integer functions
In the original big integer implementation, big integers were entirely opaque to the caller and only the architecture-dependent code knew any details of the internal structure. This has long since ceased to be the case: for the sake of arithmetic efficiency, many portions of the codebase now presume that big integers are represented as an array of elements, with each element being a native-endian unsigned value (with the precise type being chosen by the architecture-specific header file) and with the least significant element being first in the array. The functions bigint_init(), bigint_done(), bigint_is_zero(), bigint_is_geq(), and bigint_max_bit_set() are never used on fast code paths, and most architectures use a generic C implementation of these functions. Provide generic implementations of these slow-path functions to be used on all architectures. Signed-off-by: Michael Brown <mcb30@ipxe.org>
1 parent 05a459f commit e68ca57

8 files changed

Lines changed: 136 additions & 588 deletions

File tree

src/arch/arm32/include/bits/bigint.h

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
1010

1111
#include <stdint.h>
1212
#include <string.h>
13-
#include <strings.h>
1413

1514
/** Element of a big integer */
1615
typedef uint32_t bigint_element_t;
1716

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
27-
bigint_init_raw ( uint32_t *value0, unsigned int size,
28-
const void *data, size_t len ) {
29-
size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
30-
uint8_t *value_byte = ( ( void * ) value0 );
31-
const uint8_t *data_byte = ( data + len );
32-
33-
/* Copy raw data in reverse order, padding with zeros */
34-
while ( len-- )
35-
*(value_byte++) = *(--data_byte);
36-
while ( pad_len-- )
37-
*(value_byte++) = 0;
38-
}
39-
4017
/**
4118
* Add big integers
4219
*
@@ -182,76 +159,6 @@ bigint_shr_raw ( uint32_t *value0, unsigned int size ) {
182159
return carry;
183160
}
184161

185-
/**
186-
* Test if big integer is equal to zero
187-
*
188-
* @v value0 Element 0 of big integer
189-
* @v size Number of elements
190-
* @ret is_zero Big integer is equal to zero
191-
*/
192-
static inline __attribute__ (( always_inline, pure )) int
193-
bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
194-
const uint32_t *value = value0;
195-
uint32_t value_i;
196-
197-
do {
198-
value_i = *(value++);
199-
if ( value_i )
200-
break;
201-
} while ( --size );
202-
203-
return ( value_i == 0 );
204-
}
205-
206-
/**
207-
* Compare big integers
208-
*
209-
* @v value0 Element 0 of big integer
210-
* @v reference0 Element 0 of reference big integer
211-
* @v size Number of elements
212-
* @ret geq Big integer is greater than or equal to the reference
213-
*/
214-
static inline __attribute__ (( always_inline, pure )) int
215-
bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0,
216-
unsigned int size ) {
217-
const uint32_t *value = ( value0 + size );
218-
const uint32_t *reference = ( reference0 + size );
219-
uint32_t value_i;
220-
uint32_t reference_i;
221-
222-
do {
223-
value_i = *(--value);
224-
reference_i = *(--reference);
225-
if ( value_i != reference_i )
226-
break;
227-
} while ( --size );
228-
229-
return ( value_i >= reference_i );
230-
}
231-
232-
/**
233-
* Find highest bit set in big integer
234-
*
235-
* @v value0 Element 0 of big integer
236-
* @v size Number of elements
237-
* @ret max_bit Highest bit set + 1 (or 0 if no bits set)
238-
*/
239-
static inline __attribute__ (( always_inline )) int
240-
bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
241-
const uint32_t *value = ( value0 + size );
242-
int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
243-
uint32_t value_i;
244-
245-
do {
246-
value_i = *(--value);
247-
max_bit -= ( 32 - fls ( value_i ) );
248-
if ( value_i )
249-
break;
250-
} while ( --size );
251-
252-
return max_bit;
253-
}
254-
255162
/**
256163
* Grow big integer
257164
*
@@ -284,25 +191,6 @@ bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused,
284191
memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
285192
}
286193

287-
/**
288-
* Finalise big integer
289-
*
290-
* @v value0 Element 0 of big integer to finalise
291-
* @v size Number of elements
292-
* @v out Output buffer
293-
* @v len Length of output buffer
294-
*/
295-
static inline __attribute__ (( always_inline )) void
296-
bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
297-
void *out, size_t len ) {
298-
const uint8_t *value_byte = ( ( const void * ) value0 );
299-
uint8_t *out_byte = ( out + len );
300-
301-
/* Copy raw data in reverse order */
302-
while ( len-- )
303-
*(--out_byte) = *(value_byte++);
304-
}
305-
306194
/**
307195
* Multiply big integer elements
308196
*

src/arch/arm64/include/bits/bigint.h

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,10 @@ FILE_SECBOOT ( PERMITTED );
1111

1212
#include <stdint.h>
1313
#include <string.h>
14-
#include <strings.h>
1514

1615
/** Element of a big integer */
1716
typedef uint64_t bigint_element_t;
1817

19-
/**
20-
* Initialise big integer
21-
*
22-
* @v value0 Element 0 of big integer to initialise
23-
* @v size Number of elements
24-
* @v data Raw data
25-
* @v len Length of raw data
26-
*/
27-
static inline __attribute__ (( always_inline )) void
28-
bigint_init_raw ( uint64_t *value0, unsigned int size,
29-
const void *data, size_t len ) {
30-
size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
31-
uint8_t *value_byte = ( ( void * ) value0 );
32-
const uint8_t *data_byte = ( data + len );
33-
34-
/* Copy raw data in reverse order, padding with zeros */
35-
while ( len-- )
36-
*(value_byte++) = *(--data_byte);
37-
while ( pad_len-- )
38-
*(value_byte++) = 0;
39-
}
40-
4118
/**
4219
* Add big integers
4320
*
@@ -183,76 +160,6 @@ bigint_shr_raw ( uint64_t *value0, unsigned int size ) {
183160
return ( low & 1 );
184161
}
185162

186-
/**
187-
* Test if big integer is equal to zero
188-
*
189-
* @v value0 Element 0 of big integer
190-
* @v size Number of elements
191-
* @ret is_zero Big integer is equal to zero
192-
*/
193-
static inline __attribute__ (( always_inline, pure )) int
194-
bigint_is_zero_raw ( const uint64_t *value0, unsigned int size ) {
195-
const uint64_t *value = value0;
196-
uint64_t value_i;
197-
198-
do {
199-
value_i = *(value++);
200-
if ( value_i )
201-
break;
202-
} while ( --size );
203-
204-
return ( value_i == 0 );
205-
}
206-
207-
/**
208-
* Compare big integers
209-
*
210-
* @v value0 Element 0 of big integer
211-
* @v reference0 Element 0 of reference big integer
212-
* @v size Number of elements
213-
* @ret geq Big integer is greater than or equal to the reference
214-
*/
215-
static inline __attribute__ (( always_inline, pure )) int
216-
bigint_is_geq_raw ( const uint64_t *value0, const uint64_t *reference0,
217-
unsigned int size ) {
218-
const uint64_t *value = ( value0 + size );
219-
const uint64_t *reference = ( reference0 + size );
220-
uint64_t value_i;
221-
uint64_t reference_i;
222-
223-
do {
224-
value_i = *(--value);
225-
reference_i = *(--reference);
226-
if ( value_i != reference_i )
227-
break;
228-
} while ( --size );
229-
230-
return ( value_i >= reference_i );
231-
}
232-
233-
/**
234-
* Find highest bit set in big integer
235-
*
236-
* @v value0 Element 0 of big integer
237-
* @v size Number of elements
238-
* @ret max_bit Highest bit set + 1 (or 0 if no bits set)
239-
*/
240-
static inline __attribute__ (( always_inline )) int
241-
bigint_max_set_bit_raw ( const uint64_t *value0, unsigned int size ) {
242-
const uint64_t *value = ( value0 + size );
243-
int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
244-
uint64_t value_i;
245-
246-
do {
247-
value_i = *(--value);
248-
max_bit -= ( 64 - fls ( value_i ) );
249-
if ( value_i )
250-
break;
251-
} while ( --size );
252-
253-
return max_bit;
254-
}
255-
256163
/**
257164
* Grow big integer
258165
*
@@ -285,25 +192,6 @@ bigint_shrink_raw ( const uint64_t *source0, unsigned int source_size __unused,
285192
memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
286193
}
287194

288-
/**
289-
* Finalise big integer
290-
*
291-
* @v value0 Element 0 of big integer to finalise
292-
* @v size Number of elements
293-
* @v out Output buffer
294-
* @v len Length of output buffer
295-
*/
296-
static inline __attribute__ (( always_inline )) void
297-
bigint_done_raw ( const uint64_t *value0, unsigned int size __unused,
298-
void *out, size_t len ) {
299-
const uint8_t *value_byte = ( ( const void * ) value0 );
300-
uint8_t *out_byte = ( out + len );
301-
302-
/* Copy raw data in reverse order */
303-
while ( len-- )
304-
*(--out_byte) = *(value_byte++);
305-
}
306-
307195
/**
308196
* Multiply big integer elements
309197
*

0 commit comments

Comments
 (0)