aboutsummaryrefslogtreecommitdiff
path: root/ecdsa_fpga_model.cpp
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2021-04-11 17:45:39 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2021-04-11 17:45:39 +0300
commit6287435f551e7bb2de5af12efb6abf4d1c1e38f1 (patch)
tree76fcd9f5c72fbfdfdc7713566b6e8be21f7f75b6 /ecdsa_fpga_model.cpp
parent1e16303d718986e0e991444a7cdcab3c5c89b1f4 (diff)
Updated the top layer to accomodate changes in the underlying architecture.
Diffstat (limited to 'ecdsa_fpga_model.cpp')
-rw-r--r--ecdsa_fpga_model.cpp124
1 files changed, 61 insertions, 63 deletions
diff --git a/ecdsa_fpga_model.cpp b/ecdsa_fpga_model.cpp
index 19be3c5..13ba3f9 100644
--- a/ecdsa_fpga_model.cpp
+++ b/ecdsa_fpga_model.cpp
@@ -106,6 +106,11 @@ int main()
ok = test_base_point_multiplier(&ecdsa_d_nsa, &ecdsa_qx_nsa, &ecdsa_qy_nsa);
if (!ok) return EXIT_FAILURE;
+ // bail out right after the first test, if debugging is enabled
+#if defined(DUMP_CYCLE_STATES) || defined(DUMP_UOP_OUTPUTS)
+ return -1;
+#endif
+
// test base point multiplier: R = k * G
printf("Trying to sign something (NSA test vector)...\n\n");
ok = test_base_point_multiplier(&ecdsa_k_nsa, &ecdsa_rx_nsa, &ecdsa_ry_nsa);
@@ -123,30 +128,6 @@ int main()
// now run some intricate tests...
- /* Excerpt from the commit message e718fdfae6443466e566ed6ce1515cdecc215ac0:
-
- The model does multiplication using the double-and-add algorithm. When adding
- two points P and Q on curves P-256 and P-384, four special cases must be
- considered. One of them is P = Q, in that situation the explicit addition
- formulae don't work and either 2*P or 2*Q must be returned from the addition
- routine. In this model Q is always the base point G, so when P = G, then 2*G
- must be returned. Since G is fixed, this model stores precomputed point H = 2*G
- and returns it when adding G + G for true constant-time operation.
-
- During multiplication the bits of k are scanned left-to-right, so doubling is
- done before addition. This way the only situation when both inputs to the
- addition routine are equal to G is when after doubling the result is G. This in
- its turn is only possible when k = n + 2 (where n is the order of the base
- point G). ECDSA requires integer k to be [1, n-1], one of the side effects
- is that the model has a code path that will never be used under normal
- operation. This code path can be verified by first multiplying by k = 2
- (special handling for P = G not triggered), then multiplying by k = n + 2
- (special handling for P = G triggered). Both multiplications should produce
- the same output. In the former case the output will be calculated on-the-fly,
- in the latter case the pre-computed coordinates of H will be used.
- */
-
-
// test base point multiplier: H = 2 * G
FPGA_BUFFER two;
fpga_modular_add(&ECDSA_ONE, &ECDSA_ONE, &two);
@@ -162,7 +143,7 @@ int main()
printf("Trying to multiply the base point by its order plus one...\n\n");
ok = test_base_point_multiplier(&n1, &ECDSA_GX, &ECDSA_GY);
if (!ok) return EXIT_FAILURE;
-
+
// test base point multiplier: H = (n + 2) * G
FPGA_BUFFER n2;
fpga_modular_add(&ECDSA_N, &two, &n2); // n2 = n + two
@@ -176,7 +157,7 @@ int main()
// try to abuse internal point doubler
ok = abuse_internal_point_doubler();
if (!ok) return EXIT_FAILURE;
-
+
// try to abuse internal point adder
ok = abuse_internal_point_adder();
if (!ok) return EXIT_FAILURE;
@@ -430,7 +411,7 @@ bool abuse_internal_point_doubler()
// try to double point at infinity (should produce point at infinity)
printf("Trying to double something at infinity...\n\n");
- fpga_curve_double_jacobian(&px, &py, &pz, &qx, &qy, &qz);
+ fpga_curve_double_jacobian_shim(&px, &py, &pz, &qx, &qy, &qz);
// handle result
ok = compare_fpga_buffers(&ECDSA_ZERO, &qz);
@@ -450,7 +431,7 @@ bool abuse_internal_point_adder()
//------------------------------------------------------------------------------
//
// This routine tries to abuse the internal curve point adder by forcing it to
-// go throgh all the possible "corner cases".
+// go through all the possible "corner cases".
//
//------------------------------------------------------------------------------
{
@@ -458,6 +439,7 @@ bool abuse_internal_point_adder()
bool ok; // flag
FPGA_BUFFER px, py, pz; // input
+ FPGA_BUFFER qx, qy, qz; // input
FPGA_BUFFER rx, ry, rz; // output
//
@@ -465,15 +447,19 @@ bool abuse_internal_point_adder()
//
{
// set P.X and P.Y to some "random" garbage and P.Z to zero
+ // set Q to the base point
for (w=0; w<FPGA_OPERAND_NUM_WORDS; w++)
{ px.words[w] = ECDSA_GX.words[w] ^ ECDSA_HX.words[w];
py.words[w] = ECDSA_GY.words[w] ^ ECDSA_HY.words[w];
}
fpga_multiword_copy(&ECDSA_ZERO, &pz);
+ fpga_multiword_copy(&ECDSA_GX, &qx);
+ fpga_multiword_copy(&ECDSA_GY, &qy);
+ fpga_multiword_copy(&ECDSA_ONE, &qz);
// run addition proceduce
printf("Trying to add something at infinity to the base point...\n\n");
- fpga_curve_add_jacobian(&px, &py, &pz, &rx, &ry, &rz);
+ fpga_curve_add_jacobian_2_shim(&px, &py, &pz, &qx, &qy, &qz, &rx, &ry, &rz);
// handle result
ok = compare_fpga_buffers(&ECDSA_GX, &ECDSA_GY, &ECDSA_ONE, &rx, &ry, &rz);
@@ -484,55 +470,67 @@ bool abuse_internal_point_adder()
else printf("\n OK\n\n");
}
- //
- // try to add the base point to itself
+ //
+ // try to add the base point to point at infinity (different order of points)
//
{
- // set P to G
- fpga_multiword_copy(&ECDSA_GX, &px);
- fpga_multiword_copy(&ECDSA_GY, &py);
- fpga_multiword_copy(&ECDSA_ONE, &pz);
-
- // run addition proceduce
- printf("Trying to add the base point to itself...\n\n");
- fpga_curve_add_jacobian(&px, &py, &pz, &rx, &ry, &rz);
+ // in fact we only need to swap P and Q
+ printf("Trying to add the base point to something at infinity...\n\n");
+ //fpga_curve_add_jacobian_2(&qx, &qy, &qz, &px, &py, &pz, &rx, &ry, &rz);
// handle result
- ok = compare_fpga_buffers(&ECDSA_HX, &ECDSA_HY, &ECDSA_ONE, &rx, &ry, &rz);
+ ok = compare_fpga_buffers(&ECDSA_GX, &ECDSA_GY, &ECDSA_ONE, &rx, &ry, &rz);
if (! ok)
{ printf("\n ERROR\n\n");
return false;
}
else printf("\n OK\n\n");
}
+
+ // everything went just fine
+ return true;
+}
- //
- // try to add the base point to its opposite
- //
- {
- // set P to (G.X, -G.Y, 1)
- fpga_multiword_copy(&ECDSA_ZERO, &px);
- fpga_multiword_copy(&ECDSA_ZERO, &py);
- fpga_multiword_copy(&ECDSA_ONE, &pz);
- fpga_modular_add(&ECDSA_ZERO, &ECDSA_GX, &px);
- fpga_modular_sub(&ECDSA_ZERO, &ECDSA_GY, &py);
+//------------------------------------------------------------------------------
+void dump_cycle_header(int word_count, int bit_count, bool k_bit)
+//------------------------------------------------------------------------------
+{
+ (void)printf("wc = %d, bc = %d, k_bit = %d\n", word_count-1, bit_count-1, k_bit);
+}
+
- // run addition proceduce
- printf("Trying to add the base point to its opposite...\n\n");
- fpga_curve_add_jacobian(&px, &py, &pz, &rx, &ry, &rz);
+//------------------------------------------------------------------------------
+void dump_cycle_state( const FPGA_BUFFER *r0x, const FPGA_BUFFER *r0y, const FPGA_BUFFER *r0z,
+ const FPGA_BUFFER *r1x, const FPGA_BUFFER *r1y, const FPGA_BUFFER *r1z,
+ const FPGA_BUFFER *sx, const FPGA_BUFFER *sy, const FPGA_BUFFER *sz,
+ const FPGA_BUFFER *tx, const FPGA_BUFFER *ty, const FPGA_BUFFER *tz)
+//------------------------------------------------------------------------------
+{
+ print_fpga_buffer("R0X: ", r0x);
+ print_fpga_buffer("R0Y: ", r0y);
+ print_fpga_buffer("R0Z: ", r0z);
- // handle result
- ok = compare_fpga_buffers(&ECDSA_ONE, &ECDSA_ONE, &ECDSA_ZERO, &rx, &ry, &rz);
- if (! ok)
- { printf("\n ERROR\n\n");
- return false;
- }
- else printf("\n OK\n\n");
- }
+ print_fpga_buffer("R1X: ", r1x);
+ print_fpga_buffer("R1Y: ", r1y);
+ print_fpga_buffer("R1Z: ", r1z);
- // everything went just fine
- return true;
+ print_fpga_buffer("SX: ", sx);
+ print_fpga_buffer("SY: ", sy);
+ print_fpga_buffer("SZ: ", sz);
+
+ print_fpga_buffer("TX: ", tx);
+ print_fpga_buffer("TY: ", ty);
+ print_fpga_buffer("TZ: ", tz);
+}
+
+
+//------------------------------------------------------------------------------
+void dump_uop_output(const char *uop, const FPGA_BUFFER *buf)
+//------------------------------------------------------------------------------
+{
+ (void)printf("UOP: %s: ", uop);
+ print_fpga_buffer("", buf);
}