* cipher/keccak.c (USE_RISCV_B): New. [USE_RISCV_B]: (ANDN64, ROL64, keccak_riscv_b_64_ops): New. (keccak_init) [USE_RISCV_B]: Use 'keccak_riscv_b_64_ops' if HWF_RISCV_IMAFDC and HWF_RISCV_B available. --
Patch adds RISC-V "B" extension acceleration for SHA3. Benchmark on SpacemiT K1 (1600 Mhz): Before: | nanosecs/byte mebibytes/sec cycles/byte SHA3-256 | 22.98 ns/B 41.51 MiB/s 36.76 c/B After (2x faster): | nanosecs/byte mebibytes/sec cycles/byte SHA3-256 | 11.15 ns/B 85.57 MiB/s 17.83 c/B Signed-off-by: Jussi Kivilinna <jussi.kivili...@iki.fi> --- cipher/keccak.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/cipher/keccak.c b/cipher/keccak.c index 44cc9f71..4ada6b4c 100644 --- a/cipher/keccak.c +++ b/cipher/keccak.c @@ -91,6 +91,15 @@ #endif /* USE_S390X_CRYPTO */ +/* GCM_USE_RISCV_B indicates whether to compile GCM with RISC-V "B" extension + * code. */ +#undef USE_RISCV_B +#if defined (__riscv) && (__riscv_xlen == 64) && \ + defined(HAVE_GCC_INLINE_ASM_RISCV) +# define USE_RISCV_B 1 +#endif + + /* x86-64 vector register assembly implementations use SystemV ABI, ABI * conversion needed on Win64 through function attribute. */ #undef ASM_FUNC_ABI @@ -359,7 +368,6 @@ static inline void absorb_lanes64_1(u64 *dst, const byte *in) dst[0] ^= buf_get_le64(in + 8 * 0); } - # define ANDN64(x, y) (~(x) & (y)) # define ROL64(x, n) (((x) << ((unsigned int)n & 63)) | \ ((x) >> ((64 - (unsigned int)(n)) & 63))) @@ -450,6 +458,48 @@ static const keccak_ops_t keccak_bmi2_64_ops = #endif /* USE_64BIT_BMI2 */ +/* Construct 64-bit RISC-V "B" extension implementation. */ +#ifdef USE_RISCV_B + +# define ANDN64(x, y) ({ \ + u64 tmp; \ + asm (".option push;\n\t" \ + ".option arch, +zbb;\n\t" \ + "andn %0, %1, %2;\n\t" \ + ".option pop;\n\t" \ + : "=r" (tmp) \ + : "r" (y), "r" (x)); \ + tmp; }) + +# define ROL64(x, n) ({ \ + u64 tmp; \ + asm (".option push;\n\t" \ + ".option arch, +zbb;\n\t" \ + "rori %0, %1, %2;\n\t" \ + ".option pop;\n\t" \ + : "=r" (tmp) \ + : "r" (x), "I" ((64 - n) & 63)); \ + tmp; }) + +# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_riscv_b +# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_riscv_b +# include "keccak_permute_64.h" + +# undef ANDN64 +# undef ROL64 +# undef KECCAK_F1600_PERMUTE_FUNC_NAME +# undef KECCAK_F1600_ABSORB_FUNC_NAME + +static const keccak_ops_t keccak_riscv_b_64_ops = +{ + .permute = keccak_f1600_state_permute64_riscv_b, + .absorb = keccak_absorb_lanes64_riscv_b, + .extract = keccak_extract64, +}; + +#endif /* USE_RISCV_B */ + + /* 64-bit Intel AVX512 implementation. */ #ifdef USE_64BIT_AVX512 @@ -1002,6 +1052,10 @@ keccak_init (int algo, void *context, unsigned int flags) else if (features & HWF_INTEL_FAST_SHLD) ctx->ops = &keccak_shld_64_ops; #endif +#ifdef USE_RISCV_B + else if ((features & HWF_RISCV_IMAFDC) && (features & HWF_RISCV_B)) + ctx->ops = &keccak_riscv_b_64_ops; +#endif /* Set input block size, in Keccak terms this is called 'rate'. */ -- 2.45.2 _______________________________________________ Gcrypt-devel mailing list Gcrypt-devel@gnupg.org https://lists.gnupg.org/mailman/listinfo/gcrypt-devel