From 2db58a7ba317da318eca5ae19dcc0e4899c423e1 Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Tue, 18 Jul 2017 02:14:27 +0300 Subject: Changes to the model: * Follow what Verilog does more closely: FPGA can't do PP = P * P, because it can't read from two different block mem P locations at the same time, we have to do P1 = P2 = P, PP = P1 * P2 * Updated the test vector script to format additional quantities to help debug Verilog exponentiation module * Added the trick suggested by Bernd Paysan to help better conceal whether we're discarding multiplication result when the current exponent bit is not set --- modexp_fpga_model.h | 6 +++++ modexp_fpga_model_montgomery.cpp | 47 +++++++++++++++++++++++++++------------- test/format_test_vectors.py | 6 +++-- test/modexp_fpga_model_vectors.v | 22 +++++++++++++++++++ 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/modexp_fpga_model.h b/modexp_fpga_model.h index 2a91d32..567b625 100644 --- a/modexp_fpga_model.h +++ b/modexp_fpga_model.h @@ -57,6 +57,12 @@ typedef uint64_t _WIDE_WORD; // only used internally to mimic DSP slice operati #define SYSTOLIC_WIDTH 128 // width of systolic array in bits +//---------------------------------------------------------------- +// Power Consumption Masking Constant +//---------------------------------------------------------------- +#define POWER_MASK 0x5A5A5A5A + + //---------------------------------------------------------------- // Handy values //---------------------------------------------------------------- diff --git a/modexp_fpga_model_montgomery.cpp b/modexp_fpga_model_montgomery.cpp index 5bc5ba4..92a5e47 100644 --- a/modexp_fpga_model_montgomery.cpp +++ b/modexp_fpga_model_montgomery.cpp @@ -132,22 +132,35 @@ void montgomery_exponentiate(const FPGA_WORD *A, const FPGA_WORD *B, const FPGA_ bool flag_update_r; // flag - FPGA_WORD P[MAX_OPERAND_WORDS]; // power of A - FPGA_WORD mask; // mask + FPGA_WORD T0[MAX_OPERAND_WORDS]; // + FPGA_WORD T1[MAX_OPERAND_WORDS]; // + FPGA_WORD T2[MAX_OPERAND_WORDS]; // + + FPGA_WORD P1[MAX_OPERAND_WORDS]; // + FPGA_WORD P2[MAX_OPERAND_WORDS]; // + FPGA_WORD P3[MAX_OPERAND_WORDS]; // + + FPGA_WORD mask; // // R = 1, P = 1 for (word_cnt=0; word_cnt 0) ? 0 : 1, - P[word_cnt] = A[word_cnt]; + T1[word_cnt] = (word_cnt > 0) ? 0 : 1, + T2[word_cnt] = (word_cnt > 0) ? 0 : 1, + P1[word_cnt] = A[word_cnt], + P2[word_cnt] = A[word_cnt], + P3[word_cnt] = A[word_cnt]; - FPGA_WORD M_PP[MAX_OPERAND_WORDS]; // intermediate buffer for next power - FPGA_WORD M_RP[MAX_OPERAND_WORDS]; // intermediate buffer for next result + FPGA_WORD PP[MAX_OPERAND_WORDS]; // intermediate buffer for next power + FPGA_WORD TP[MAX_OPERAND_WORDS]; // intermediate buffer for next result // scan all bits of the exponent for (bit_cnt=0; bit_cnt<(len * CHAR_BIT * sizeof(FPGA_WORD)); bit_cnt++) { - montgomery_multiply(P, P, N, N_COEFF, M_PP, len, false); // M_PP = P * P - montgomery_multiply(R, P, N, N_COEFF, M_RP, len, false); // M_RP = R * P + for (word_cnt=0; word_cnt