#include <stdint.h>
#include <string.h>
-#include <strings.h>
/** Element of a big integer */
typedef uint32_t bigint_element_t;
-/**
- * Initialise big integer
- *
- * @v value0 Element 0 of big integer to initialise
- * @v size Number of elements
- * @v data Raw data
- * @v len Length of raw data
- */
-static inline __attribute__ (( always_inline )) void
-bigint_init_raw ( uint32_t *value0, unsigned int size,
- const void *data, size_t len ) {
- size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
- uint8_t *value_byte = ( ( void * ) value0 );
- const uint8_t *data_byte = ( data + len );
-
- /* Copy raw data in reverse order, padding with zeros */
- while ( len-- )
- *(value_byte++) = *(--data_byte);
- while ( pad_len-- )
- *(value_byte++) = 0;
-}
-
/**
* Add big integers
*
return carry;
}
-/**
- * Test if big integer is equal to zero
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret is_zero Big integer is equal to zero
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
- const uint32_t *value = value0;
- uint32_t value_i;
-
- do {
- value_i = *(value++);
- if ( value_i )
- break;
- } while ( --size );
-
- return ( value_i == 0 );
-}
-
-/**
- * Compare big integers
- *
- * @v value0 Element 0 of big integer
- * @v reference0 Element 0 of reference big integer
- * @v size Number of elements
- * @ret geq Big integer is greater than or equal to the reference
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0,
- unsigned int size ) {
- const uint32_t *value = ( value0 + size );
- const uint32_t *reference = ( reference0 + size );
- uint32_t value_i;
- uint32_t reference_i;
-
- do {
- value_i = *(--value);
- reference_i = *(--reference);
- if ( value_i != reference_i )
- break;
- } while ( --size );
-
- return ( value_i >= reference_i );
-}
-
-/**
- * Find highest bit set in big integer
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret max_bit Highest bit set + 1 (or 0 if no bits set)
- */
-static inline __attribute__ (( always_inline )) int
-bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
- const uint32_t *value = ( value0 + size );
- int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
- uint32_t value_i;
-
- do {
- value_i = *(--value);
- max_bit -= ( 32 - fls ( value_i ) );
- if ( value_i )
- break;
- } while ( --size );
-
- return max_bit;
-}
-
/**
* Grow big integer
*
memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
}
-/**
- * Finalise big integer
- *
- * @v value0 Element 0 of big integer to finalise
- * @v size Number of elements
- * @v out Output buffer
- * @v len Length of output buffer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
- void *out, size_t len ) {
- const uint8_t *value_byte = ( ( const void * ) value0 );
- uint8_t *out_byte = ( out + len );
-
- /* Copy raw data in reverse order */
- while ( len-- )
- *(--out_byte) = *(value_byte++);
-}
-
/**
* Multiply big integer elements
*
#include <stdint.h>
#include <string.h>
-#include <strings.h>
/** Element of a big integer */
typedef uint64_t bigint_element_t;
-/**
- * Initialise big integer
- *
- * @v value0 Element 0 of big integer to initialise
- * @v size Number of elements
- * @v data Raw data
- * @v len Length of raw data
- */
-static inline __attribute__ (( always_inline )) void
-bigint_init_raw ( uint64_t *value0, unsigned int size,
- const void *data, size_t len ) {
- size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
- uint8_t *value_byte = ( ( void * ) value0 );
- const uint8_t *data_byte = ( data + len );
-
- /* Copy raw data in reverse order, padding with zeros */
- while ( len-- )
- *(value_byte++) = *(--data_byte);
- while ( pad_len-- )
- *(value_byte++) = 0;
-}
-
/**
* Add big integers
*
return ( low & 1 );
}
-/**
- * Test if big integer is equal to zero
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret is_zero Big integer is equal to zero
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_zero_raw ( const uint64_t *value0, unsigned int size ) {
- const uint64_t *value = value0;
- uint64_t value_i;
-
- do {
- value_i = *(value++);
- if ( value_i )
- break;
- } while ( --size );
-
- return ( value_i == 0 );
-}
-
-/**
- * Compare big integers
- *
- * @v value0 Element 0 of big integer
- * @v reference0 Element 0 of reference big integer
- * @v size Number of elements
- * @ret geq Big integer is greater than or equal to the reference
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_geq_raw ( const uint64_t *value0, const uint64_t *reference0,
- unsigned int size ) {
- const uint64_t *value = ( value0 + size );
- const uint64_t *reference = ( reference0 + size );
- uint64_t value_i;
- uint64_t reference_i;
-
- do {
- value_i = *(--value);
- reference_i = *(--reference);
- if ( value_i != reference_i )
- break;
- } while ( --size );
-
- return ( value_i >= reference_i );
-}
-
-/**
- * Find highest bit set in big integer
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret max_bit Highest bit set + 1 (or 0 if no bits set)
- */
-static inline __attribute__ (( always_inline )) int
-bigint_max_set_bit_raw ( const uint64_t *value0, unsigned int size ) {
- const uint64_t *value = ( value0 + size );
- int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
- uint64_t value_i;
-
- do {
- value_i = *(--value);
- max_bit -= ( 64 - fls ( value_i ) );
- if ( value_i )
- break;
- } while ( --size );
-
- return max_bit;
-}
-
/**
* Grow big integer
*
memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
}
-/**
- * Finalise big integer
- *
- * @v value0 Element 0 of big integer to finalise
- * @v size Number of elements
- * @v out Output buffer
- * @v len Length of output buffer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_done_raw ( const uint64_t *value0, unsigned int size __unused,
- void *out, size_t len ) {
- const uint8_t *value_byte = ( ( const void * ) value0 );
- uint8_t *out_byte = ( out + len );
-
- /* Copy raw data in reverse order */
- while ( len-- )
- *(--out_byte) = *(value_byte++);
-}
-
/**
* Multiply big integer elements
*
#include <stdint.h>
#include <string.h>
-#include <strings.h>
/** Element of a big integer */
typedef uint64_t bigint_element_t;
-/**
- * Initialise big integer
- *
- * @v value0 Element 0 of big integer to initialise
- * @v size Number of elements
- * @v data Raw data
- * @v len Length of raw data
- */
-static inline __attribute__ (( always_inline )) void
-bigint_init_raw ( uint64_t *value0, unsigned int size,
- const void *data, size_t len ) {
- size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
- uint8_t *value_byte = ( ( void * ) value0 );
- const uint8_t *data_byte = ( data + len );
-
- /* Copy raw data in reverse order, padding with zeros */
- while ( len-- )
- *(value_byte++) = *(--data_byte);
- while ( pad_len-- )
- *(value_byte++) = 0;
-}
-
/**
* Add big integers
*
return ( carry & 1 );
}
-/**
- * Test if big integer is equal to zero
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret is_zero Big integer is equal to zero
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_zero_raw ( const uint64_t *value0, unsigned int size ) {
- const uint64_t *value = value0;
- uint64_t value_i;
-
- do {
- value_i = *(value++);
- if ( value_i )
- break;
- } while ( --size );
-
- return ( value_i == 0 );
-}
-
-/**
- * Compare big integers
- *
- * @v value0 Element 0 of big integer
- * @v reference0 Element 0 of reference big integer
- * @v size Number of elements
- * @ret geq Big integer is greater than or equal to the reference
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_geq_raw ( const uint64_t *value0, const uint64_t *reference0,
- unsigned int size ) {
- const uint64_t *value = ( value0 + size );
- const uint64_t *reference = ( reference0 + size );
- uint64_t value_i;
- uint64_t reference_i;
-
- do {
- value_i = *(--value);
- reference_i = *(--reference);
- if ( value_i != reference_i )
- break;
- } while ( --size );
-
- return ( value_i >= reference_i );
-}
-
-/**
- * Find highest bit set in big integer
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret max_bit Highest bit set + 1 (or 0 if no bits set)
- */
-static inline __attribute__ (( always_inline )) int
-bigint_max_set_bit_raw ( const uint64_t *value0, unsigned int size ) {
- const uint64_t *value = ( value0 + size );
- int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
- uint64_t value_i;
-
- do {
- value_i = *(--value);
- max_bit -= ( 64 - fls ( value_i ) );
- if ( value_i )
- break;
- } while ( --size );
-
- return max_bit;
-}
-
/**
* Grow big integer
*
memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
}
-/**
- * Finalise big integer
- *
- * @v value0 Element 0 of big integer to finalise
- * @v size Number of elements
- * @v out Output buffer
- * @v len Length of output buffer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_done_raw ( const uint64_t *value0, unsigned int size __unused,
- void *out, size_t len ) {
- const uint8_t *value_byte = ( ( const void * ) value0 );
- uint8_t *out_byte = ( out + len );
-
- /* Copy raw data in reverse order */
- while ( len-- )
- *(--out_byte) = *(value_byte++);
-}
-
/**
* Multiply big integer elements
*
#include <stdint.h>
#include <string.h>
-#include <strings.h>
/** Element of a big integer */
typedef unsigned long bigint_element_t;
-/**
- * Initialise big integer
- *
- * @v value0 Element 0 of big integer to initialise
- * @v size Number of elements
- * @v data Raw data
- * @v len Length of raw data
- */
-static inline __attribute__ (( always_inline )) void
-bigint_init_raw ( unsigned long *value0, unsigned int size,
- const void *data, size_t len ) {
- size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
- uint8_t *value_byte = ( ( void * ) value0 );
- const uint8_t *data_byte = ( data + len );
-
- /* Copy raw data in reverse order, padding with zeros */
- while ( len-- )
- *(value_byte++) = *(--data_byte);
- while ( pad_len-- )
- *(value_byte++) = 0;
-}
-
/**
* Add big integers
*
return ( !! carry );
}
-/**
- * Test if big integer is equal to zero
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret is_zero Big integer is equal to zero
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_zero_raw ( const unsigned long *value0, unsigned int size ) {
- const unsigned long *value = value0;
- unsigned long value_i;
-
- do {
- value_i = *(value++);
- if ( value_i )
- break;
- } while ( --size );
-
- return ( value_i == 0 );
-}
-
-/**
- * Compare big integers
- *
- * @v value0 Element 0 of big integer
- * @v reference0 Element 0 of reference big integer
- * @v size Number of elements
- * @ret geq Big integer is greater than or equal to the reference
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_geq_raw ( const unsigned long *value0,
- const unsigned long *reference0, unsigned int size ) {
- const unsigned long *value = ( value0 + size );
- const unsigned long *reference = ( reference0 + size );
- unsigned long value_i;
- unsigned long reference_i;
-
- do {
- value_i = *(--value);
- reference_i = *(--reference);
- if ( value_i != reference_i )
- break;
- } while ( --size );
-
- return ( value_i >= reference_i );
-}
-
-/**
- * Find highest bit set in big integer
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret max_bit Highest bit set + 1 (or 0 if no bits set)
- */
-static inline __attribute__ (( always_inline )) int
-bigint_max_set_bit_raw ( const unsigned long *value0, unsigned int size ) {
- const unsigned long *value = ( value0 + size );
- int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
- unsigned long value_i;
-
- do {
- value_i = *(--value);
- max_bit -= ( ( 8 * sizeof ( *value0 ) ) - fls ( value_i ) );
- if ( value_i )
- break;
- } while ( --size );
-
- return max_bit;
-}
-
/**
* Grow big integer
*
memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
}
-/**
- * Finalise big integer
- *
- * @v value0 Element 0 of big integer to finalise
- * @v size Number of elements
- * @v out Output buffer
- * @v len Length of output buffer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_done_raw ( const unsigned long *value0, unsigned int size __unused,
- void *out, size_t len ) {
- const uint8_t *value_byte = ( ( const void * ) value0 );
- uint8_t *out_byte = ( out + len );
-
- /* Copy raw data in reverse order */
- while ( len-- )
- *(--out_byte) = *(value_byte++);
-}
-
/**
* Multiply big integer elements
*
FILE_SECBOOT ( PERMITTED );
#include <stdint.h>
-#include <string.h>
/** Element of a big integer */
typedef uint32_t bigint_element_t;
-/**
- * Initialise big integer
- *
- * @v value0 Element 0 of big integer to initialise
- * @v size Number of elements
- * @v data Raw data
- * @v len Length of raw data
- */
-static inline __attribute__ (( always_inline )) void
-bigint_init_raw ( uint32_t *value0, unsigned int size,
- const void *data, size_t len ) {
- bigint_t ( size ) __attribute__ (( may_alias )) *value =
- ( ( void * ) value0 );
- long pad_len = ( sizeof ( *value ) - len );
- void *discard_D;
- long discard_c;
-
- /* Copy raw data in reverse order, padding with zeros */
- __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" );
-}
-
/**
* Add big integers
*
return out;
}
-/**
- * Test if big integer is equal to zero
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret is_zero Big integer is equal to zero
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
- void *discard_D;
- long discard_c;
- int result;
-
- __asm__ __volatile__ ( "xor %0, %0\n\t" /* Set ZF */
- "repe scasl\n\t"
- "sete %b0\n\t"
- : "=&a" ( result ), "=&D" ( discard_D ),
- "=&c" ( discard_c )
- : "1" ( value0 ), "2" ( size ) );
- return result;
-}
-
-/**
- * Compare big integers
- *
- * @v value0 Element 0 of big integer
- * @v reference0 Element 0 of reference big integer
- * @v size Number of elements
- * @ret geq Big integer is greater than or equal to the reference
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0,
- unsigned int size ) {
- long discard_c;
- long discard_tmp;
- int result;
-
- __asm__ __volatile__ ( "\n1:\n\t"
- "movl -4(%3, %1, 4), %k2\n\t"
- "cmpl -4(%4, %1, 4), %k2\n\t"
- "loope 1b\n\t"
- "setae %b0\n\t"
- : "=q" ( result ), "=&c" ( discard_c ),
- "=&r" ( discard_tmp )
- : "r" ( value0 ), "r" ( reference0 ),
- "0" ( 0 ), "1" ( size ) );
- return result;
-}
-
-/**
- * Find highest bit set in big integer
- *
- * @v value0 Element 0 of big integer
- * @v size Number of elements
- * @ret max_bit Highest bit set + 1 (or 0 if no bits set)
- */
-static inline __attribute__ (( always_inline )) int
-bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
- long discard_c;
- int result;
-
- __asm__ __volatile__ ( "\n1:\n\t"
- "bsrl -4(%2,%1,4), %0\n\t"
- "loopz 1b\n\t"
- "rol %1\n\t" /* Does not affect ZF */
- "rol %1\n\t"
- "leal 1(%k0,%k1,8), %k0\n\t"
- "jnz 2f\n\t"
- "xor %0, %0\n\t"
- "\n2:\n\t"
- : "=&r" ( result ), "=&c" ( discard_c )
- : "r" ( value0 ), "1" ( size ) );
- return result;
-}
-
/**
* Grow big integer
*
: "eax" );
}
-/**
- * Finalise big integer
- *
- * @v value0 Element 0 of big integer to finalise
- * @v size Number of elements
- * @v out Output buffer
- * @v len Length of output buffer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
- void *out, size_t len ) {
- struct {
- uint8_t bytes[len];
- } __attribute__ (( may_alias )) *out_bytes = out;
- void *discard_D;
- long discard_c;
-
- /* Copy raw data in reverse order */
- __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"
- : "=&D" ( discard_D ), "=&c" ( discard_c ),
- "+m" ( *out_bytes )
- : "r" ( value0 ), "0" ( out ), "1" ( len )
- : "eax" );
-}
-
/**
* Multiply big integer elements
*
#include <stdint.h>
#include <string.h>
+#include <strings.h>
#include <assert.h>
+#include <byteswap.h>
#include <stdio.h>
#include <ipxe/bigint.h>
return buf;
}
+/**
+ * Initialise big integer
+ *
+ * @v value0 Element 0 of big integer to initialise
+ * @v size Number of elements
+ * @v data Raw data
+ * @v len Length of raw data
+ */
+void bigint_init_raw ( bigint_element_t *value0, unsigned int size,
+ const void *data, size_t len ) {
+ bigint_t ( size ) __attribute__ (( may_alias ))
+ *value = ( ( void * ) value0 );
+ uint8_t *value_byte = ( ( void * ) value0 );
+ const uint8_t *data_byte = data;
+ unsigned int toggle;
+ unsigned int i;
+
+ /* Zero big integer */
+ memset ( value, 0, sizeof ( *value ) );
+
+ /* Copy data, byte-swapping as needed */
+ toggle = ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ? 0 :
+ ( sizeof ( value->element[0] ) - 1 ) );
+ for ( i = 0 ; len-- ; i++ )
+ value_byte[ i ^ toggle ] = data_byte[len];
+}
+
+/**
+ * Finalise big integer
+ *
+ * @v value0 Element 0 of big integer to finalise
+ * @v size Number of elements
+ * @v out Output buffer
+ * @v len Length of output buffer
+ */
+void bigint_done_raw ( const bigint_element_t *value0, unsigned int size,
+ void *out, size_t len ) {
+ const bigint_t ( size ) __attribute__ (( may_alias ))
+ *value = ( ( const void * ) value0 );
+ const uint8_t *value_byte = ( ( const void * ) value0 );
+ uint8_t *out_byte = out;
+ unsigned int toggle;
+ unsigned int i;
+
+ /* Zero output buffer */
+ memset ( out, 0, len );
+
+ /* Copy data, byte-swapping as needed */
+ toggle = ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ? 0 :
+ ( sizeof ( value->element[0] ) - 1 ) );
+ for ( i = 0 ; len-- ; i++ )
+ out_byte[len] = value_byte[ i ^ toggle ];
+}
+
+/**
+ * Test if big integer is equal to zero
+ *
+ * @v value0 Element 0 of big integer
+ * @v size Number of elements
+ * @ret is_zero Big integer is equal to zero
+ */
+int bigint_is_zero_raw ( const bigint_element_t *value0, unsigned int size ) {
+ const bigint_t ( size ) __attribute__ (( may_alias )) *value =
+ ( ( const void * ) value0 );
+ bigint_element_t or;
+ unsigned int i;
+
+ /* Construct binary OR of all elements */
+ for ( i = 0, or = 0 ; i < size ; i++ )
+ or |= value->element[i];
+
+ return ( or == 0 );
+}
+
+/**
+ * Compare big integers
+ *
+ * @v value0 Element 0 of big integer
+ * @v reference0 Element 0 of reference big integer
+ * @v size Number of elements
+ * @ret geq Big integer is greater than or equal to the reference
+ */
+int bigint_is_geq_raw ( const bigint_element_t *value0,
+ const bigint_element_t *reference0,
+ unsigned int size ) {
+ const bigint_t ( size ) __attribute__ (( may_alias )) *value =
+ ( ( const void * ) value0 );
+ const bigint_t ( size ) __attribute__ (( may_alias )) *reference =
+ ( ( const void * ) reference0 );
+ bigint_element_t value_element;
+ bigint_element_t reference_element;
+
+ /* Find highest differing element */
+ do {
+ value_element = value->element[ size - 1 ];
+ reference_element = reference->element[ size - 1 ];
+ if ( value_element != reference_element )
+ break;
+ } while ( --size );
+
+ return ( value_element >= reference_element );
+}
+
+/**
+ * Find highest bit set in big integer
+ *
+ * @v value0 Element 0 of big integer
+ * @v size Number of elements
+ * @ret max_bit Highest bit set + 1 (or 0 if no bits set)
+ */
+int bigint_max_set_bit_raw ( const bigint_element_t *value0,
+ unsigned int size ) {
+ const bigint_t ( size ) __attribute__ (( may_alias )) *value =
+ ( ( const void * ) value0 );
+ bigint_element_t element;
+ unsigned int max_bit;
+ unsigned int i;
+
+ /* Find highest set bit in highest non-zero element */
+ max_bit = ( sizeof ( *value ) * 8 );
+ for ( i = 0 ; i < size ; i++ ) {
+ element = value->element[ size - i - 1 ];
+ max_bit -= ( sizeof ( element) * 8 );
+ if ( element ) {
+ max_bit += flsll ( element );
+ break;
+ }
+ }
+
+ return max_bit;
+}
+
/**
* Conditionally swap big integers (in constant time)
*
*/
#include <stdint.h>
+#include <string.h>
#include <errno.h>
#include <ipxe/ffdhe.h>
* implementation of the big integer operations.
*/
+#include <string.h>
#include <errno.h>
#include <ipxe/weierstrass.h>