[PATCH 6/6] Add SHA3 acceleration for RISC-V "B" extension
Jussi Kivilinna
jussi.kivilinna at iki.fi
Mon Jan 6 16:08:53 CET 2025
* 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.kivilinna at 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
More information about the Gcrypt-devel
mailing list