28#ifndef SECP256K1_DEBUG_INVARIANTS_HPP
29#define SECP256K1_DEBUG_INVARIANTS_HPP
37#if defined(NDEBUG) && !defined(SECP256K1_FORCE_INVARIANTS)
39#define SECP_ASSERT(expr) ((void)0)
40#define SECP_ASSERT_MSG(expr, msg) ((void)0)
41#define SECP_ASSERT_NORMALIZED(fe) ((void)0)
42#define SECP_ASSERT_ON_CURVE(pt) ((void)0)
43#define SECP_ASSERT_SCALAR_VALID(s) ((void)0)
44#define SECP_ASSERT_SCALAR_NONZERO(s) ((void)0)
45#define SECP_ASSERT_NOT_INFINITY(pt) ((void)0)
46#define SECP_ASSERT_FE_LESS_THAN_P(fe) ((void)0)
47#define SECP_DEBUG_COUNTER_INC(name) ((void)0)
48#define SECP_DEBUG_COUNTER_REPORT() ((void)0)
66 static constexpr uint64_t P[4] = {
67 0xFFFFFFFEFFFFFC2Full,
68 0xFFFFFFFFFFFFFFFFull,
69 0xFFFFFFFFFFFFFFFFull,
73 const auto& l = fe.limbs();
75 for (
int i = 3; i >= 0; --i) {
76 if (l[i] < P[i])
return true;
77 if (l[i] > P[i])
return false;
85 if (pt.is_infinity())
return true;
87#if defined(SECP256K1_FAST_52BIT)
154 (void)std::fprintf(stderr,
160 " scalar_mul: %llu\n"
161 " invariants: %llu\n",
180#define SECP_ASSERT(expr) do { \
182 (void)std::fprintf(stderr, \
183 "SECP_ASSERT FAILED: %s\n at %s:%d (%s)\n", \
184 #expr, __FILE__, __LINE__, __func__); \
189#define SECP_ASSERT_MSG(expr, msg) do { \
191 (void)std::fprintf(stderr, \
192 "SECP_ASSERT FAILED: %s\n %s\n at %s:%d (%s)\n", \
193 #expr, msg, __FILE__, __LINE__, __func__); \
198#define SECP_ASSERT_NORMALIZED(fe) do { \
199 ++secp256k1::fast::debug::counters().invariant_check_count; \
200 if (!secp256k1::fast::debug::is_normalized_field_element(fe)) { \
201 (void)std::fprintf(stderr, \
202 "SECP_ASSERT_NORMALIZED FAILED: field element not canonical\n" \
203 " at %s:%d (%s)\n", __FILE__, __LINE__, __func__); \
204 const auto& _l = (fe).limbs(); \
205 (void)std::fprintf(stderr, " limbs: [%016llx, %016llx, %016llx, %016llx]\n", \
206 (unsigned long long)_l[0], (unsigned long long)_l[1], \
207 (unsigned long long)_l[2], (unsigned long long)_l[3]); \
212#define SECP_ASSERT_ON_CURVE(pt) do { \
213 ++secp256k1::fast::debug::counters().invariant_check_count; \
214 if (!secp256k1::fast::debug::is_on_curve(pt)) { \
215 (void)std::fprintf(stderr, \
216 "SECP_ASSERT_ON_CURVE FAILED: point not on secp256k1\n" \
217 " at %s:%d (%s)\n", __FILE__, __LINE__, __func__); \
222#define SECP_ASSERT_SCALAR_VALID(s) do { \
223 ++secp256k1::fast::debug::counters().invariant_check_count; \
224 if (!secp256k1::fast::debug::is_valid_scalar(s)) { \
225 (void)std::fprintf(stderr, \
226 "SECP_ASSERT_SCALAR_VALID FAILED: scalar is zero\n" \
227 " at %s:%d (%s)\n", __FILE__, __LINE__, __func__); \
232#define SECP_ASSERT_SCALAR_NONZERO(s) SECP_ASSERT_SCALAR_VALID(s)
234#define SECP_ASSERT_NOT_INFINITY(pt) do { \
235 if ((pt).is_infinity()) { \
236 (void)std::fprintf(stderr, \
237 "SECP_ASSERT_NOT_INFINITY FAILED\n" \
238 " at %s:%d (%s)\n", __FILE__, __LINE__, __func__); \
243#define SECP_ASSERT_FE_LESS_THAN_P(fe) SECP_ASSERT_NORMALIZED(fe)
245#define SECP_DEBUG_COUNTER_INC(name) \
246 (++secp256k1::fast::debug::counters().name ## _count)
248#define SECP_DEBUG_COUNTER_REPORT() \
249 secp256k1::fast::debug::counters().report()
FieldElement square() const
static FieldElement zero()
static FieldElement from_uint64(std::uint64_t value)
bool is_normalized_field_element(const FieldElement &fe) noexcept
bool is_valid_scalar(const Scalar &s) noexcept
DebugCounters & counters() noexcept
bool is_on_curve(const Point &pt) noexcept
bool is_zero() const noexcept
FieldElement52 square() const noexcept
void report() const noexcept
uint64_t invariant_check_count
uint64_t scalar_mul_count