diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-01-21 16:07:52 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-01-21 16:07:52 +0100 |
commit | 55df79c6c08e31f24370f3ddc69e37729b4c5676 (patch) | |
tree | a1efdab7f7202a86cbda4ece13d9a38e7a722c79 /src/crypto/zinc/curve25519/curve25519-x86_64-glue.c | |
parent | a3f8970c8181f44091f987679527e41fa6531d68 (diff) |
curve25519: x86_64: replace with formally verified implementation
This comes from INRIA's HACL*/Vale. It implements the same algorithm and
implementation strategy as the code it replaces, only this code has been
formally verified, sans the base point multiplication, which uses code
similar to prior, only it uses the formally verified field arithmetic
alongside reproducable ladder generation steps. This doesn't have a
pure-bmi2 version, which means haswell no longer benefits, but the
increased (doubled) code complexity is not worth it for a single
generation of chips that's already old.
Performance-wise, this is around 1% slower on older microarchitectures,
and slightly faster on newer microarchitectures, mainly 10nm ones or
backports of 10nm to 14nm. This implementation is "everest" below:
Xeon E5-2680 v4 (Broadwell)
armfazh: 133340 cycles per call
everest: 133436 cycles per call
Xeon Gold 5120 (Sky Lake Server)
armfazh: 112636 cycles per call
everest: 113906 cycles per call
Core i5-6300U (Sky Lake Client)
armfazh: 116810 cycles per call
everest: 117916 cycles per call
Core i7-7600U (Kaby Lake)
armfazh: 119523 cycles per call
everest: 119040 cycles per call
Core i7-8750H (Coffee Lake)
armfazh: 113914 cycles per call
everest: 113650 cycles per call
Core i9-9880H (Coffee Lake Refresh)
armfazh: 112616 cycles per call
everest: 114082 cycles per call
Core i3-8121U (Cannon Lake)
armfazh: 113202 cycles per call
everest: 111382 cycles per call
Core i7-8265U (Whiskey Lake)
armfazh: 127307 cycles per call
everest: 127697 cycles per call
Core i7-8550U (Kaby Lake Refresh)
armfazh: 127522 cycles per call
everest: 127083 cycles per call
Xeon Platinum 8275CL (Cascade Lake)
armfazh: 114380 cycles per call
everest: 114656 cycles per call
Achieving these kind of results with formally verified code is quite
remarkable, especialy considering that performance is favorable for
newer chips.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/crypto/zinc/curve25519/curve25519-x86_64-glue.c')
-rw-r--r-- | src/crypto/zinc/curve25519/curve25519-x86_64-glue.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/src/crypto/zinc/curve25519/curve25519-x86_64-glue.c b/src/crypto/zinc/curve25519/curve25519-x86_64-glue.c index d62bd37..e08cc2b 100644 --- a/src/crypto/zinc/curve25519/curve25519-x86_64-glue.c +++ b/src/crypto/zinc/curve25519/curve25519-x86_64-glue.c @@ -8,29 +8,25 @@ #include "curve25519-x86_64.c" -static bool curve25519_use_bmi2 __ro_after_init; -static bool curve25519_use_adx __ro_after_init; +static bool curve25519_use_bmi2_adx __ro_after_init; static bool *const curve25519_nobs[] __initconst = { - &curve25519_use_bmi2, &curve25519_use_adx }; + &curve25519_use_bmi2_adx }; static void __init curve25519_fpu_init(void) { - curve25519_use_bmi2 = IS_ENABLED(CONFIG_AS_BMI2) && - boot_cpu_has(X86_FEATURE_BMI2); - curve25519_use_adx = IS_ENABLED(CONFIG_AS_ADX) && - boot_cpu_has(X86_FEATURE_BMI2) && - boot_cpu_has(X86_FEATURE_ADX); + curve25519_use_bmi2_adx = IS_ENABLED(CONFIG_AS_BMI2) && + IS_ENABLED(CONFIG_AS_ADX) && + boot_cpu_has(X86_FEATURE_BMI2) && + boot_cpu_has(X86_FEATURE_ADX); } static inline bool curve25519_arch(u8 mypublic[CURVE25519_KEY_SIZE], const u8 secret[CURVE25519_KEY_SIZE], const u8 basepoint[CURVE25519_KEY_SIZE]) { - if (IS_ENABLED(CONFIG_AS_ADX) && curve25519_use_adx) { - curve25519_adx(mypublic, secret, basepoint); - return true; - } else if (IS_ENABLED(CONFIG_AS_BMI2) && curve25519_use_bmi2) { - curve25519_bmi2(mypublic, secret, basepoint); + if (IS_ENABLED(CONFIG_AS_ADX) && IS_ENABLED(CONFIG_AS_BMI2) && + curve25519_use_bmi2_adx) { + curve25519_ever64(mypublic, secret, basepoint); return true; } return false; @@ -39,11 +35,9 @@ static inline bool curve25519_arch(u8 mypublic[CURVE25519_KEY_SIZE], static inline bool curve25519_base_arch(u8 pub[CURVE25519_KEY_SIZE], const u8 secret[CURVE25519_KEY_SIZE]) { - if (IS_ENABLED(CONFIG_AS_ADX) && curve25519_use_adx) { - curve25519_adx_base(pub, secret); - return true; - } else if (IS_ENABLED(CONFIG_AS_BMI2) && curve25519_use_bmi2) { - curve25519_bmi2_base(pub, secret); + if (IS_ENABLED(CONFIG_AS_ADX) && IS_ENABLED(CONFIG_AS_BMI2) && + curve25519_use_bmi2_adx) { + curve25519_ever64_base(pub, secret); return true; } return false; |