2022-12-12 23:40:36 -05:00
|
|
|
#ifndef SECP256K1_INT128_H
|
|
|
|
#define SECP256K1_INT128_H
|
|
|
|
|
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
#if defined(SECP256K1_WIDEMUL_INT128)
|
|
|
|
# if defined(SECP256K1_INT128_NATIVE)
|
|
|
|
# include "int128_native.h"
|
|
|
|
# elif defined(SECP256K1_INT128_STRUCT)
|
|
|
|
# include "int128_struct.h"
|
|
|
|
# else
|
|
|
|
# error "Please select int128 implementation"
|
|
|
|
# endif
|
|
|
|
|
|
|
|
/* Construct an unsigned 128-bit value from a high and a low 64-bit value. */
|
|
|
|
static SECP256K1_INLINE void secp256k1_u128_load(secp256k1_uint128 *r, uint64_t hi, uint64_t lo);
|
|
|
|
|
|
|
|
/* Multiply two unsigned 64-bit values a and b and write the result to r. */
|
|
|
|
static SECP256K1_INLINE void secp256k1_u128_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b);
|
|
|
|
|
|
|
|
/* Multiply two unsigned 64-bit values a and b and add the result to r.
|
|
|
|
* The final result is taken modulo 2^128.
|
|
|
|
*/
|
|
|
|
static SECP256K1_INLINE void secp256k1_u128_accum_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b);
|
|
|
|
|
|
|
|
/* Add an unsigned 64-bit value a to r.
|
|
|
|
* The final result is taken modulo 2^128.
|
|
|
|
*/
|
|
|
|
static SECP256K1_INLINE void secp256k1_u128_accum_u64(secp256k1_uint128 *r, uint64_t a);
|
|
|
|
|
|
|
|
/* Unsigned (logical) right shift.
|
|
|
|
* Non-constant time in n.
|
|
|
|
*/
|
|
|
|
static SECP256K1_INLINE void secp256k1_u128_rshift(secp256k1_uint128 *r, unsigned int n);
|
|
|
|
|
|
|
|
/* Return the low 64-bits of a 128-bit value as an unsigned 64-bit value. */
|
|
|
|
static SECP256K1_INLINE uint64_t secp256k1_u128_to_u64(const secp256k1_uint128 *a);
|
|
|
|
|
|
|
|
/* Return the high 64-bits of a 128-bit value as an unsigned 64-bit value. */
|
|
|
|
static SECP256K1_INLINE uint64_t secp256k1_u128_hi_u64(const secp256k1_uint128 *a);
|
|
|
|
|
|
|
|
/* Write an unsigned 64-bit value to r. */
|
|
|
|
static SECP256K1_INLINE void secp256k1_u128_from_u64(secp256k1_uint128 *r, uint64_t a);
|
|
|
|
|
|
|
|
/* Tests if r is strictly less than to 2^n.
|
|
|
|
* n must be strictly less than 128.
|
|
|
|
*/
|
|
|
|
static SECP256K1_INLINE int secp256k1_u128_check_bits(const secp256k1_uint128 *r, unsigned int n);
|
|
|
|
|
|
|
|
/* Construct an signed 128-bit value from a high and a low 64-bit value. */
|
|
|
|
static SECP256K1_INLINE void secp256k1_i128_load(secp256k1_int128 *r, int64_t hi, uint64_t lo);
|
|
|
|
|
|
|
|
/* Multiply two signed 64-bit values a and b and write the result to r. */
|
|
|
|
static SECP256K1_INLINE void secp256k1_i128_mul(secp256k1_int128 *r, int64_t a, int64_t b);
|
|
|
|
|
|
|
|
/* Multiply two signed 64-bit values a and b and add the result to r.
|
|
|
|
* Overflow or underflow from the addition is undefined behaviour.
|
|
|
|
*/
|
|
|
|
static SECP256K1_INLINE void secp256k1_i128_accum_mul(secp256k1_int128 *r, int64_t a, int64_t b);
|
|
|
|
|
|
|
|
/* Compute a*d - b*c from signed 64-bit values and write the result to r. */
|
|
|
|
static SECP256K1_INLINE void secp256k1_i128_det(secp256k1_int128 *r, int64_t a, int64_t b, int64_t c, int64_t d);
|
|
|
|
|
|
|
|
/* Signed (arithmetic) right shift.
|
|
|
|
* Non-constant time in b.
|
|
|
|
*/
|
|
|
|
static SECP256K1_INLINE void secp256k1_i128_rshift(secp256k1_int128 *r, unsigned int b);
|
|
|
|
|
2023-03-08 17:41:24 -05:00
|
|
|
/* Return the input value modulo 2^64. */
|
|
|
|
static SECP256K1_INLINE uint64_t secp256k1_i128_to_u64(const secp256k1_int128 *a);
|
|
|
|
|
|
|
|
/* Return the value as a signed 64-bit value.
|
|
|
|
* Requires the input to be between INT64_MIN and INT64_MAX.
|
|
|
|
*/
|
2022-12-12 23:40:36 -05:00
|
|
|
static SECP256K1_INLINE int64_t secp256k1_i128_to_i64(const secp256k1_int128 *a);
|
|
|
|
|
|
|
|
/* Write a signed 64-bit value to r. */
|
|
|
|
static SECP256K1_INLINE void secp256k1_i128_from_i64(secp256k1_int128 *r, int64_t a);
|
|
|
|
|
|
|
|
/* Compare two 128-bit values for equality. */
|
|
|
|
static SECP256K1_INLINE int secp256k1_i128_eq_var(const secp256k1_int128 *a, const secp256k1_int128 *b);
|
|
|
|
|
2023-03-08 17:41:24 -05:00
|
|
|
/* Tests if r is equal to sign*2^n (sign must be 1 or -1).
|
2022-12-12 23:40:36 -05:00
|
|
|
* n must be strictly less than 127.
|
|
|
|
*/
|
2023-03-08 17:41:24 -05:00
|
|
|
static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n, int sign);
|
2022-12-12 23:40:36 -05:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|