diff mbox series

[13/18] crypto: Add generic 64-bit carry-less multiply routine

Message ID 20230713211435.13505-14-richard.henderson@linaro.org
State New
Headers show
Series crypto: Provide clmul.h and host accel | expand

Commit Message

Richard Henderson July 13, 2023, 9:14 p.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 host/include/generic/host/crypto/clmul.h |  2 ++
 include/crypto/clmul.h                   |  7 +++++++
 crypto/clmul.c                           | 17 +++++++++++++++++
 3 files changed, 26 insertions(+)
diff mbox series

Patch

diff --git a/host/include/generic/host/crypto/clmul.h b/host/include/generic/host/crypto/clmul.h
index 3fbb1576cf..7f70afeb57 100644
--- a/host/include/generic/host/crypto/clmul.h
+++ b/host/include/generic/host/crypto/clmul.h
@@ -23,4 +23,6 @@ 
 #define clmul_32x2_even         clmul_32x2_even_gen
 #define clmul_32x2_odd          clmul_32x2_odd_gen
 
+#define clmul_64                clmul_64_gen
+
 #endif /* GENERIC_HOST_CRYPTO_CLMUL_H */
diff --git a/include/crypto/clmul.h b/include/crypto/clmul.h
index ce43c9aeb1..8b4c263459 100644
--- a/include/crypto/clmul.h
+++ b/include/crypto/clmul.h
@@ -111,6 +111,13 @@  Int128 clmul_32x2_even_gen(Int128, Int128);
  */
 Int128 clmul_32x2_odd_gen(Int128, Int128);
 
+/**
+ * clmul_64:
+ *
+ * Perform a 64x64->128 carry-less multiply.
+ */
+Int128 clmul_64_gen(uint64_t, uint64_t);
+
 #include "host/crypto/clmul.h"
 
 #endif /* CRYPTO_CLMUL_H */
diff --git a/crypto/clmul.c b/crypto/clmul.c
index c197cd5f21..0be06073f0 100644
--- a/crypto/clmul.c
+++ b/crypto/clmul.c
@@ -144,3 +144,20 @@  Int128 clmul_32x2_odd_gen(Int128 n, Int128 m)
     rh = clmul_32_gen(int128_gethi(n) >> 32, int128_gethi(m) >> 32);
     return int128_make128(rl, rh);
 }
+
+Int128 clmul_64_gen(uint64_t n, uint64_t m)
+{
+    uint64_t rl = 0, rh = 0;
+
+    /* Bit 0 can only influence the low 64-bit result.  */
+    if (n & 1) {
+        rl = m;
+    }
+
+    for (int i = 1; i < 64; ++i) {
+        uint64_t mask = -((n >> i) & 1);
+        rl ^= (m << i) & mask;
+        rh ^= (m >> (64 - i)) & mask;
+    }
+    return int128_make128(rl, rh);
+}