Skip to content

Commit 0b1c7ad

Browse files
committed
add runtime check for BMI2 and ADX
1 parent 33026ed commit 0b1c7ad

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

src/secp256k1.c

+5
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ static int secp256k1_context_is_proper(const secp256k1_context* ctx) {
8383
}
8484

8585
void secp256k1_selftest(void) {
86+
if (!SECP256K1_CHECKMEM_RUNNING()) {
87+
if (!secp256k1_selftest_cpuid()) {
88+
secp256k1_callback_call(&default_error_callback, "required CPU flags are not present.");
89+
}
90+
}
8691
if (!secp256k1_selftest_passes()) {
8792
secp256k1_callback_call(&default_error_callback, "self test failed");
8893
}

src/selftest.h

+25
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,31 @@ static int secp256k1_selftest_sha256(void) {
2525
return secp256k1_memcmp_var(out, output32, 32) == 0;
2626
}
2727

28+
static int secp256k1_selftest_cpuid(void) {
29+
int ret = 1;
30+
31+
#if defined(USE_ASM_X86_64)
32+
// getting the CPU flags from the cpu, more information in the Intel manual,
33+
// Table 3-8 Information Returned by CPUID instruction (3-194, Vol.2A)
34+
const int CPU_FLAG_ENUMERATION = 7;
35+
const int LEAF_NODE_ZERO = 0;
36+
37+
// for the cpu self test, we need BMI2 and ADX support
38+
const int BIT_ADX = 19;
39+
const int BIT_BMI2 = 8;
40+
int flags = 0;
41+
__asm__ __volatile__("cpuid\n"
42+
: "=b"(flags)
43+
: "a"(CPU_FLAG_ENUMERATION), "c"(LEAF_NODE_ZERO)
44+
: "rdx", "rbx", "cc");
45+
46+
int has_adx = (flags >> BIT_ADX) & 1;
47+
int has_bmi2 = (flags >> BIT_BMI2) & 1;
48+
ret = has_adx && has_bmi2;
49+
#endif
50+
return ret;
51+
}
52+
2853
static int secp256k1_selftest_passes(void) {
2954
return secp256k1_selftest_sha256();
3055
}

0 commit comments

Comments
 (0)