@@ -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 */
@@ -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 */
@@ -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);
+}
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(+)