iPXE
bigint.h File Reference

Big integer support. More...

#include <assert.h>
#include <stdint.h>
#include <bits/bigint.h>

Go to the source code of this file.

Macros

#define bigint_t(size)
 Define a big-integer type.
#define bigint_required_size(len)
 Determine number of elements required for a big-integer type.
#define bigint_size(bigint)
 Determine number of elements in big-integer type.
#define bigint_ntoa(value)
 Transcribe big integer (for debugging).
#define bigint_init(value, data, len)
 Initialise big integer.
#define bigint_done(value, out, len)
 Finalise big integer.
#define bigint_add(addend, value)
 Add big integers.
#define bigint_subtract(subtrahend, value)
 Subtract big integers.
#define bigint_shl(value)
 Shift big integer left.
#define bigint_shr(value)
 Shift big integer right.
#define bigint_is_zero(value)
 Test if big integer is equal to zero.
#define bigint_is_geq(value, reference)
 Compare big integers.
#define bigint_set_bit(value, bit)
 Set bit in big integer.
#define bigint_clear_bit(value, bit)
 Clear bit in big integer.
#define bigint_bit_is_set(value, bit)
 Test if bit is set in big integer.
#define bigint_msb_is_set(value)
 Test if most significant bit is set in big integer.
#define bigint_max_set_bit(value)
 Find highest bit set in big integer.
#define bigint_grow(source, dest)
 Grow big integer.
#define bigint_shrink(source, dest)
 Shrink big integer.
#define bigint_copy(source, dest)
 Copy big integer.
#define bigint_swap(first, second, swap)
 Conditionally swap big integers (in constant time).
#define bigint_multiply(multiplicand, multiplier, result)
 Multiply big integers.
#define bigint_reduce(modulus, result)
 Reduce big integer R^2 modulo N.
#define bigint_mod_invert(invertend, inverse)
 Compute inverse of odd big integer modulo any power of two.
#define bigint_montgomery_relaxed(modulus, value, result)
 Perform relaxed Montgomery reduction (REDC) of a big integer.
#define bigint_montgomery(modulus, value, result)
 Perform classic Montgomery reduction (REDC) of a big integer.
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
 Perform generalised exponentiation via a Montgomery ladder.
#define bigint_mod_exp(base, modulus, exponent, result, tmp)
 Perform modular exponentiation of big integers.
#define bigint_mod_exp_tmp_len(modulus)
 Calculate temporary working space required for moduluar exponentiation.

Typedefs

typedef void bigint_ladder_op_t(const bigint_element_t *operand0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp)
 A big integer Montgomery ladder commutative operation.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static __attribute__ ((always_inline)) void bigint_set_bit_raw(bigint_element_t *value0
 Set bit in big integer.
 return (!!(value->element[index] &(1UL<< subindex)))
const char * bigint_ntoa_raw (const bigint_element_t *value0, unsigned int size)
 Transcribe big integer (for debugging).
void bigint_init_raw (bigint_element_t *value0, unsigned int size, const void *data, size_t len)
 Initialise big integer.
void bigint_done_raw (const bigint_element_t *value0, unsigned int size, void *out, size_t len)
 Finalise big integer.
int bigint_add_raw (const bigint_element_t *addend0, bigint_element_t *value0, unsigned int size)
int bigint_subtract_raw (const bigint_element_t *subtrahend0, 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)
int bigint_is_zero_raw (const bigint_element_t *value0, unsigned int size)
 Test if big integer is equal to zero.
int bigint_is_geq_raw (const bigint_element_t *value0, const bigint_element_t *reference0, unsigned int size)
 Compare big integers.
int bigint_bit_is_set_raw (const bigint_element_t *value0, unsigned int size, unsigned int bit)
int bigint_max_set_bit_raw (const bigint_element_t *value0, unsigned int size)
 Find highest bit set in big integer.
void bigint_grow_raw (const bigint_element_t *source0, unsigned int source_size, bigint_element_t *dest0, unsigned int dest_size)
void bigint_shrink_raw (const bigint_element_t *source0, unsigned int source_size, bigint_element_t *dest0, unsigned int dest_size)
void bigint_swap_raw (bigint_element_t *first0, bigint_element_t *second0, unsigned int size, int swap)
 Conditionally swap big integers (in constant time).
void bigint_multiply_one (const bigint_element_t multiplicand, const bigint_element_t multiplier, bigint_element_t *result, bigint_element_t *carry)
void bigint_multiply_raw (const bigint_element_t *multiplicand0, unsigned int multiplicand_size, const bigint_element_t *multiplier0, unsigned int multiplier_size, bigint_element_t *result0)
 Multiply big integers.
void bigint_reduce_raw (const bigint_element_t *modulus0, bigint_element_t *result0, unsigned int size)
 Reduce big integer R^2 modulo N.
void bigint_mod_invert_raw (const bigint_element_t *invertend0, bigint_element_t *inverse0, unsigned int size)
 Compute inverse of odd big integer modulo any power of two.
int bigint_montgomery_relaxed_raw (const bigint_element_t *modulus0, bigint_element_t *value0, bigint_element_t *result0, unsigned int size)
 Perform relaxed Montgomery reduction (REDC) of a big integer.
void bigint_montgomery_raw (const bigint_element_t *modulus0, bigint_element_t *value0, bigint_element_t *result0, unsigned int size)
 Perform classic Montgomery reduction (REDC) of a big integer.
void bigint_ladder_raw (bigint_element_t *result0, bigint_element_t *multiple0, unsigned int size, const bigint_element_t *exponent0, unsigned int exponent_size, bigint_ladder_op_t *op, const void *ctx, void *tmp)
 Perform generalised exponentiation via a Montgomery ladder.
void bigint_mod_exp_ladder (const bigint_element_t *multiplier0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp)
 Perform modular multiplication as part of a Montgomery ladder.
void bigint_mod_exp_raw (const bigint_element_t *base0, const bigint_element_t *modulus0, const bigint_element_t *exponent0, bigint_element_t *result0, unsigned int size, unsigned int exponent_size, void *tmp)
 Perform modular exponentiation of big integers.

Variables

static unsigned int size
static unsigned int unsigned int bit
unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) )
unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) )
value element [index] = ( 1UL << subindex )

Detailed Description

Big integer support.

Definition in file bigint.h.

Macro Definition Documentation

◆ bigint_t

#define bigint_t ( size)
Value:
struct { \
}
uint32_t bigint_element_t
Element of a big integer.
Definition bigint.h:15
uint16_t size
Buffer size.
Definition dwmac.h:3
value element[index]
Definition bigint.h:396

Define a big-integer type.

Parameters
sizeNumber of elements
Return values
bigint_tBig integer type

Definition at line 21 of file bigint.h.

21#define bigint_t( size ) \
22 struct { \
23 bigint_element_t element[ (size) ]; \
24 }

Referenced by bigint_add_okx(), bigint_add_sample(), bigint_bit_is_set_okx(), bigint_bit_is_set_sample(), bigint_copy_sample(), bigint_done_raw(), bigint_done_sample(), bigint_grow_sample(), bigint_init_raw(), bigint_init_sample(), bigint_is_geq_okx(), bigint_is_geq_raw(), bigint_is_geq_sample(), bigint_is_zero_okx(), bigint_is_zero_raw(), bigint_is_zero_sample(), bigint_ladder_raw(), bigint_max_set_bit_okx(), bigint_max_set_bit_raw(), bigint_max_set_bit_sample(), bigint_mod_exp_ladder(), bigint_mod_exp_okx(), bigint_mod_exp_raw(), bigint_mod_exp_sample(), bigint_mod_invert_okx(), bigint_mod_invert_raw(), bigint_mod_invert_sample(), bigint_montgomery_okx(), bigint_montgomery_raw(), bigint_montgomery_relaxed_raw(), bigint_montgomery_sample(), bigint_multiply_okx(), bigint_multiply_raw(), bigint_multiply_sample(), bigint_ntoa_raw(), bigint_reduce_okx(), bigint_reduce_raw(), bigint_reduce_sample(), bigint_shl_okx(), bigint_shl_sample(), bigint_shr_okx(), bigint_shr_sample(), bigint_shrink_sample(), bigint_subtract_okx(), bigint_subtract_sample(), bigint_swap_okx(), bigint_swap_sample(), x25519_multiply_step1::bigint_t(), x25519_multiply_step2::bigint_t(), ecdsa_alloc(), ecdsa_init_values(), ecdsa_invert(), ecdsa_parse_signature(), ecdsa_prepend_signature(), ecdsa_sign_rs(), ecdsa_verify_rs(), elliptic_curve_okx(), ffdhe(), rsa_alloc(), rsa_cipher(), rsa_init(), weierstrass_add_raw(), weierstrass_done_raw(), weierstrass_exec(), weierstrass_init_curve(), weierstrass_init_raw(), weierstrass_is_infinity(), weierstrass_multiply(), and weierstrass_verify_raw().

◆ bigint_required_size

#define bigint_required_size ( len)
Value:
( (len) ? ( ( (len) + sizeof ( bigint_element_t ) - 1 ) / \
sizeof ( bigint_element_t ) ) : 1 )
ring len
Length.
Definition dwmac.h:226

Determine number of elements required for a big-integer type.

Parameters
lenMaximum length of big integer, in bytes
Return values
sizeNumber of elements

Definition at line 32 of file bigint.h.

32#define bigint_required_size( len ) \
33 ( (len) ? ( ( (len) + sizeof ( bigint_element_t ) - 1 ) / \
34 sizeof ( bigint_element_t ) ) : 1 )

Referenced by bigint_add_okx(), bigint_bit_is_set_okx(), bigint_is_geq_okx(), bigint_is_zero_okx(), bigint_max_set_bit_okx(), bigint_mod_exp_okx(), bigint_mod_invert_okx(), bigint_montgomery_okx(), bigint_multiply_okx(), bigint_reduce_okx(), bigint_shl_okx(), bigint_shr_okx(), bigint_subtract_okx(), bigint_swap_okx(), bigint_t(), x25519_multiply_step1::bigint_t(), x25519_multiply_step2::bigint_t(), ecdsa_alloc(), elliptic_curve_okx(), rsa_alloc(), and weierstrass_multiply().

◆ bigint_size

#define bigint_size ( bigint)
Value:
( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) )

Determine number of elements in big-integer type.

Parameters
bigintBig integer
Return values
sizeNumber of elements

Definition at line 42 of file bigint.h.

42#define bigint_size( bigint ) \
43 ( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) )

Referenced by bigint_add_okx(), bigint_is_geq_okx(), bigint_mod_exp_okx(), bigint_multiply_okx(), bigint_reduce_okx(), bigint_subtract_okx(), and weierstrass_add_ladder().

◆ bigint_ntoa

#define bigint_ntoa ( value)
Value:
( { \
unsigned int size = bigint_size (value); \
bigint_ntoa_raw ( (value)->element, size ); \
} )
pseudo_bit_t value[0x00020]
Definition arbel.h:2
#define bigint_size(bigint)
Determine number of elements in big-integer type.
Definition bigint.h:42

Transcribe big integer (for debugging).

Parameters
valueBig integer to be transcribed
Return values
stringBig integer in string form (may be abbreviated)

Definition at line 51 of file bigint.h.

51#define bigint_ntoa( value ) ( { \
52 unsigned int size = bigint_size (value); \
53 bigint_ntoa_raw ( (value)->element, size ); \
54 } )

Referenced by bigint_add_okx(), bigint_bit_is_set_okx(), bigint_is_geq_okx(), bigint_is_zero_okx(), bigint_max_set_bit_okx(), bigint_mod_exp_okx(), bigint_mod_invert_okx(), bigint_montgomery_okx(), bigint_multiply_okx(), bigint_reduce_okx(), bigint_shl_okx(), bigint_shr_okx(), bigint_subtract_okx(), ecdsa_init_values(), ecdsa_sign_rs(), ecdsa_verify_rs(), ffdhe(), weierstrass_add_raw(), weierstrass_done_raw(), weierstrass_exec(), weierstrass_init_curve(), weierstrass_init_raw(), weierstrass_is_infinity(), and weierstrass_multiply().

◆ bigint_init

#define bigint_init ( value,
data,
len )
Value:
do { \
unsigned int size = bigint_size (value); \
assert ( (len) <= ( size * sizeof ( (value)->element[0] ) ) ); \
bigint_init_raw ( (value)->element, size, (data), (len) ); \
} while ( 0 )
uint8_t data[48]
Additional event data.
Definition ena.h:11

Initialise big integer.

Parameters
valueBig integer to initialise
dataRaw data
lenLength of raw data

Definition at line 63 of file bigint.h.

63#define bigint_init( value, data, len ) do { \
64 unsigned int size = bigint_size (value); \
65 assert ( (len) <= ( size * sizeof ( (value)->element[0] ) ) ); \
66 bigint_init_raw ( (value)->element, size, (data), (len) ); \
67 } while ( 0 )

Referenced by bigint_add_okx(), bigint_bit_is_set_okx(), bigint_init_sample(), bigint_is_geq_okx(), bigint_is_zero_okx(), bigint_max_set_bit_okx(), bigint_mod_exp_okx(), bigint_mod_exp_raw(), bigint_mod_invert_okx(), bigint_montgomery_okx(), bigint_multiply_okx(), bigint_reduce_okx(), bigint_shl_okx(), bigint_shr_okx(), bigint_subtract_okx(), bigint_swap_okx(), ecdsa_init_values(), ecdsa_parse_signature(), ecdsa_sign_rs(), ecdsa_verify_rs(), elliptic_curve_okx(), ffdhe(), rsa_cipher(), rsa_init(), weierstrass_init_curve(), weierstrass_init_raw(), weierstrass_is_infinity(), weierstrass_multiply(), x25519_init_constants(), x25519_invert_okx(), x25519_is_zero(), x25519_key(), x25519_ladder(), and x25519_multiply_okx().

◆ bigint_done

#define bigint_done ( value,
out,
len )
Value:
do { \
unsigned int size = bigint_size (value); \
bigint_done_raw ( (value)->element, size, (out), (len) ); \
} while ( 0 )
__be32 out[4]
Definition CIB_PRM.h:8

Finalise big integer.

Parameters
valueBig integer to finalise
outOutput buffer
lenLength of output buffer

Definition at line 76 of file bigint.h.

76#define bigint_done( value, out, len ) do { \
77 unsigned int size = bigint_size (value); \
78 bigint_done_raw ( (value)->element, size, (out), (len) ); \
79 } while ( 0 )

Referenced by bigint_add_okx(), bigint_done_sample(), bigint_mod_exp_okx(), bigint_mod_invert_okx(), bigint_montgomery_okx(), bigint_multiply_okx(), bigint_reduce_okx(), bigint_shl_okx(), bigint_shr_okx(), bigint_subtract_okx(), bigint_swap_okx(), ecdsa_prepend_signature(), ecdsa_verify_rs(), elliptic_curve_okx(), ffdhe(), rsa_cipher(), weierstrass_done_raw(), and x25519_key().

◆ bigint_add

#define bigint_add ( addend,
value )
Value:
( { \
unsigned int size = bigint_size (addend); \
bigint_add_raw ( (addend)->element, (value)->element, size ); \
} )

Add big integers.

Parameters
addendBig integer to add
valueBig integer to be added to
Return values
carryCarry out

Definition at line 88 of file bigint.h.

88#define bigint_add( addend, value ) ( { \
89 unsigned int size = bigint_size (addend); \
90 bigint_add_raw ( (addend)->element, (value)->element, size ); \
91 } )

Referenced by bigint_add_okx(), bigint_add_sample(), bigint_mod_exp_raw(), bigint_mod_invert_raw(), bigint_montgomery_relaxed_raw(), bigint_reduce_raw(), ecdsa_sign_rs(), elliptic_curve_okx(), ffdhe(), weierstrass_exec(), weierstrass_init_curve(), x25519_add(), x25519_init_constants(), x25519_multiply(), and x25519_subtract().

◆ bigint_subtract

#define bigint_subtract ( subtrahend,
value )
Value:
( { \
unsigned int size = bigint_size (subtrahend); \
bigint_subtract_raw ( (subtrahend)->element, (value)->element, \
size ); \
} )

Subtract big integers.

Parameters
subtrahendBig integer to subtract
valueBig integer to be subtracted from
Return values
borrowBorrow out

Definition at line 100 of file bigint.h.

100#define bigint_subtract( subtrahend, value ) ( { \
101 unsigned int size = bigint_size (subtrahend); \
102 bigint_subtract_raw ( (subtrahend)->element, (value)->element, \
103 size ); \
104 } )

Referenced by bigint_mod_exp_raw(), bigint_montgomery_raw(), bigint_reduce_raw(), bigint_subtract_okx(), bigint_subtract_sample(), ecdsa_init_values(), ecdsa_verify_rs(), weierstrass_exec(), weierstrass_init_curve(), x25519_reduce_by(), and x25519_subtract().

◆ bigint_shl

#define bigint_shl ( value)
Value:
( { \
unsigned int size = bigint_size (value); \
bigint_shl_raw ( (value)->element, size ); \
} )

Shift big integer left.

Parameters
valueBig integer
Return values
outBit shifted out

Definition at line 112 of file bigint.h.

112#define bigint_shl( value ) ( { \
113 unsigned int size = bigint_size (value); \
114 bigint_shl_raw ( (value)->element, size ); \
115 } )

Referenced by bigint_reduce_raw(), bigint_shl_okx(), and bigint_shl_sample().

◆ bigint_shr

#define bigint_shr ( value)
Value:
( { \
unsigned int size = bigint_size (value); \
bigint_shr_raw ( (value)->element, size ); \
} )

Shift big integer right.

Parameters
valueBig integer
Return values
outBit shifted out

Definition at line 123 of file bigint.h.

123#define bigint_shr( value ) ( { \
124 unsigned int size = bigint_size (value); \
125 bigint_shr_raw ( (value)->element, size ); \
126 } )

Referenced by bigint_mod_exp_raw(), bigint_mod_invert_raw(), bigint_shr_okx(), and bigint_shr_sample().

◆ bigint_is_zero

#define bigint_is_zero ( value)
Value:
( { \
unsigned int size = bigint_size (value); \
bigint_is_zero_raw ( (value)->element, size ); } )

Test if big integer is equal to zero.

Parameters
valueBig integer
sizeNumber of elements
Return values
is_zeroBig integer is equal to zero

Definition at line 135 of file bigint.h.

135#define bigint_is_zero( value ) ( { \
136 unsigned int size = bigint_size (value); \
137 bigint_is_zero_raw ( (value)->element, size ); } )

Referenced by bigint_is_zero_okx(), bigint_is_zero_sample(), ecdsa_parse_signature(), ecdsa_sign_rs(), ecdsa_verify_rs(), weierstrass_init_raw(), weierstrass_is_infinity(), weierstrass_verify_raw(), and x25519_is_zero().

◆ bigint_is_geq

#define bigint_is_geq ( value,
reference )
Value:
( { \
unsigned int size = bigint_size (value); \
bigint_is_geq_raw ( (value)->element, (reference)->element, \
size ); } )

Compare big integers.

Parameters
valueBig integer
referenceReference big integer
Return values
geqBig integer is greater than or equal to the reference

Definition at line 146 of file bigint.h.

146#define bigint_is_geq( value, reference ) ( { \
147 unsigned int size = bigint_size (value); \
148 bigint_is_geq_raw ( (value)->element, (reference)->element, \
149 size ); } )

Referenced by bigint_is_geq_okx(), bigint_is_geq_sample(), bigint_montgomery_raw(), bigint_reduce_raw(), ecdsa_parse_signature(), ecdsa_sign_rs(), and ffdhe().

◆ bigint_set_bit

#define bigint_set_bit ( value,
bit )
Value:
do { \
unsigned int size = bigint_size (value); \
bigint_set_bit_raw ( (value)->element, size, bit ); \
} while ( 0 )
static unsigned int unsigned int bit
Definition bigint.h:390

Set bit in big integer.

Parameters
valueBig integer
bitBit to set

Definition at line 157 of file bigint.h.

157#define bigint_set_bit( value, bit ) do { \
158 unsigned int size = bigint_size (value); \
159 bigint_set_bit_raw ( (value)->element, size, bit ); \
160 } while ( 0 )

Referenced by bigint_reduce_raw().

◆ bigint_clear_bit

#define bigint_clear_bit ( value,
bit )
Value:
do { \
unsigned int size = bigint_size (value); \
bigint_clear_bit_raw ( (value)->element, size, bit ); \
} while ( 0 )

Clear bit in big integer.

Parameters
valueBig integer
bitBit to set

Definition at line 168 of file bigint.h.

168#define bigint_clear_bit( value, bit ) do { \
169 unsigned int size = bigint_size (value); \
170 bigint_clear_bit_raw ( (value)->element, size, bit ); \
171 } while ( 0 )

◆ bigint_bit_is_set

#define bigint_bit_is_set ( value,
bit )
Value:
( { \
unsigned int size = bigint_size (value); \
bigint_bit_is_set_raw ( (value)->element, size, bit ); } )

Test if bit is set in big integer.

Parameters
valueBig integer
bitBit to test
Return values
is_setBit is set

Definition at line 180 of file bigint.h.

180#define bigint_bit_is_set( value, bit ) ( { \
181 unsigned int size = bigint_size (value); \
182 bigint_bit_is_set_raw ( (value)->element, size, bit ); } )

Referenced by bigint_add_okx(), bigint_bit_is_set_okx(), bigint_bit_is_set_sample(), bigint_ladder_raw(), bigint_mod_exp_raw(), bigint_mod_invert_raw(), bigint_montgomery_relaxed_raw(), and bigint_shl_okx().

◆ bigint_msb_is_set

#define bigint_msb_is_set ( value)
Value:
( { \
unsigned int size = bigint_size (value); \
bigint_msb_is_set_raw ( (value)->element, size ); } )

Test if most significant bit is set in big integer.

Parameters
valueBig integer
Return values
is_setMost significant bit is set

Definition at line 190 of file bigint.h.

190#define bigint_msb_is_set( value ) ( { \
191 unsigned int size = bigint_size (value); \
192 bigint_msb_is_set_raw ( (value)->element, size ); } )

◆ bigint_max_set_bit

#define bigint_max_set_bit ( value)
Value:
( { \
unsigned int size = bigint_size (value); \
bigint_max_set_bit_raw ( (value)->element, size ); } )

Find highest bit set in big integer.

Parameters
valueBig integer
Return values
max_bitHighest bit set + 1 (or 0 if no bits set)

Definition at line 200 of file bigint.h.

200#define bigint_max_set_bit( value ) ( { \
201 unsigned int size = bigint_size (value); \
202 bigint_max_set_bit_raw ( (value)->element, size ); } )

Referenced by bigint_max_set_bit_okx(), bigint_max_set_bit_sample(), bigint_mod_exp_raw(), and bigint_reduce_raw().

◆ bigint_grow

#define bigint_grow ( source,
dest )
Value:
do { \
unsigned int source_size = bigint_size (source); \
unsigned int dest_size = bigint_size (dest); \
bigint_grow_raw ( (source)->element, source_size, \
} while ( 0 )
static unsigned int source_size
Definition bigint.h:141
static unsigned int uint32_t unsigned int dest_size
Definition bigint.h:142
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

Grow big integer.

Parameters
sourceSource big integer
destDestination big integer

Definition at line 210 of file bigint.h.

210#define bigint_grow( source, dest ) do { \
211 unsigned int source_size = bigint_size (source); \
212 unsigned int dest_size = bigint_size (dest); \
213 bigint_grow_raw ( (source)->element, source_size, \
214 (dest)->element, dest_size ); \
215 } while ( 0 )

Referenced by bigint_grow_sample(), bigint_mod_exp_raw(), ecdsa_init_values(), weierstrass_done_raw(), weierstrass_verify_raw(), and x25519_multiply().

◆ bigint_shrink

#define bigint_shrink ( source,
dest )
Value:
do { \
unsigned int source_size = bigint_size (source); \
unsigned int dest_size = bigint_size (dest); \
bigint_shrink_raw ( (source)->element, source_size, \
} while ( 0 )

Shrink big integer.

Parameters
sourceSource big integer
destDestination big integer

Definition at line 223 of file bigint.h.

223#define bigint_shrink( source, dest ) do { \
224 unsigned int source_size = bigint_size (source); \
225 unsigned int dest_size = bigint_size (dest); \
226 bigint_shrink_raw ( (source)->element, source_size, \
227 (dest)->element, dest_size ); \
228 } while ( 0 )

Referenced by bigint_mod_exp_ladder(), and bigint_shrink_sample().

◆ bigint_copy

#define bigint_copy ( source,
dest )
Value:
do { \
build_assert ( sizeof ( *(source) ) == sizeof ( *(dest) ) ); \
bigint_shrink ( (source), (dest) ); \
} while ( 0 )

Copy big integer.

Parameters
sourceSource big integer
destDestination big integer

Definition at line 236 of file bigint.h.

236#define bigint_copy( source, dest ) do { \
237 build_assert ( sizeof ( *(source) ) == sizeof ( *(dest) ) ); \
238 bigint_shrink ( (source), (dest) ); \
239 } while ( 0 )

Referenced by bigint_copy_sample(), bigint_mod_exp_raw(), bigint_montgomery_relaxed_raw(), ecdsa_init_values(), ecdsa_invert(), weierstrass_done_raw(), weierstrass_exec(), weierstrass_init_curve(), weierstrass_init_raw(), weierstrass_multiply(), x25519_add(), x25519_init_constants(), x25519_invert(), x25519_ladder(), x25519_reduce_by(), and x25519_subtract().

◆ bigint_swap

#define bigint_swap ( first,
second,
swap )
Value:
do { \
unsigned int size = bigint_size (first); \
bigint_swap_raw ( (first)->element, (second)->element, size, \
(swap) ); \
} while ( 0 )
uint32_t first
First block in range.
Definition pccrr.h:1

Conditionally swap big integers (in constant time).

Parameters
firstBig integer to be conditionally swapped
secondBig integer to be conditionally swapped
swapSwap first and second big integers

Definition at line 248 of file bigint.h.

248#define bigint_swap( first, second, swap ) do { \
249 unsigned int size = bigint_size (first); \
250 bigint_swap_raw ( (first)->element, (second)->element, size, \
251 (swap) ); \
252 } while ( 0 )

Referenced by bigint_ladder_raw(), bigint_montgomery_raw(), bigint_swap_okx(), bigint_swap_sample(), x25519_reduce_by(), and x25519_step().

◆ bigint_multiply

#define bigint_multiply ( multiplicand,
multiplier,
result )
Value:
do { \
unsigned int multiplicand_size = bigint_size (multiplicand); \
unsigned int multiplier_size = bigint_size (multiplier); \
bigint_multiply_raw ( (multiplicand)->element, \
multiplicand_size, (multiplier)->element, \
multiplier_size, (result)->element ); \
} while ( 0 )
uint16_t result
Definition hyperv.h:33
static const uint32_t multiplier
Port multiplier number.
Definition bigint.h:195

Multiply big integers.

Parameters
multiplicandBig integer to be multiplied
multiplierBig integer to be multiplied
resultBig integer to hold result

Definition at line 261 of file bigint.h.

261#define bigint_multiply( multiplicand, multiplier, result ) do { \
262 unsigned int multiplicand_size = bigint_size (multiplicand); \
263 unsigned int multiplier_size = bigint_size (multiplier); \
264 bigint_multiply_raw ( (multiplicand)->element, \
265 multiplicand_size, (multiplier)->element, \
266 multiplier_size, (result)->element ); \
267 } while ( 0 )

Referenced by bigint_mod_exp_ladder(), bigint_mod_exp_raw(), bigint_multiply_okx(), bigint_multiply_sample(), ecdsa_invert(), ecdsa_sign_rs(), ecdsa_verify_rs(), weierstrass_done_raw(), weierstrass_exec(), weierstrass_init_curve(), weierstrass_init_raw(), and x25519_multiply().

◆ bigint_reduce

#define bigint_reduce ( modulus,
result )
Value:
do { \
unsigned int size = bigint_size (modulus); \
bigint_reduce_raw ( (modulus)->element, (result)->element, \
size ); \
} while ( 0 )

Reduce big integer R^2 modulo N.

Parameters
modulusBig integer modulus
resultBig integer to hold result

Definition at line 275 of file bigint.h.

275#define bigint_reduce( modulus, result ) do { \
276 unsigned int size = bigint_size (modulus); \
277 bigint_reduce_raw ( (modulus)->element, (result)->element, \
278 size ); \
279 } while ( 0 )

Referenced by bigint_mod_exp_raw(), bigint_reduce_okx(), bigint_reduce_sample(), ecdsa_init_values(), and weierstrass_init_curve().

◆ bigint_mod_invert

#define bigint_mod_invert ( invertend,
inverse )
Value:
do { \
unsigned int size = bigint_size ( inverse ); \
bigint_mod_invert_raw ( (invertend)->element, \
(inverse)->element, size ); \
} while ( 0 )

Compute inverse of odd big integer modulo any power of two.

Parameters
invertendOdd big integer to be inverted
inverseBig integer to hold result

Definition at line 287 of file bigint.h.

287#define bigint_mod_invert( invertend, inverse ) do { \
288 unsigned int size = bigint_size ( inverse ); \
289 bigint_mod_invert_raw ( (invertend)->element, \
290 (inverse)->element, size ); \
291 } while ( 0 )

Referenced by bigint_mod_exp_raw(), bigint_mod_invert_okx(), bigint_mod_invert_sample(), and bigint_montgomery_relaxed_raw().

◆ bigint_montgomery_relaxed

#define bigint_montgomery_relaxed ( modulus,
value,
result )
Value:
( { \
unsigned int size = bigint_size (modulus); \
bigint_montgomery_relaxed_raw ( (modulus)->element, \
(value)->element, \
(result)->element, size ); \
} )

Perform relaxed Montgomery reduction (REDC) of a big integer.

Parameters
modulusBig integer odd modulus
valueBig integer to be reduced
resultBig integer to hold result
Return values
carryCarry out

Definition at line 301 of file bigint.h.

301#define bigint_montgomery_relaxed( modulus, value, result ) ( { \
302 unsigned int size = bigint_size (modulus); \
303 bigint_montgomery_relaxed_raw ( (modulus)->element, \
304 (value)->element, \
305 (result)->element, size ); \
306 } )

Referenced by bigint_mod_exp_raw(), bigint_montgomery_raw(), weierstrass_done_raw(), weierstrass_exec(), and weierstrass_init_raw().

◆ bigint_montgomery

#define bigint_montgomery ( modulus,
value,
result )
Value:
do { \
unsigned int size = bigint_size (modulus); \
bigint_montgomery_raw ( (modulus)->element, (value)->element, \
(result)->element, size ); \
} while ( 0 )

Perform classic Montgomery reduction (REDC) of a big integer.

Parameters
modulusBig integer odd modulus
valueBig integer to be reduced
resultBig integer to hold result

Definition at line 315 of file bigint.h.

315#define bigint_montgomery( modulus, value, result ) do { \
316 unsigned int size = bigint_size (modulus); \
317 bigint_montgomery_raw ( (modulus)->element, (value)->element, \
318 (result)->element, size ); \
319 } while ( 0 )

Referenced by bigint_mod_exp_ladder(), bigint_mod_exp_raw(), bigint_montgomery_okx(), bigint_montgomery_sample(), ecdsa_init_values(), ecdsa_invert(), ecdsa_sign_rs(), ecdsa_verify_rs(), weierstrass_done_raw(), weierstrass_init_curve(), and weierstrass_verify_raw().

◆ bigint_ladder

#define bigint_ladder ( result,
multiple,
exponent,
op,
ctx,
tmp )
Value:
do { \
unsigned int size = bigint_size (result); \
unsigned int exponent_size = bigint_size (exponent); \
bigint_ladder_raw ( (result)->element, (multiple)->element, \
size, (exponent)->element, exponent_size, \
(op), (ctx), (tmp) ); \
} while ( 0 )
struct golan_eq_context ctx
Definition CIB_PRM.h:0
unsigned long tmp
Definition linux_pci.h:65
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327

Perform generalised exponentiation via a Montgomery ladder.

Parameters
resultBig integer result (initialised to identity element)
multipleBig integer multiple (initialised to generator)
exponentBig integer exponent
opMontgomery ladder commutative operation
ctxOperation context (if needed)
tmpTemporary working space (if needed)

Definition at line 331 of file bigint.h.

331#define bigint_ladder( result, multiple, exponent, op, ctx, tmp ) do { \
332 unsigned int size = bigint_size (result); \
333 unsigned int exponent_size = bigint_size (exponent); \
334 bigint_ladder_raw ( (result)->element, (multiple)->element, \
335 size, (exponent)->element, exponent_size, \
336 (op), (ctx), (tmp) ); \
337 } while ( 0 )

Referenced by bigint_mod_exp_raw(), ecdsa_invert(), weierstrass_done_raw(), and weierstrass_multiply().

◆ bigint_mod_exp

#define bigint_mod_exp ( base,
modulus,
exponent,
result,
tmp )
Value:
do { \
unsigned int size = bigint_size (base); \
unsigned int exponent_size = bigint_size (exponent); \
bigint_mod_exp_raw ( (base)->element, (modulus)->element, \
(exponent)->element, (result)->element, \
size, exponent_size, tmp ); \
} while ( 0 )
uint32_t base
Base.
Definition librm.h:3

Perform modular exponentiation of big integers.

Parameters
baseBig integer base
modulusBig integer modulus
exponentBig integer exponent
resultBig integer to hold result
tmpTemporary working space

Definition at line 348 of file bigint.h.

348#define bigint_mod_exp( base, modulus, exponent, result, tmp ) do { \
349 unsigned int size = bigint_size (base); \
350 unsigned int exponent_size = bigint_size (exponent); \
351 bigint_mod_exp_raw ( (base)->element, (modulus)->element, \
352 (exponent)->element, (result)->element, \
353 size, exponent_size, tmp ); \
354 } while ( 0 )

Referenced by bigint_mod_exp_okx(), bigint_mod_exp_sample(), ffdhe(), and rsa_cipher().

◆ bigint_mod_exp_tmp_len

#define bigint_mod_exp_tmp_len ( modulus)
Value:
sizeof ( struct { typeof ( *(modulus) ) temp[4]; } )
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48

Calculate temporary working space required for moduluar exponentiation.

Parameters
modulusBig integer modulus
Return values
lenLength of temporary working space

Definition at line 362 of file bigint.h.

362#define bigint_mod_exp_tmp_len( modulus ) \
363 sizeof ( struct { typeof ( *(modulus) ) temp[4]; } )

Referenced by bigint_mod_exp_okx(), bigint_mod_exp_raw(), ffdhe(), and rsa_alloc().

Typedef Documentation

◆ bigint_ladder_op_t

typedef void bigint_ladder_op_t(const bigint_element_t *operand0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp)

A big integer Montgomery ladder commutative operation.

Parameters
operandElement 0 of first input operand (may overlap result)
resultElement 0 of second input operand and result
sizeNumber of elements in operands and result
ctxOperation context (if needed)
tmpTemporary working space (if needed)

Definition at line 376 of file bigint.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ __attribute__()

__attribute__ ( (always_inline) )
inlinestatic

Set bit in big integer.

Test if most significant bit is set in big integer.

Test if bit is set in big integer.

Clear bit in big integer.

Parameters
value0Element 0 of big integer
sizeNumber of elements
bitBit to set
value0Element 0 of big integer
sizeNumber of elements
bitBit to clear
value0Element 0 of big integer
sizeNumber of elements
bitBit to test
Return values
is_setBit is set
Parameters
value0Element 0 of big integer
sizeNumber of elements
Return values
is_setMost significant bit is set

◆ return()

return ( !! value->element[index] &(1UL<< subindex))

References index, subindex, and value.

◆ bigint_ntoa_raw()

const char * bigint_ntoa_raw ( const bigint_element_t * value0,
unsigned int size )

Transcribe big integer (for debugging).

Parameters
value0Element 0 of big integer to be transcribed
sizeNumber of elements
Return values
stringBig integer in string form (may be abbreviated)

Definition at line 50 of file bigint.c.

51 {
52 const bigint_t ( size ) __attribute__ (( may_alias ))
53 *value = ( ( const void * ) value0 );
55 static char buf[256];
56 unsigned int count;
57 int threshold;
59 char *tmp;
60 int i;
61
62 /* Calculate abbreviation threshold, if any */
63 count = ( size * sizeof ( element ) );
64 threshold = count;
65 if ( count >= ( ( sizeof ( buf ) - 1 /* NUL */ ) / 2 /* "xx" */ ) ) {
66 threshold -= ( ( sizeof ( buf ) - 3 /* "..." */
67 - ( BIGINT_NTOA_LSB_MIN * 2 /* "xx" */ )
68 - 1 /* NUL */ ) / 2 /* "xx" */ );
69 }
70
71 /* Transcribe bytes, abbreviating with "..." if necessary */
72 for ( tmp = buf, i = ( count - 1 ) ; i >= 0 ; i-- ) {
73 element = value->element[ i / sizeof ( element ) ];
74 byte = ( element >> ( 8 * ( i % sizeof ( element ) ) ) );
75 tmp += sprintf ( tmp, "%02x", byte );
76 if ( i == threshold ) {
77 tmp += sprintf ( tmp, "..." );
79 }
80 }
81 assert ( tmp < ( buf + sizeof ( buf ) ) );
82
83 return buf;
84}
unsigned char uint8_t
Definition stdint.h:10
static uint32_t * value0
Definition bigint.h:26
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
#define BIGINT_NTOA_LSB_MIN
Minimum number of least significant bytes included in transcription.
Definition bigint.c:41
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define __attribute__(x)
Definition compiler.h:10
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:21
unsigned char byte
Definition smc9000.h:38
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition stdio.h:37

References __attribute__, assert, BIGINT_NTOA_LSB_MIN, bigint_t, count, element, size, sprintf, tmp, value, and value0.

◆ bigint_init_raw()

void bigint_init_raw ( bigint_element_t * value0,
unsigned int size,
const void * data,
size_t len )

Initialise big integer.

Parameters
value0Element 0 of big integer to initialise
sizeNumber of elements
dataRaw data
lenLength of raw data

Definition at line 94 of file bigint.c.

95 {
96 bigint_t ( size ) __attribute__ (( may_alias ))
97 *value = ( ( void * ) value0 );
98 uint8_t *value_byte = ( ( void * ) value0 );
99 const uint8_t *data_byte = data;
100 unsigned int toggle;
101 unsigned int i;
102
103 /* Zero big integer */
104 memset ( value, 0, sizeof ( *value ) );
105
106 /* Copy data, byte-swapping as needed */
107 toggle = ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ? 0 :
108 ( sizeof ( value->element[0] ) - 1 ) );
109 for ( i = 0 ; len-- ; i++ )
110 value_byte[ i ^ toggle ] = data_byte[len];
111}
#define __BYTE_ORDER
Definition endian.h:7
#define __LITTLE_ENDIAN
Constant representing little-endian byte order.
Definition endian.h:13
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, __BYTE_ORDER, __LITTLE_ENDIAN, bigint_t, data, len, memset(), size, value, and value0.

◆ bigint_done_raw()

void bigint_done_raw ( const bigint_element_t * value0,
unsigned int size,
void * out,
size_t len )

Finalise big integer.

Parameters
value0Element 0 of big integer to finalise
sizeNumber of elements
outOutput buffer
lenLength of output buffer

Definition at line 121 of file bigint.c.

122 {
123 const bigint_t ( size ) __attribute__ (( may_alias ))
124 *value = ( ( const void * ) value0 );
125 const uint8_t *value_byte = ( ( const void * ) value0 );
126 uint8_t *out_byte = out;
127 unsigned int toggle;
128 unsigned int i;
129
130 /* Zero output buffer */
131 memset ( out, 0, len );
132
133 /* Copy data, byte-swapping as needed */
134 toggle = ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ? 0 :
135 ( sizeof ( value->element[0] ) - 1 ) );
136 for ( i = 0 ; len-- ; i++ )
137 out_byte[len] = value_byte[ i ^ toggle ];
138}

References __attribute__, __BYTE_ORDER, __LITTLE_ENDIAN, bigint_t, len, memset(), out, size, value, and value0.

◆ bigint_add_raw()

int bigint_add_raw ( const bigint_element_t * addend0,
bigint_element_t * value0,
unsigned int size )

References size, and value0.

◆ bigint_subtract_raw()

int bigint_subtract_raw ( const bigint_element_t * subtrahend0,
bigint_element_t * value0,
unsigned int size )

References size, and value0.

◆ bigint_shl_raw()

int bigint_shl_raw ( bigint_element_t * value0,
unsigned int size )

References size, and value0.

◆ bigint_shr_raw()

int bigint_shr_raw ( bigint_element_t * value0,
unsigned int size )

References size, and value0.

◆ bigint_is_zero_raw()

int bigint_is_zero_raw ( const bigint_element_t * value0,
unsigned int size )

Test if big integer is equal to zero.

Parameters
value0Element 0 of big integer
sizeNumber of elements
Return values
is_zeroBig integer is equal to zero

Definition at line 147 of file bigint.c.

147 {
148 const bigint_t ( size ) __attribute__ (( may_alias )) *value =
149 ( ( const void * ) value0 );
151 unsigned int i;
152
153 /* Construct binary OR of all elements */
154 for ( i = 0, or = 0 ; i < size ; i++ )
155 or |= value->element[i];
156
157 return ( or == 0 );
158}

References __attribute__, bigint_t, size, value, and value0.

◆ bigint_is_geq_raw()

int bigint_is_geq_raw ( const bigint_element_t * value0,
const bigint_element_t * reference0,
unsigned int size )

Compare big integers.

Parameters
value0Element 0 of big integer
reference0Element 0 of reference big integer
sizeNumber of elements
Return values
geqBig integer is greater than or equal to the reference

Definition at line 168 of file bigint.c.

170 {
171 const bigint_t ( size ) __attribute__ (( may_alias )) *value =
172 ( ( const void * ) value0 );
173 const bigint_t ( size ) __attribute__ (( may_alias )) *reference =
174 ( ( const void * ) reference0 );
175 bigint_element_t value_element;
176 bigint_element_t reference_element;
177
178 /* Find highest differing element */
179 do {
180 value_element = value->element[ size - 1 ];
181 reference_element = reference->element[ size - 1 ];
182 if ( value_element != reference_element )
183 break;
184 } while ( --size );
185
186 return ( value_element >= reference_element );
187}

References __attribute__, bigint_t, size, value, and value0.

◆ bigint_bit_is_set_raw()

int bigint_bit_is_set_raw ( const bigint_element_t * value0,
unsigned int size,
unsigned int bit )

References bit, size, and value0.

◆ bigint_max_set_bit_raw()

int bigint_max_set_bit_raw ( const bigint_element_t * value0,
unsigned int size )

Find highest bit set in big integer.

Parameters
value0Element 0 of big integer
sizeNumber of elements
Return values
max_bitHighest bit set + 1 (or 0 if no bits set)

Definition at line 196 of file bigint.c.

197 {
198 const bigint_t ( size ) __attribute__ (( may_alias )) *value =
199 ( ( const void * ) value0 );
201 unsigned int max_bit;
202 unsigned int i;
203
204 /* Find highest set bit in highest non-zero element */
205 max_bit = ( sizeof ( *value ) * 8 );
206 for ( i = 0 ; i < size ; i++ ) {
207 element = value->element[ size - i - 1 ];
208 max_bit -= ( sizeof ( element) * 8 );
209 if ( element ) {
210 max_bit += flsll ( element );
211 break;
212 }
213 }
214
215 return max_bit;
216}
#define flsll(x)
Find last (i.e.
Definition strings.h:149

References __attribute__, bigint_t, element, flsll, size, value, and value0.

◆ bigint_grow_raw()

void bigint_grow_raw ( const bigint_element_t * source0,
unsigned int source_size,
bigint_element_t * dest0,
unsigned int dest_size )

References dest0, dest_size, and source_size.

◆ bigint_shrink_raw()

void bigint_shrink_raw ( const bigint_element_t * source0,
unsigned int source_size,
bigint_element_t * dest0,
unsigned int dest_size )

References dest0, dest_size, size, and source_size.

◆ bigint_swap_raw()

void bigint_swap_raw ( bigint_element_t * first0,
bigint_element_t * second0,
unsigned int size,
int swap )

Conditionally swap big integers (in constant time).

Parameters
first0Element 0 of big integer to be conditionally swapped
second0Element 0 of big integer to be conditionally swapped
sizeNumber of elements in big integers
swapSwap first and second big integers

Definition at line 226 of file bigint.c.

227 {
228 bigint_element_t mask;
230 unsigned int i;
231
232 /* Construct mask */
233 mask = ( ( bigint_element_t ) ( ! swap ) - 1 );
234
235 /* Conditionally swap elements */
236 for ( i = 0 ; i < size ; i++ ) {
237 xor = ( mask & ( first0[i] ^ second0[i] ) );
238 first0[i] ^= xor;
239 second0[i] ^= xor;
240 }
241}
static u32 xor(u32 a, u32 b)
Definition tlan.h:457

References size, and xor().

◆ bigint_multiply_one()

void bigint_multiply_one ( const bigint_element_t multiplicand,
const bigint_element_t multiplier,
bigint_element_t * result,
bigint_element_t * carry )

◆ bigint_multiply_raw()

void bigint_multiply_raw ( const bigint_element_t * multiplicand0,
unsigned int multiplicand_size,
const bigint_element_t * multiplier0,
unsigned int multiplier_size,
bigint_element_t * result0 )

Multiply big integers.

Parameters
multiplicand0Element 0 of big integer to be multiplied
multiplicand_sizeNumber of elements in multiplicand
multiplier0Element 0 of big integer to be multiplied
multiplier_sizeNumber of elements in multiplier
result0Element 0 of big integer to hold result

Definition at line 252 of file bigint.c.

256 {
257 unsigned int result_size = ( multiplicand_size + multiplier_size );
258 const bigint_t ( multiplicand_size ) __attribute__ (( may_alias ))
259 *multiplicand = ( ( const void * ) multiplicand0 );
260 const bigint_t ( multiplier_size ) __attribute__ (( may_alias ))
261 *multiplier = ( ( const void * ) multiplier0 );
262 bigint_t ( result_size ) __attribute__ (( may_alias ))
263 *result = ( ( void * ) result0 );
264 bigint_element_t multiplicand_element;
265 const bigint_element_t *multiplier_element;
266 bigint_element_t *result_element;
267 bigint_element_t carry_element;
268 unsigned int i;
269 unsigned int j;
270
271 /* Zero required portion of result
272 *
273 * All elements beyond the length of the multiplier will be
274 * written before they are read, and so do not need to be
275 * zeroed in advance.
276 */
277 memset ( result, 0, sizeof ( *multiplier ) );
278
279 /* Multiply integers one element at a time, adding the low
280 * half of the double-element product directly into the
281 * result, and maintaining a running single-element carry.
282 *
283 * The running carry can never overflow beyond a single
284 * element. At each step, the calculation we perform is:
285 *
286 * carry:result[i+j] := ( ( multiplicand[i] * multiplier[j] )
287 * + result[i+j] + carry )
288 *
289 * The maximum value (for n-bit elements) is therefore:
290 *
291 * (2^n - 1)*(2^n - 1) + (2^n - 1) + (2^n - 1) = 2^(2n) - 1
292 *
293 * This is precisely the maximum value for a 2n-bit integer,
294 * and so the carry out remains within the range of an n-bit
295 * integer, i.e. a single element.
296 */
297 for ( i = 0 ; i < multiplicand_size ; i++ ) {
298 multiplicand_element = multiplicand->element[i];
299 multiplier_element = &multiplier->element[0];
300 result_element = &result->element[i];
301 carry_element = 0;
302 for ( j = 0 ; j < multiplier_size ; j++ ) {
303 bigint_multiply_one ( multiplicand_element,
304 *(multiplier_element++),
305 result_element++,
306 &carry_element );
307 }
308 *result_element = carry_element;
309 }
310}
void bigint_multiply_one(const bigint_element_t multiplicand, const bigint_element_t multiplier, bigint_element_t *result, bigint_element_t *carry)

References __attribute__, bigint_multiply_one(), bigint_t, memset(), multiplier, and result.

◆ bigint_reduce_raw()

void bigint_reduce_raw ( const bigint_element_t * modulus0,
bigint_element_t * result0,
unsigned int size )

Reduce big integer R^2 modulo N.

Parameters
modulus0Element 0 of big integer modulus
result0Element 0 of big integer to hold result
sizeNumber of elements in modulus and result

Reduce the value R^2 modulo N, where R=2^n and n is the number of bits in the representation of the modulus N, including any leading zero bits.

Definition at line 323 of file bigint.c.

324 {
325 const bigint_t ( size ) __attribute__ (( may_alias ))
326 *modulus = ( ( const void * ) modulus0 );
327 bigint_t ( size ) __attribute__ (( may_alias ))
328 *result = ( ( void * ) result0 );
329 const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
330 unsigned int shift;
331 int max;
332 int sign;
333 int msb;
334 int carry;
335
336 /* We have the constants:
337 *
338 * N = modulus
339 *
340 * n = number of bits in the modulus (including any leading zeros)
341 *
342 * R = 2^n
343 *
344 * Let r be the extension of the n-bit result register by a
345 * separate two's complement sign bit, such that -R <= r < R,
346 * and define:
347 *
348 * x = r * 2^k
349 *
350 * as the value being reduced modulo N, where k is a
351 * non-negative integer bit shift.
352 *
353 * We want to reduce the initial value R^2=2^(2n), which we
354 * may trivially represent using r=1 and k=2n.
355 *
356 * We then iterate over decrementing k, maintaining the loop
357 * invariant:
358 *
359 * -N <= r < N
360 *
361 * On each iteration we must first double r, to compensate for
362 * having decremented k:
363 *
364 * k' = k - 1
365 *
366 * r' = 2r
367 *
368 * x = r * 2^k = 2r * 2^(k-1) = r' * 2^k'
369 *
370 * Note that doubling the n-bit result register will create a
371 * value of n+1 bits: this extra bit needs to be handled
372 * separately during the calculation.
373 *
374 * We then subtract N (if r is currently non-negative) or add
375 * N (if r is currently negative) to restore the loop
376 * invariant:
377 *
378 * 0 <= r < N => r" = 2r - N => -N <= r" < N
379 * -N <= r < 0 => r" = 2r + N => -N <= r" < N
380 *
381 * Note that since N may use all n bits, the most significant
382 * bit of the n-bit result register is not a valid two's
383 * complement sign bit for r: the extra sign bit therefore
384 * also needs to be handled separately.
385 *
386 * Once we reach k=0, we have x=r and therefore:
387 *
388 * -N <= x < N
389 *
390 * After this last loop iteration (with k=0), we may need to
391 * add a single multiple of N to ensure that x is positive,
392 * i.e. lies within the range 0 <= x < N.
393 *
394 * Since neither the modulus nor the value R^2 are secret, we
395 * may elide approximately half of the total number of
396 * iterations by constructing the initial representation of
397 * R^2 as r=2^m and k=2n-m (for some m such that 2^m < N).
398 */
399
400 /* Initialise x=R^2 */
401 memset ( result, 0, sizeof ( *result ) );
402 max = ( bigint_max_set_bit ( modulus ) - 2 );
403 if ( max < 0 ) {
404 /* Degenerate case of N=0 or N=1: return a zero result */
405 return;
406 }
408 shift = ( ( 2 * size * width ) - max );
409 sign = 0;
410
411 /* Iterate as described above */
412 while ( shift-- ) {
413
414 /* Calculate 2r, storing extra bit separately */
415 msb = bigint_shl ( result );
416
417 /* Add or subtract N according to current sign */
418 if ( sign ) {
419 carry = bigint_add ( modulus, result );
420 } else {
421 carry = bigint_subtract ( modulus, result );
422 }
423
424 /* Calculate new sign of result
425 *
426 * We know the result lies in the range -N <= r < N
427 * and so the tuple (old sign, msb, carry) cannot ever
428 * take the values (0, 1, 0) or (1, 0, 0). We can
429 * therefore treat these as don't-care inputs, which
430 * allows us to simplify the boolean expression by
431 * ignoring the old sign completely.
432 */
433 assert ( ( sign == msb ) || carry );
434 sign = ( msb ^ carry );
435 }
436
437 /* Add N to make result positive if necessary */
438 if ( sign )
439 bigint_add ( modulus, result );
440
441 /* Sanity check */
442 assert ( ! bigint_is_geq ( result, modulus ) );
443}
int carry
Definition bigint.h:33
#define max(x, y)
Definition ath.h:41
#define bigint_set_bit(value, bit)
Set bit in big integer.
Definition bigint.h:157
#define bigint_shl(value)
Shift big integer left.
Definition bigint.h:112
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition bigint.h:100
#define bigint_max_set_bit(value)
Find highest bit set in big integer.
Definition bigint.h:200
#define bigint_is_geq(value, reference)
Compare big integers.
Definition bigint.h:146
#define bigint_add(addend, value)
Add big integers.
Definition bigint.h:88

References __attribute__, assert, bigint_add, bigint_is_geq, bigint_max_set_bit, bigint_set_bit, bigint_shl, bigint_subtract, bigint_t, carry, max, memset(), result, and size.

◆ bigint_mod_invert_raw()

void bigint_mod_invert_raw ( const bigint_element_t * invertend0,
bigint_element_t * inverse0,
unsigned int size )

Compute inverse of odd big integer modulo any power of two.

Parameters
invertend0Element 0 of odd big integer to be inverted
inverse0Element 0 of big integer to hold result
sizeNumber of elements in invertend and result

Definition at line 452 of file bigint.c.

453 {
454 const bigint_t ( size ) __attribute__ (( may_alias ))
455 *invertend = ( ( const void * ) invertend0 );
456 bigint_t ( size ) __attribute__ (( may_alias ))
457 *inverse = ( ( void * ) inverse0 );
458 bigint_element_t accum;
460 unsigned int i;
461
462 /* Sanity check */
463 assert ( bigint_bit_is_set ( invertend, 0 ) );
464
465 /* Initialise output */
466 memset ( inverse, 0xff, sizeof ( *inverse ) );
467
468 /* Compute inverse modulo 2^(width)
469 *
470 * This method is a lightly modified version of the pseudocode
471 * presented in "A New Algorithm for Inversion mod p^k (Koç,
472 * 2017)".
473 *
474 * Each inner loop iteration calculates one bit of the
475 * inverse. The residue value is the two's complement
476 * negation of the value "b" as used by Koç, to allow for
477 * division by two using a logical right shift (since we have
478 * no arithmetic right shift operation for big integers).
479 *
480 * The residue is stored in the as-yet uncalculated portion of
481 * the inverse. The size of the residue therefore decreases
482 * by one element for each outer loop iteration. Trivial
483 * inspection of the algorithm shows that any higher bits
484 * could not contribute to the eventual output value, and so
485 * we may safely reuse storage this way.
486 *
487 * Due to the suffix property of inverses mod 2^k, the result
488 * represents the least significant bits of the inverse modulo
489 * an arbitrarily large 2^k.
490 */
491 for ( i = size ; i > 0 ; i-- ) {
492 const bigint_t ( i ) __attribute__ (( may_alias ))
493 *addend = ( ( const void * ) invertend );
494 bigint_t ( i ) __attribute__ (( may_alias ))
495 *residue = ( ( void * ) inverse );
496
497 /* Calculate one element's worth of inverse bits */
498 for ( accum = 0, bit = 1 ; bit ; bit <<= 1 ) {
499 if ( bigint_bit_is_set ( residue, 0 ) ) {
500 accum |= bit;
501 bigint_add ( addend, residue );
502 }
503 bigint_shr ( residue );
504 }
505
506 /* Store in the element no longer required to hold residue */
507 inverse->element[ i - 1 ] = accum;
508 }
509
510 /* Correct order of inverse elements */
511 for ( i = 0 ; i < ( size / 2 ) ; i++ ) {
512 accum = inverse->element[i];
513 inverse->element[i] = inverse->element[ size - 1 - i ];
514 inverse->element[ size - 1 - i ] = accum;
515 }
516}
#define bigint_bit_is_set(value, bit)
Test if bit is set in big integer.
Definition bigint.h:180
#define bigint_shr(value)
Shift big integer right.
Definition bigint.h:123

References __attribute__, assert, bigint_add, bigint_bit_is_set, bigint_shr, bigint_t, bit, memset(), and size.

◆ bigint_montgomery_relaxed_raw()

int bigint_montgomery_relaxed_raw ( const bigint_element_t * modulus0,
bigint_element_t * value0,
bigint_element_t * result0,
unsigned int size )

Perform relaxed Montgomery reduction (REDC) of a big integer.

Parameters
modulus0Element 0 of big integer odd modulus
value0Element 0 of big integer to be reduced
result0Element 0 of big integer to hold result
sizeNumber of elements in modulus and result
Return values
carryCarry out

The value to be reduced will be made divisible by the size of the modulus while retaining its residue class (i.e. multiples of the modulus will be added until the low half of the value is zero).

The result may be expressed as

tR = x + mN

where x is the input value, N is the modulus, R=2^n (where n is the number of bits in the representation of the modulus, including any leading zero bits), and m is the number of multiples of the modulus added to make the result tR divisible by R.

The maximum addend is mN <= (R-1)*N (and such an m can be proven to exist since N is limited to being odd and therefore coprime to R).

Since the result of this addition is one bit larger than the input value, a carry out bit is also returned. The caller may be able to prove that the carry out is always zero, in which case it may be safely ignored.

The upper half of the output value (i.e. t) will also be copied to the result pointer. It is permissible for the result pointer to overlap the lower half of the input value.

External knowledge of constraints on the modulus and the input value may be used to prove constraints on the result. The constraint on the modulus may be generally expressed as

R > kN

for some positive integer k. The value k=1 is allowed, and simply expresses that the modulus fits within the number of bits in its own representation.

For classic Montgomery reduction, we have k=1, i.e. R > N and a separate constraint that the input value is in the range x < RN. This gives the result constraint

tR < RN + (R-1)N < 2RN - N < 2RN t < 2N

A single subtraction of the modulus may therefore be required to bring it into the range t < N.

When the input value is known to be a product of two integers A and B, with A < aN and B < bN, we get the result constraint

tR < abN^2 + (R-1)N < (ab/k)RN + RN - N < (1 + ab/k)RN t < (1 + ab/k)N

If we have k=a=b=1, i.e. R > N with A < N and B < N, then the result is in the range t < 2N and may require a single subtraction of the modulus to bring it into the range t < N so that it may be used as an input on a subsequent iteration.

If we have k=4 and a=b=2, i.e. R > 4N with A < 2N and B < 2N, then the result is in the range t < 2N and may immediately be used as an input on a subsequent iteration, without requiring a subtraction.

Larger values of k may be used to allow for larger values of a and b, which can be useful to elide intermediate reductions in a calculation chain that involves additions and subtractions between multiplications (as used in elliptic curve point addition, for example). As a general rule: each intermediate addition or subtraction will require k to be doubled.

When the input value is known to be a single integer A, with A < aN (as used when converting out of Montgomery form), we get the result constraint

tR < aN + (R-1)N < RN + (a-1)N

If we have a=1, i.e. A < N, then the constraint becomes

tR < RN t < N

and so the result is immediately in the range t < N with no subtraction of the modulus required.

For any larger value of a, the result value t=N becomes possible. Additional external knowledge may potentially be used to prove that t=N cannot occur. For example: if the caller is performing modular exponentiation with a prime modulus (or, more generally, a modulus that is coprime to the base), then there is no way for a non-zero base value to end up producing an exact multiple of the modulus. If t=N cannot be disproved, then conversion out of Montgomery form may require an additional subtraction of the modulus.

Definition at line 622 of file bigint.c.

625 {
626 const bigint_t ( size ) __attribute__ (( may_alias ))
627 *modulus = ( ( const void * ) modulus0 );
628 union {
629 bigint_t ( size * 2 ) full;
630 struct {
631 bigint_t ( size ) low;
632 bigint_t ( size ) high;
633 } __attribute__ (( packed ));
634 } __attribute__ (( may_alias )) *value = ( ( void * ) value0 );
635 bigint_t ( size ) __attribute__ (( may_alias ))
636 *result = ( ( void * ) result0 );
637 static bigint_t ( 1 ) cached;
638 static bigint_t ( 1 ) negmodinv;
639 bigint_element_t multiple;
641 unsigned int i;
642 unsigned int j;
643 int overflow;
644
645 /* Sanity checks */
646 assert ( bigint_bit_is_set ( modulus, 0 ) );
647
648 /* Calculate inverse (or use cached version) */
649 if ( cached.element[0] != modulus->element[0] ) {
650 bigint_mod_invert ( modulus, &negmodinv );
651 negmodinv.element[0] = -negmodinv.element[0];
652 cached.element[0] = modulus->element[0];
653 }
654
655 /* Perform multiprecision Montgomery reduction */
656 for ( i = 0 ; i < size ; i++ ) {
657
658 /* Determine scalar multiple for this round */
659 multiple = ( value->low.element[i] * negmodinv.element[0] );
660
661 /* Multiply value to make it divisible by 2^(width*i) */
662 carry = 0;
663 for ( j = 0 ; j < size ; j++ ) {
664 bigint_multiply_one ( multiple, modulus->element[j],
665 &value->full.element[ i + j ],
666 &carry );
667 }
668
669 /* Since value is now divisible by 2^(width*i), we
670 * know that the current low element must have been
671 * zeroed.
672 */
673 assert ( value->low.element[i] == 0 );
674
675 /* Store the multiplication carry out in the result,
676 * avoiding the need to immediately propagate the
677 * carry through the remaining elements.
678 */
679 result->element[i] = carry;
680 }
681
682 /* Add the accumulated carries */
683 overflow = bigint_add ( result, &value->high );
684
685 /* Copy to result buffer */
686 bigint_copy ( &value->high, result );
687
688 return overflow;
689}
#define bigint_mod_invert(invertend, inverse)
Compute inverse of odd big integer modulo any power of two.
Definition bigint.h:287
#define bigint_copy(source, dest)
Copy big integer.
Definition bigint.h:236
uint32_t high
High 32 bits of address.
Definition myson.h:1
uint32_t low
Low 16 bits of address.
Definition myson.h:0
if(natsemi->flags &NATSEMI_64BIT) return 1

References __attribute__, assert, bigint_add, bigint_bit_is_set, bigint_copy, bigint_mod_invert, bigint_multiply_one(), bigint_t, carry, high, low, result, size, value, and value0.

◆ bigint_montgomery_raw()

void bigint_montgomery_raw ( const bigint_element_t * modulus0,
bigint_element_t * value0,
bigint_element_t * result0,
unsigned int size )

Perform classic Montgomery reduction (REDC) of a big integer.

Parameters
modulus0Element 0 of big integer odd modulus
value0Element 0 of big integer to be reduced
result0Element 0 of big integer to hold result
sizeNumber of elements in modulus and result

Definition at line 699 of file bigint.c.

702 {
703 const bigint_t ( size ) __attribute__ (( may_alias ))
704 *modulus = ( ( const void * ) modulus0 );
705 union {
706 bigint_t ( size * 2 ) full;
707 struct {
708 bigint_t ( size ) low;
709 bigint_t ( size ) high;
710 } __attribute__ (( packed ));
711 } __attribute__ (( may_alias )) *value = ( ( void * ) value0 );
712 bigint_t ( size ) __attribute__ (( may_alias ))
713 *result = ( ( void * ) result0 );
714 int overflow;
715 int underflow;
716
717 /* Sanity check */
718 assert ( ! bigint_is_geq ( &value->high, modulus ) );
719
720 /* Perform relaxed Montgomery reduction */
721 overflow = bigint_montgomery_relaxed ( modulus, &value->full, result );
722
723 /* Conditionally subtract the modulus once */
724 underflow = bigint_subtract ( modulus, result );
725 bigint_swap ( result, &value->high, ( underflow & ~overflow ) );
726
727 /* Sanity check */
728 assert ( ! bigint_is_geq ( result, modulus ) );
729}
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition bigint.h:301
#define bigint_swap(first, second, swap)
Conditionally swap big integers (in constant time).
Definition bigint.h:248

References __attribute__, assert, bigint_is_geq, bigint_montgomery_relaxed, bigint_subtract, bigint_swap, bigint_t, high, low, result, size, value, and value0.

◆ bigint_ladder_raw()

void bigint_ladder_raw ( bigint_element_t * result0,
bigint_element_t * multiple0,
unsigned int size,
const bigint_element_t * exponent0,
unsigned int exponent_size,
bigint_ladder_op_t * op,
const void * ctx,
void * tmp )

Perform generalised exponentiation via a Montgomery ladder.

Parameters
result0Element 0 of result (initialised to identity element)
multiple0Element 0 of multiple (initialised to generator)
sizeNumber of elements in result and multiple
exponent0Element 0 of exponent
exponent_sizeNumber of elements in exponent
opMontgomery ladder commutative operation
ctxOperation context (if needed)
tmpTemporary working space (if needed)

The Montgomery ladder may be used to perform any operation that is isomorphic to exponentiation, i.e. to compute the result

r = g^e = g * g * g * g * .... * g

for an arbitrary commutative operation "*", generator "g" and exponent "e".

The result "r" is computed in constant time (assuming that the underlying operation is constant time) in k steps, where k is the number of bits in the big integer representation of the exponent.

The result "r" must be initialised to the operation's identity element, and the multiple must be initialised to the generator "g". On exit, the multiple will contain

m = r * g = g^(e+1)

Note that the terminology used here refers to exponentiation defined as repeated multiplication, but that the ladder may equally well be used to perform any isomorphic operation (such as multiplication defined as repeated addition).

Definition at line 766 of file bigint.c.

770 {
771 bigint_t ( size ) __attribute__ (( may_alias ))
772 *result = ( ( void * ) result0 );
773 bigint_t ( size ) __attribute__ (( may_alias ))
774 *multiple = ( ( void * ) multiple0 );
775 const bigint_t ( exponent_size ) __attribute__ (( may_alias ))
776 *exponent = ( ( const void * ) exponent0 );
777 const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
778 unsigned int bit = ( exponent_size * width );
779 int toggle = 0;
780 int previous;
781
782 /* We have two physical storage locations: Rres (the "result"
783 * register) and Rmul (the "multiple" register).
784 *
785 * On entry we have:
786 *
787 * Rres = g^0 = 1 (the identity element)
788 * Rmul = g (the generator)
789 *
790 * For calculation purposes, define two virtual registers R[0]
791 * and R[1], mapped to the underlying physical storage
792 * locations via a boolean toggle state "t":
793 *
794 * R[t] -> Rres
795 * R[~t] -> Rmul
796 *
797 * Define the initial toggle state to be t=0, so that we have:
798 *
799 * R[0] = g^0 = 1 (the identity element)
800 * R[1] = g (the generator)
801 *
802 * The Montgomery ladder then iterates over each bit "b" of
803 * the exponent "e" (from MSB down to LSB), computing:
804 *
805 * R[1] := R[0] * R[1], R[0] := R[0] * R[0] (if b=0)
806 * R[0] := R[1] * R[0], R[1] := R[1] * R[1] (if b=1)
807 *
808 * i.e.
809 *
810 * R[~b] := R[b] * R[~b], R[b] := R[b] * R[b]
811 *
812 * To avoid data-dependent memory access patterns, we
813 * implement this as:
814 *
815 * Rmul := Rres * Rmul
816 * Rres := Rres * Rres
817 *
818 * and update the toggle state "t" (via constant-time
819 * conditional swaps) as needed to ensure that R[b] always
820 * maps to Rres and R[~b] always maps to Rmul.
821 */
822 while ( bit-- ) {
823
824 /* Update toggle state t := b
825 *
826 * If the new toggle state is not equal to the old
827 * toggle state, then we must swap R[0] and R[1] (in
828 * constant time).
829 */
830 previous = toggle;
831 toggle = bigint_bit_is_set ( exponent, bit );
832 bigint_swap ( result, multiple, ( toggle ^ previous ) );
833
834 /* Calculate Rmul = R[~b] := R[b] * R[~b] = Rres * Rmul */
835 op ( result->element, multiple->element, size, ctx, tmp );
836
837 /* Calculate Rres = R[b] := R[b] * R[b] = Rres * Rres */
838 op ( result->element, result->element, size, ctx, tmp );
839 }
840
841 /* Reset toggle state to zero */
842 bigint_swap ( result, multiple, toggle );
843}

References __attribute__, bigint_bit_is_set, bigint_swap, bigint_t, bit, ctx, op, result, size, and tmp.

◆ bigint_mod_exp_ladder()

void bigint_mod_exp_ladder ( const bigint_element_t * multiplier0,
bigint_element_t * result0,
unsigned int size,
const void * ctx,
void * tmp )

Perform modular multiplication as part of a Montgomery ladder.

Parameters
operandElement 0 of first input operand (may overlap result)
resultElement 0 of second input operand and result
sizeNumber of elements in operands and result
ctxOperation context (odd modulus, or NULL)
tmpTemporary working space

Definition at line 854 of file bigint.c.

856 {
857 const bigint_t ( size ) __attribute__ (( may_alias ))
858 *multiplier = ( ( const void * ) multiplier0 );
859 bigint_t ( size ) __attribute__ (( may_alias ))
860 *result = ( ( void * ) result0 );
861 const bigint_t ( size ) __attribute__ (( may_alias ))
862 *modulus = ( ( const void * ) ctx );
863 bigint_t ( size * 2 ) __attribute__ (( may_alias ))
864 *product = ( ( void * ) tmp );
865
866 /* Multiply and reduce */
868 if ( modulus ) {
869 bigint_montgomery ( modulus, product, result );
870 } else {
872 }
873}
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition bigint.h:315
#define bigint_shrink(source, dest)
Shrink big integer.
Definition bigint.h:223
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition bigint.h:261
uint8_t product
Product string.
Definition smbios.h:5

References __attribute__, bigint_montgomery, bigint_multiply, bigint_shrink, bigint_t, ctx, multiplier, product, result, size, and tmp.

Referenced by bigint_mod_exp_raw(), ecdsa_invert(), and weierstrass_done_raw().

◆ bigint_mod_exp_raw()

void bigint_mod_exp_raw ( const bigint_element_t * base0,
const bigint_element_t * modulus0,
const bigint_element_t * exponent0,
bigint_element_t * result0,
unsigned int size,
unsigned int exponent_size,
void * tmp )

Perform modular exponentiation of big integers.

Parameters
base0Element 0 of big integer base
modulus0Element 0 of big integer modulus
exponent0Element 0 of big integer exponent
result0Element 0 of big integer to hold result
sizeNumber of elements in base, modulus, and result
exponent_sizeNumber of elements in exponent
tmpTemporary working space

Definition at line 886 of file bigint.c.

891 {
892 const bigint_t ( size ) __attribute__ (( may_alias )) *base =
893 ( ( const void * ) base0 );
894 const bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
895 ( ( const void * ) modulus0 );
896 const bigint_t ( exponent_size ) __attribute__ (( may_alias ))
897 *exponent = ( ( const void * ) exponent0 );
898 bigint_t ( size ) __attribute__ (( may_alias )) *result =
899 ( ( void * ) result0 );
900 const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
901 struct {
902 struct {
903 bigint_t ( size ) modulus;
904 bigint_t ( size ) stash;
905 };
906 union {
907 bigint_t ( 2 * size ) full;
908 bigint_t ( size ) low;
909 } product;
910 } *temp = tmp;
911 const uint8_t one[1] = { 1 };
912 bigint_element_t submask;
913 unsigned int subsize;
914 unsigned int scale;
915 unsigned int i;
916
917 /* Sanity check */
918 assert ( sizeof ( *temp ) == bigint_mod_exp_tmp_len ( modulus ) );
919
920 /* Handle degenerate case of zero modulus */
921 if ( ! bigint_max_set_bit ( modulus ) ) {
922 memset ( result, 0, sizeof ( *result ) );
923 return;
924 }
925
926 /* Factor modulus as (N * 2^scale) where N is odd */
927 bigint_copy ( modulus, &temp->modulus );
928 for ( scale = 0 ; ( ! bigint_bit_is_set ( &temp->modulus, 0 ) ) ;
929 scale++ ) {
930 bigint_shr ( &temp->modulus );
931 }
932 subsize = ( ( scale + width - 1 ) / width );
933 submask = ( ( 1UL << ( scale % width ) ) - 1 );
934 if ( ! submask )
935 submask = ~submask;
936
937 /* Calculate (R^2 mod N) */
938 bigint_reduce ( &temp->modulus, &temp->stash );
939
940 /* Initialise result = Montgomery(1, R^2 mod N) */
941 bigint_grow ( &temp->stash, &temp->product.full );
942 bigint_montgomery ( &temp->modulus, &temp->product.full, result );
943
944 /* Convert base into Montgomery form */
945 bigint_multiply ( base, &temp->stash, &temp->product.full );
946 bigint_montgomery ( &temp->modulus, &temp->product.full,
947 &temp->stash );
948
949 /* Calculate x1 = base^exponent modulo N */
950 bigint_ladder ( result, &temp->stash, exponent, bigint_mod_exp_ladder,
951 &temp->modulus, &temp->product );
952
953 /* Convert back out of Montgomery form */
954 bigint_grow ( result, &temp->product.full );
955 bigint_montgomery_relaxed ( &temp->modulus, &temp->product.full,
956 result );
957
958 /* Handle even moduli via Garner's algorithm */
959 if ( subsize ) {
960 const bigint_t ( subsize ) __attribute__ (( may_alias ))
961 *subbase = ( ( const void * ) base );
962 bigint_t ( subsize ) __attribute__ (( may_alias ))
963 *submodulus = ( ( void * ) &temp->modulus );
964 bigint_t ( subsize ) __attribute__ (( may_alias ))
965 *substash = ( ( void * ) &temp->stash );
966 bigint_t ( subsize ) __attribute__ (( may_alias ))
967 *subresult = ( ( void * ) result );
968 union {
969 bigint_t ( 2 * subsize ) full;
970 bigint_t ( subsize ) low;
971 } __attribute__ (( may_alias ))
972 *subproduct = ( ( void * ) &temp->product.full );
973
974 /* Calculate x2 = base^exponent modulo 2^k */
975 bigint_init ( substash, one, sizeof ( one ) );
976 bigint_copy ( subbase, submodulus );
977 bigint_ladder ( substash, submodulus, exponent,
978 bigint_mod_exp_ladder, NULL, subproduct );
979
980 /* Reconstruct N */
981 bigint_copy ( modulus, &temp->modulus );
982 for ( i = 0 ; i < scale ; i++ )
983 bigint_shr ( &temp->modulus );
984
985 /* Calculate N^-1 modulo 2^k */
986 bigint_mod_invert ( submodulus, &subproduct->low );
987 bigint_copy ( &subproduct->low, submodulus );
988
989 /* Calculate y = (x2 - x1) * N^-1 modulo 2^k */
990 bigint_subtract ( subresult, substash );
991 bigint_multiply ( substash, submodulus, &subproduct->full );
992 subproduct->low.element[ subsize - 1 ] &= submask;
993 bigint_grow ( &subproduct->low, &temp->stash );
994
995 /* Reconstruct N */
996 bigint_mod_invert ( submodulus, &subproduct->low );
997 bigint_copy ( &subproduct->low, submodulus );
998
999 /* Calculate x = x1 + N * y */
1000 bigint_multiply ( &temp->modulus, &temp->stash,
1001 &temp->product.full );
1002 bigint_add ( &temp->product.low, result );
1003 }
1004}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
void bigint_mod_exp_ladder(const bigint_element_t *multiplier0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp)
Perform modular multiplication as part of a Montgomery ladder.
Definition bigint.c:854
#define bigint_grow(source, dest)
Grow big integer.
Definition bigint.h:210
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition bigint.h:331
#define bigint_mod_exp_tmp_len(modulus)
Calculate temporary working space required for moduluar exponentiation.
Definition bigint.h:362
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition bigint.h:275
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:63

References __attribute__, assert, base, bigint_add, bigint_bit_is_set, bigint_copy, bigint_grow, bigint_init, bigint_ladder, bigint_max_set_bit, bigint_mod_exp_ladder(), bigint_mod_exp_tmp_len, bigint_mod_invert, bigint_montgomery, bigint_montgomery_relaxed, bigint_multiply, bigint_reduce, bigint_shr, bigint_subtract, bigint_t, low, memset(), NULL, product, result, size, and tmp.

Variable Documentation

◆ size

unsigned int size
Initial value:
{
const bigint_t ( size ) __attribute__ (( may_alias )) *value =
( ( const void * ) value0 )

Definition at line 389 of file bigint.h.

◆ bit

◆ index

unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) )

Definition at line 393 of file bigint.h.

◆ subindex

unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) )

Definition at line 394 of file bigint.h.

Referenced by return().

◆ element

value element[index] = ( 1UL << subindex )