3#ifndef C237C0F0_BF55_4453_9221_DE161395FF08
4#define C237C0F0_BF55_4453_9221_DE161395FF08
10#if defined(__x86_64__) || defined(_M_X64)
37#if (defined(__aarch64__) || defined(_M_ARM64)) && !defined(SECP256K1_NO_ASM)
40 void field_mul_arm64(uint64_t out[4],
const uint64_t a[4],
const uint64_t b[4])
noexcept;
41 void field_sqr_arm64(uint64_t out[4],
const uint64_t a[4])
noexcept;
42 void field_add_arm64(uint64_t out[4],
const uint64_t a[4],
const uint64_t b[4])
noexcept;
43 void field_sub_arm64(uint64_t out[4],
const uint64_t a[4],
const uint64_t b[4])
noexcept;
44 void field_neg_arm64(uint64_t out[4],
const uint64_t a[4])
noexcept;
67#ifdef SECP256K1_HAS_RISCV_ASM
105inline void mulx64(uint64_t a, uint64_t b, uint64_t& lo, uint64_t& hi) {
106 #if defined(_MSC_VER)
108 lo = _mulx_u64(a, b, &hi);
109 #elif defined(__GNUC__) || defined(__clang__)
110 #if defined(__BMI2__)
112 lo = _mulx_u64(a, b,
reinterpret_cast<unsigned long long*
>(&hi));
115 #ifdef SECP256K1_NO_INT128
117 uint64_t a_lo = a & 0xFFFFFFFFULL;
118 uint64_t a_hi = a >> 32;
119 uint64_t b_lo = b & 0xFFFFFFFFULL;
120 uint64_t b_hi = b >> 32;
122 uint64_t p0 = a_lo * b_lo;
123 uint64_t p1 = a_lo * b_hi;
124 uint64_t p2 = a_hi * b_lo;
125 uint64_t p3 = a_hi * b_hi;
127 uint64_t carry = ((p0 >> 32) + (p1 & 0xFFFFFFFFULL) + (p2 & 0xFFFFFFFFULL)) >> 32;
129 lo = p0 + (p1 << 32) + (p2 << 32);
130 hi = p3 + (p1 >> 32) + (p2 >> 32) + carry;
132 #if defined(__GNUC__)
133 #pragma GCC diagnostic push
134 #pragma GCC diagnostic ignored "-Wpedantic"
136 __uint128_t result =
static_cast<__uint128_t
>(a) * b;
137 lo =
static_cast<uint64_t
>(result);
138 hi =
static_cast<uint64_t
>(result >> 64);
139 #if defined(__GNUC__)
140 #pragma GCC diagnostic pop
146 #if defined(__GNUC__)
147 #pragma GCC diagnostic push
148 #pragma GCC diagnostic ignored "-Wpedantic"
150 __uint128_t result =
static_cast<__uint128_t
>(a) * b;
151 lo =
static_cast<uint64_t
>(result);
152 hi =
static_cast<uint64_t
>(result >> 64);
153 #if defined(__GNUC__)
154 #pragma GCC diagnostic pop
161#if defined(__x86_64__) || defined(_M_X64)
162inline uint8_t
adcx64(uint64_t a, uint64_t b, uint8_t carry, uint64_t& result) {
163 #if defined(_MSC_VER)
165 return _addcarry_u64(carry, a, b,
reinterpret_cast<unsigned long long*
>(&result));
168 return _addcarry_u64(carry, a, b,
reinterpret_cast<unsigned long long*
>(&result));
173inline uint8_t
adcx64(uint64_t a, uint64_t b, uint8_t carry, uint64_t& result) {
174 #ifdef SECP256K1_NO_INT128
177 uint8_t new_carry = (result < a) ? 1 : 0;
179 uint64_t temp = result + 1;
180 new_carry |= (temp < result) ? 1 : 0;
185 #if defined(__GNUC__)
186 #pragma GCC diagnostic push
187 #pragma GCC diagnostic ignored "-Wpedantic"
189 unsigned __int128 sum =
static_cast<unsigned __int128
>(a) +
190 static_cast<unsigned __int128
>(b) +
191 static_cast<unsigned __int128
>(carry);
192 result =
static_cast<uint64_t
>(sum);
193 return static_cast<uint8_t
>(sum >> 64);
194 #if defined(__GNUC__)
195 #pragma GCC diagnostic pop
202inline uint8_t
adox64(uint64_t a, uint64_t b, uint8_t overflow, uint64_t& result) {
205 return adcx64(a, b, overflow, result);
void square_4_karatsuba(const uint64_t a[4], uint64_t result[8])
void mul_4x4_bmi2(const uint64_t a[4], const uint64_t b[4], uint64_t result[8])
void montgomery_reduce_bmi2(uint64_t result[8])
uint8_t adcx64(uint64_t a, uint64_t b, uint8_t carry, uint64_t &result)
uint8_t adox64(uint64_t a, uint64_t b, uint8_t overflow, uint64_t &result)
void mulx64(uint64_t a, uint64_t b, uint64_t &lo, uint64_t &hi)
void square_4_bmi2(const uint64_t a[4], uint64_t result[8])
FieldElement field_negate_bmi2(const FieldElement &a)
FieldElement field_square_bmi2(const FieldElement &a)
FieldElement field_add_bmi2(const FieldElement &a, const FieldElement &b)
FieldElement field_square_karatsuba(const FieldElement &a)
FieldElement field_mul_bmi2(const FieldElement &a, const FieldElement &b)