aboutsummaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c99
1 files changed, 89 insertions, 10 deletions
diff --git a/main.c b/main.c
index d538f48..6584eeb 100644
--- a/main.c
+++ b/main.c
@@ -6,34 +6,113 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include "function.h"
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
+#include <asm/fpu/api.h>
+#include <asm/simd.h>
static unsigned long stamp = 0;
module_param(stamp, ulong, 0);
int dummy;
+
+enum { CURVE25519_POINT_SIZE = 32 };
+u8 dummy_out[CURVE25519_POINT_SIZE];
+#include "test_vectors.h"
+
+#define declare_it(name) \
+bool curve25519_ ## name(u8 mypublic[CURVE25519_POINT_SIZE], const u8 secret[CURVE25519_POINT_SIZE], const u8 basepoint[CURVE25519_POINT_SIZE]); \
+static __always_inline int name(void) \
+{ \
+ return curve25519_ ## name(dummy_out, curve25519_test_vectors[0].private, curve25519_test_vectors[0].public); \
+}
+
+#define do_it(name) do { \
+ for (i = 0; i < WARMUP; ++i) \
+ ret |= name(); \
+ start_ ## name = get_cycles(); \
+ for (i = 0; i < TRIALS; ++i) \
+ ret |= name(); \
+ end_ ## name = get_cycles(); \
+} while (0)
+
+#define test_it(name, before, after) do { \
+ memset(out, __LINE__, CURVE25519_POINT_SIZE); \
+ before; \
+ ret = curve25519_ ## name(out, curve25519_test_vectors[i].private, curve25519_test_vectors[i].public); \
+ after; \
+ if (memcmp(out, curve25519_test_vectors[i].result, CURVE25519_POINT_SIZE)) { \
+ pr_err(#name " self-test %zu: FAIL\n", i + 1); \
+ return false; \
+ } \
+} while (0)
+
+#define report_it(name) do { \
+ pr_err("%lu: %7s: %llu cycles per call\n", stamp, #name, (end_ ## name - start_ ## name) / TRIALS); \
+} while (0)
+
+
+declare_it(donna64)
+declare_it(hacl64)
+declare_it(sandy2x)
+declare_it(amd64)
+declare_it(fiat32)
+declare_it(donna32)
+
+static bool verify(void)
+{
+ int ret;
+ size_t i = 0;
+ u8 out[CURVE25519_POINT_SIZE];
+
+ for (i = 0; i < ARRAY_SIZE(curve25519_test_vectors); ++i) {
+ test_it(donna64, {}, {});
+ test_it(hacl64, {}, {});
+ test_it(sandy2x, kernel_fpu_begin(), kernel_fpu_end());
+ test_it(amd64, {}, {});
+ test_it(fiat32, {}, {});
+ test_it(donna32, {}, {});
+ }
+ return true;
+}
+
static int __init mod_init(void)
{
+ enum { WARMUP = 5000, TRIALS = 10000, IDLE = 1 * 1000 };
int ret = 0, i;
- cycles_t start, end;
+ cycles_t start_donna64, end_donna64;
+ cycles_t start_hacl64, end_hacl64;
+ cycles_t start_sandy2x, end_sandy2x;
+ cycles_t start_amd64, end_amd64;
+ cycles_t start_fiat32, end_fiat32;
+ cycles_t start_donna32, end_donna32;
unsigned long flags;
DEFINE_SPINLOCK(lock);
+
+ if (!verify())
+ return -EBFONT;
msleep(IDLE);
spin_lock_irqsave(&lock, flags);
-
- for (i = 0; i < WARMUP; ++i)
- ret |= function();
- start = get_cycles();
- for (i = 0; i < TRIALS; ++i)
- ret |= function();
- end = get_cycles();
+ do_it(donna64);
+ do_it(hacl64);
+ kernel_fpu_begin();
+ do_it(sandy2x);
+ kernel_fpu_end();
+ do_it(amd64);
+ do_it(fiat32);
+ do_it(donna32);
spin_unlock_irqrestore(&lock, flags);
- pr_err("%lu: %llu cycles per call\n", stamp, (end - start) / TRIALS);
+ report_it(donna64);
+ report_it(hacl64);
+ report_it(sandy2x);
+ report_it(amd64);
+ report_it(fiat32);
+ report_it(donna32);
/* Don't let compiler be too clever. */
dummy = ret;