Skip to content

Commit 366d82c

Browse files
committed
added runtime check for bmi2 and adx
1 parent 4ad1834 commit 366d82c

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-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

+28
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,34 @@ 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+
*/
35+
const int CPU_FLAG_ENUMERATION = 7;
36+
const int LEAF_NODE_ZERO = 0;
37+
38+
/* for the cpu self test, we need BMI2 and ADX support */
39+
const int BIT_ADX = 19;
40+
const int BIT_BMI2 = 8;
41+
int flags = 0;
42+
int has_adx = 0;
43+
int has_bmi2 = 0;
44+
__asm__ __volatile__("cpuid\n"
45+
: "=b"(flags)
46+
: "a"(CPU_FLAG_ENUMERATION), "c"(LEAF_NODE_ZERO)
47+
: "rdx", "cc");
48+
49+
has_adx = (flags >> BIT_ADX) & 1;
50+
has_bmi2 = (flags >> BIT_BMI2) & 1;
51+
ret = has_adx && has_bmi2;
52+
#endif
53+
return ret;
54+
}
55+
2856
static int secp256k1_selftest_passes(void) {
2957
return secp256k1_selftest_sha256();
3058
}

0 commit comments

Comments
 (0)