[Cryptech-Commits] [sw/libhal] 01/01: First attempt at using Pavel's ecdsa256 core. Not working yet.

git at cryptech.is git at cryptech.is
Thu Jan 26 06:00:30 UTC 2017


This is an automated email from the git hooks/post-receive script.

sra at hactrn.net pushed a commit to branch hw_ecdsa_p256
in repository sw/libhal.

commit 99407a540c7f1fbbc0987837173d1b81aee790bc
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Thu Jan 26 00:49:12 2017 -0500

    First attempt at using Pavel's ecdsa256 core.  Not working yet.
    
    Attempts to use Pavel's ecdsa256 base point multiplier instead of
    software point multiplier when selecting new random points (that is,
    when generating P-256 keys or P-256 signatures).  Resulting points
    pass the point validation test (point_is_on_curve()) but the resulting
    signatures are invalid.  Don't know why yet.  Seems like an odd
    combination, as one would expect random garbage to fail validation.
    
    In any case: this commit is intended to archive progress so far, and
    perhaps see if somebody else can spot what's wrong.  As presently
    coded, this wouldn't be suitable for production use even if it worked.
    
    NB: As I understand it, the ecdsa256 core is *not* a general purpose
    point multiplier even just for the P-256 curve.  Rather, it is
    strictly a base point multiplier: it takes a single scalar as input,
    and returns the X,Y affine coordinates of the curve's base point
    multiplied by that scalar.  This is essentially the eliptic curve
    portion of the computation involved in picking a random point for key
    or signature generation, but is not useful for signature validation.
    See the README.md in Pavel's source repository for further details.
---
 ecdsa.c             | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 hal.h               |  3 +++
 verilog_constants.h | 18 ++++++++++++-
 3 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/ecdsa.c b/ecdsa.c
index 916a2f4..42ea307 100644
--- a/ecdsa.c
+++ b/ecdsa.c
@@ -89,6 +89,18 @@
 #endif
 
 /*
+ * Whether to use experimental Verilog ECDSA-P256 point multiplier.
+ */
+
+#ifndef HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
+#define HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER 1
+#endif
+
+#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
+static int verilog_ecdsa256_multiplier = 1;
+#endif
+
+/*
  * Whether we want debug output.
  */
 
@@ -749,6 +761,65 @@ static inline hal_error_t get_random(void *buffer, const size_t length)
 #endif /* HAL_ECDSA_DEBUG_ONLY_STATIC_TEST_VECTOR_RANDOM */
 
 /*
+ * Use experimental Verilog base point multiplier core to calculate
+ * public key given a private key.  point_pick_random() has already
+ * selected a suitable private key for us, we just need to calculate
+ * the corresponding public key.
+ */
+
+#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
+
+static hal_error_t verilog_point_pick_random(fp_int *k, ec_point_t *P)
+{
+  assert(k != NULL && P != NULL);
+
+  const size_t len = fp_unsigned_bin_size(k);
+  uint8_t b[ECDSA256_OPERAND_BITS / 8];
+  const uint8_t zero[4] = {0, 0, 0, 0};
+  hal_core_t *core = NULL;
+  hal_error_t err;
+
+  if (len > sizeof(b))
+    return HAL_ERROR_RESULT_TOO_LONG;
+
+  if ((err = hal_core_alloc(ECDSA256_NAME, &core)) != HAL_OK)
+    goto fail;
+
+#define check(_x_) do { if ((err = (_x_)) != HAL_OK) goto fail; } while (0)
+
+  memset(b, 0, sizeof(b));
+  fp_to_unsigned_bin(k, b + sizeof(b) - len);
+
+  for (int i = 0; i < sizeof(b); i += 4)
+    check(hal_io_write(core, ECDSA256_ADDR_K + i/4, &b[sizeof(b) - 4 - i], 4));
+
+  check(hal_io_write(core, ADDR_CTRL, zero, sizeof(zero)));
+  check(hal_io_next(core));
+  check(hal_io_wait_ready(core));
+
+  for (int i = 0; i < sizeof(b); i += 4)
+    check(hal_io_read(core, ECDSA256_ADDR_X + i/4, &b[sizeof(b) - 4 - i], 4));
+  fp_read_unsigned_bin(P->x, b, sizeof(b));
+
+  for (int i = 0; i < sizeof(b); i += 4)
+    check(hal_io_read(core, ECDSA256_ADDR_Y + i/4, &b[sizeof(b) - 4 - i], 4));
+  fp_read_unsigned_bin(P->y, b, sizeof(b));
+
+  fp_set(P->z, 1);
+
+#undef check
+
+  err = HAL_OK;
+
+ fail:
+  hal_core_free(core);
+  memset(b, 0, sizeof(b));
+  return err;
+}
+
+#endif
+
+/*
  * Pick a random point on the curve, return random scalar and
  * resulting point.
  */
@@ -792,6 +863,12 @@ static hal_error_t point_pick_random(const ecdsa_curve_t * const curve,
 
   memset(k_buf, 0, sizeof(k_buf));
 
+#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
+  if (verilog_ecdsa256_multiplier && curve == get_curve(HAL_CURVE_P256) &&
+      (err = verilog_point_pick_random(k, P)) != HAL_ERROR_CORE_NOT_FOUND)
+    return err;
+#endif
+
   /*
    * Calculate P = kG and return.
    */
diff --git a/hal.h b/hal.h
index 72b1d58..b1a217a 100644
--- a/hal.h
+++ b/hal.h
@@ -103,6 +103,9 @@
 #define MKMIF_NAME              "mkmif   "
 #define MKMIF_VERSION           "0.10"
 
+#define ECDSA256_NAME           "ecdsa256"
+#define ECDSA256_VERSION        "0.11"
+
 /*
  * C API error codes.  Defined in this form so we can keep the tokens
  * and error strings together.  See errorstrings.c.
diff --git a/verilog_constants.h b/verilog_constants.h
index f0ae070..900785c 100644
--- a/verilog_constants.h
+++ b/verilog_constants.h
@@ -8,7 +8,7 @@
  * hand-edited.
  *
  * Authors: Joachim Strombergson, Paul Selkirk, Rob Austein
- * Copyright (c) 2015-2016, NORDUnet A/S All rights reserved.
+ * Copyright (c) 2015-2017, NORDUnet A/S All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -241,6 +241,22 @@
 #define MODEXPA7_ADDR_RESULT            (MODEXPA7_ADDR_OPERANDS + 3 * MODEXPA7_OPERAND_WORDS)
 
 /*
+ * ECDSA P-256 point mulitipler core.  ECDSA256_OPERAND_BITS is size
+ * in bits of the (only) supported operand size (256 bits, imagine that).
+ *
+ * (Not sure which category EC Point Mulitiplier will end up in, but
+ * let's pretend it's "math".)
+ */
+
+#define ECDSA256_OPERAND_BITS           (256)
+#define ECDSA256_OPERAND_WORDS          (ECDSA256_OPERAND_BITS / 32)
+#define ECDSA256_ADDR_REGISTERS         (0 * ECDSA256_OPERAND_WORDS)
+#define ECDSA256_ADDR_OPERANDS          (4 * ECDSA256_OPERAND_WORDS)
+#define ECDSA256_ADDR_K                 (ECDSA256_ADDR_OPERANDS + 0 * ECDSA256_OPERAND_WORDS)
+#define ECDSA256_ADDR_X                 (ECDSA256_ADDR_OPERANDS + 1 * ECDSA256_OPERAND_WORDS)
+#define ECDSA256_ADDR_Y                 (ECDSA256_ADDR_OPERANDS + 2 * ECDSA256_OPERAND_WORDS)
+
+/*
  * Utility cores.
  */
 



More information about the Commits mailing list