aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-08-15 14:34:06 -0400
committerJack Lloyd <[email protected]>2017-08-15 14:34:06 -0400
commit2266362024009f0364a07dd1bcff5115180f40a7 (patch)
tree18804ff157bab625de6c095099f74971e529b566 /src/lib/utils
parentba2c6c7b020497178776b4574ed329586f97c211 (diff)
Improve polynomial doubling code, move to util
Now does 64-bits at a time instead of 8 bits, and avoids conditional timing channel on the XOR carry. Confirmed that at least GCC 7 and Clang 4 on x86-64 compile the functions without conditional jumps. Also removes CMAC as a dependency of OCB, which only needed it in order to call CMAC::poly_double
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/info.txt1
-rw-r--r--src/lib/utils/poly_dbl.cpp129
-rw-r--r--src/lib/utils/poly_dbl.h25
3 files changed, 155 insertions, 0 deletions
diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt
index 193145c5d..cd0b4bc45 100644
--- a/src/lib/utils/info.txt
+++ b/src/lib/utils/info.txt
@@ -32,6 +32,7 @@ ct_utils.h
donna128.h
filesystem.h
os_utils.h
+poly_dbl.h
prefetch.h
rounding.h
safeint.h
diff --git a/src/lib/utils/poly_dbl.cpp b/src/lib/utils/poly_dbl.cpp
new file mode 100644
index 000000000..0cea4957b
--- /dev/null
+++ b/src/lib/utils/poly_dbl.cpp
@@ -0,0 +1,129 @@
+/*
+* (C) 2017 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/internal/poly_dbl.h>
+#include <botan/loadstor.h>
+#include <botan/exceptn.h>
+
+namespace Botan {
+
+void poly_double_n(uint8_t b[], size_t n)
+ {
+ if(n == 8)
+ return poly_double_8(b);
+ else if(n == 16)
+ return poly_double_16(b);
+ else if(n == 24)
+ return poly_double_24(b);
+ else if(n == 32)
+ return poly_double_32(b);
+ else if(n == 64)
+ return poly_double_64(b);
+ else
+ throw Invalid_Argument("Unsupported size for poly_double_n");
+ }
+
+void poly_double_8(uint8_t b[8])
+ {
+ const uint64_t poly = 0x1B;
+ uint64_t b0 = load_be<uint64_t>(b, 0);
+ const uint64_t carry0 = (b0 >> 63);
+ b0 = (b0 << 1) ^ (carry0 * poly);
+ store_be(b0, b);
+ }
+
+void poly_double_16(uint8_t b[16])
+ {
+ const uint64_t poly = 0x87;
+
+ uint64_t b0 = load_be<uint64_t>(b, 0);
+ uint64_t b1 = load_be<uint64_t>(b, 1);
+
+ const uint64_t carry0 = (b0 >> 63);
+
+ b0 = (b0 << 1) ^ (b1 >> 63);
+ b1 = (b1 << 1) ^ (carry0 * poly);
+
+ store_be(b0, b);
+ store_be(b1, b+8);
+ }
+
+void poly_double_24(uint8_t b[24])
+ {
+ const uint64_t poly = 0x87;
+
+ uint64_t b0 = load_be<uint64_t>(b, 0);
+ uint64_t b1 = load_be<uint64_t>(b, 1);
+ uint64_t b2 = load_be<uint64_t>(b, 2);
+
+ const uint64_t carry0 = (b0 >> 63);
+
+ b0 = (b0 << 1) ^ (b1 >> 63);
+ b1 = (b1 << 1) ^ (b2 >> 63);
+ b2 = (b2 << 1) ^ (carry0 * poly);
+
+ store_be(b0, b);
+ store_be(b1, b+8);
+ store_be(b2, b+16);
+ }
+
+void poly_double_32(uint8_t b[32])
+ {
+ const uint64_t poly = 0x425;
+
+ uint64_t b0 = load_be<uint64_t>(b, 0);
+ uint64_t b1 = load_be<uint64_t>(b, 1);
+ uint64_t b2 = load_be<uint64_t>(b, 2);
+ uint64_t b3 = load_be<uint64_t>(b, 3);
+
+ const uint64_t carry0 = (b0 >> 63);
+
+ b0 = (b0 << 1) ^ (b1 >> 63);
+ b1 = (b1 << 1) ^ (b2 >> 63);
+ b2 = (b2 << 1) ^ (b3 >> 63);
+ b3 = (b3 << 1) ^ (carry0 * poly);
+
+ store_be(b0, b);
+ store_be(b1, b+8);
+ store_be(b2, b+16);
+ store_be(b3, b+24);
+ }
+
+void poly_double_64(uint8_t b[64])
+ {
+ const uint64_t poly = 0x125;
+
+ uint64_t b0 = load_be<uint64_t>(b, 0);
+ uint64_t b1 = load_be<uint64_t>(b, 1);
+ uint64_t b2 = load_be<uint64_t>(b, 2);
+ uint64_t b3 = load_be<uint64_t>(b, 3);
+ uint64_t b4 = load_be<uint64_t>(b, 4);
+ uint64_t b5 = load_be<uint64_t>(b, 5);
+ uint64_t b6 = load_be<uint64_t>(b, 6);
+ uint64_t b7 = load_be<uint64_t>(b, 7);
+
+ const uint64_t carry0 = (b0 >> 63);
+
+ b0 = (b0 << 1) ^ (b1 >> 63);
+ b1 = (b1 << 1) ^ (b2 >> 63);
+ b2 = (b2 << 1) ^ (b3 >> 63);
+ b3 = (b3 << 1) ^ (b4 >> 63);
+ b4 = (b4 << 1) ^ (b5 >> 63);
+ b5 = (b5 << 1) ^ (b6 >> 63);
+ b6 = (b6 << 1) ^ (b7 >> 63);
+ b7 = (b7 << 1) ^ (carry0 * poly);
+
+ store_be(b0, b);
+ store_be(b1, b+8);
+ store_be(b2, b+16);
+ store_be(b3, b+24);
+ store_be(b4, b+32);
+ store_be(b5, b+40);
+ store_be(b6, b+48);
+ store_be(b7, b+56);
+ }
+
+}
diff --git a/src/lib/utils/poly_dbl.h b/src/lib/utils/poly_dbl.h
new file mode 100644
index 000000000..df3b419c3
--- /dev/null
+++ b/src/lib/utils/poly_dbl.h
@@ -0,0 +1,25 @@
+/*
+* (C) 2017 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_POLY_DBL_H__
+#define BOTAN_POLY_DBL_H__
+
+#include <botan/types.h>
+
+namespace Botan {
+
+void BOTAN_DLL poly_double_n(uint8_t b[], size_t n);
+
+void poly_double_8(uint8_t b[8]);
+void poly_double_16(uint8_t b[16]);
+void poly_double_24(uint8_t b[24]);
+void poly_double_32(uint8_t b[32]);
+void poly_double_64(uint8_t b[64]);
+
+
+}
+
+#endif