diff options
-rw-r--r-- | modexpng_fpga_model.py | 450 | ||||
-rw-r--r-- | vector/README.md | 4 | ||||
-rw-r--r-- | vector/vector_format.py | 2 | ||||
-rw-r--r-- | vector/vector_regenerate.py | 2 |
4 files changed, 357 insertions, 101 deletions
diff --git a/modexpng_fpga_model.py b/modexpng_fpga_model.py index 325f544..41acbff 100644 --- a/modexpng_fpga_model.py +++ b/modexpng_fpga_model.py @@ -49,7 +49,7 @@ from enum import Enum, auto # -------------- # length of public key -KEY_LENGTH = 1024 +KEY_LENGTH = 512 # how many parallel multipliers to use NUM_MULTS = 8 @@ -80,7 +80,7 @@ _VECTOR_CLASS = "Vector" # ------------------ # Debugging Settings # ------------------ -DUMP_LADDER_INDEX = -1 # at which ladder step to print debug vector +DUMP_LADDER_INDEX = -1 # at which ladder step to print intermediate debug vector (-1 doesn't print internals) DUMP_VECTORS = False # print entire debug vector components DUMP_INDICES = False # print indices of words at MAC inputs DUMP_MACS_INPUTS = False # print MAC input words @@ -89,8 +89,12 @@ DUMP_MACS_ACCUMULATION = False # print MAC accumulators contents DUMP_MULT_PARTS = False # print multiplication output parts DUMP_RECOMBINATION = False # print recombination internals DUMP_REDUCTION = False # print reduction internals +DUMP_EXPONENTS = False # dump secret exponents FORCE_OVERFLOW = False # force rarely seen internal overflow situation to verify how its handler works DUMP_PROGRESS_FACTOR = 16 # once per how many ladder steps to update progress indicator +DUMP_FORMAT_BUS = True # False: dump 18-bit words, True: dump 32-bit words +DUMP_FORMAT_C_ARRAY = False # False: dump in Verilog format, True: dump as C array initializer + # # Multi-Precision Integer @@ -115,14 +119,50 @@ class ModExpNG_Operand(): self._init_from_words(words, length) - def format_verilog_concat(self, name): + def copy(self): + return ModExpNG_Operand(None, len(self.words), self.words) - for i in range(len(self.words)): - if i > 0: - if (i % 4) == 0: print("") - else: print(" ", end='') - print("%s[%3d] = 18'h%05x;" % (name, i, self.words[i]), end='') + def _format_verilog(self, name): + + if not DUMP_FORMAT_BUS: + for i in range(len(self.words)): + if i > 0: + if (i % 4) == 0: print("") + else: print(" ", end='') + print("%s[%3d] = 18'h%05x;" % (name, i, self.words[i]), end='') + else: + + _words = list(self.words) + num_words = len(_words) + + if num_words % 2 > 0: + _words.append(0) + num_words += 1 + + for i in range(num_words // 2): + if i > 0: + if (i % 4) == 0: print("") + else: print(" ", end='') + print("%s[%3d] = 32'h%04x%04x;" % (name, i, _words[2*i+1], _words[2*i]), end='') print("") + + def _format_c_array(self, name): + words = list(reversed(self.words)) + if len(words) % 2 > 0: words.insert(0, 0) + + print("#define %s_%d_INIT \\\n\t{" % (name, KEY_LENGTH), end='') + for i in range(0, len(words), 2): + print("0x%04x%04x" % (words[i], words[i+1]), end='') + if (i + 2) < len(words): + print(", ", end='') + if ((i + 2) % 8) == 0: print("\\\n\t ", end='') + else: print("}") + + def format(self, name): + if not DUMP_FORMAT_C_ARRAY: + self._format_verilog(name) + else: + self._format_c_array(name) def _init_from_words(self, words, count): @@ -235,6 +275,8 @@ class ModExpNG_NarrowBankEnum(Enum): D = auto() E = auto() N_COEFF = auto() + Q = auto() + EXT = auto() I = auto() class ModExpNG_CoreInputEnum(Enum): @@ -273,6 +315,15 @@ class ModExpNG_WideBank(): self.n = None self.l = None self.h = None + + self.a_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.b_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.c_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.d_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.e_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.n_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.l_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.h_cache = ModExpNG_Operand(0, KEY_LENGTH) def _get_value(self, sel): if sel == ModExpNG_WideBankEnum.A: return self.a @@ -285,16 +336,46 @@ class ModExpNG_WideBank(): elif sel == ModExpNG_WideBankEnum.H: return self.h else: raise Exception("ModExpNG_WideBank._get_value(): Invalid selector!") + def _get_value_cache(self, sel): + if sel == ModExpNG_WideBankEnum.A: return self.a_cache + elif sel == ModExpNG_WideBankEnum.B: return self.b_cache + elif sel == ModExpNG_WideBankEnum.C: return self.c_cache + elif sel == ModExpNG_WideBankEnum.D: return self.d_cache + elif sel == ModExpNG_WideBankEnum.E: return self.e_cache + elif sel == ModExpNG_WideBankEnum.N: return self.n_cache + elif sel == ModExpNG_WideBankEnum.L: return self.l_cache + elif sel == ModExpNG_WideBankEnum.H: return self.h_cache + else: raise Exception("ModExpNG_WideBank._get_value(): Invalid selector!") + def _set_value(self, sel, value): - if sel == ModExpNG_WideBankEnum.A: self.a = value - elif sel == ModExpNG_WideBankEnum.B: self.b = value - elif sel == ModExpNG_WideBankEnum.C: self.c = value - elif sel == ModExpNG_WideBankEnum.D: self.d = value - elif sel == ModExpNG_WideBankEnum.E: self.e = value - elif sel == ModExpNG_WideBankEnum.N: self.n = value - elif sel == ModExpNG_WideBankEnum.L: self.l = value - elif sel == ModExpNG_WideBankEnum.H: self.h = value + + if sel == ModExpNG_WideBankEnum.A: self.a = value.copy() + elif sel == ModExpNG_WideBankEnum.B: self.b = value.copy() + elif sel == ModExpNG_WideBankEnum.C: self.c = value.copy() + elif sel == ModExpNG_WideBankEnum.D: self.d = value.copy() + elif sel == ModExpNG_WideBankEnum.E: self.e = value.copy() + elif sel == ModExpNG_WideBankEnum.N: self.n = value.copy() + elif sel == ModExpNG_WideBankEnum.L: self.l = value.copy() + elif sel == ModExpNG_WideBankEnum.H: self.h = value.copy() else: raise Exception("ModExpNG_WideBank._set_value(): Invalid selector!") + + if sel == ModExpNG_WideBankEnum.A: + for i in range(len(value.words)): self.a_cache.words[i] = value.words[i] + elif sel == ModExpNG_WideBankEnum.B: + for i in range(len(value.words)): self.b_cache.words[i] = value.words[i] + elif sel == ModExpNG_WideBankEnum.C: + for i in range(len(value.words)): self.c_cache.words[i] = value.words[i] + elif sel == ModExpNG_WideBankEnum.D: + for i in range(len(value.words)): self.d_cache.words[i] = value.words[i] + elif sel == ModExpNG_WideBankEnum.E: + for i in range(len(value.words)): self.e_cache.words[i] = value.words[i] + elif sel == ModExpNG_WideBankEnum.N: + for i in range(len(value.words)): self.n_cache.words[i] = value.words[i] + elif sel == ModExpNG_WideBankEnum.L: + for i in range(len(value.words)): self.l_cache.words[i] = value.words[i] + elif sel == ModExpNG_WideBankEnum.H: + for i in range(len(value.words)): self.h_cache.words[i] = value.words[i] + class ModExpNG_NarrowBank(): @@ -305,7 +386,17 @@ class ModExpNG_NarrowBank(): self.d = None self.e = None self.n_coeff = None + self.q = None + self.ext = ModExpNG_Operand(0, 2*_WORD_WIDTH) self.i = i + + self.a_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.b_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.c_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.d_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.e_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.n_coeff_cache = ModExpNG_Operand(0, KEY_LENGTH) + self.q_cache = ModExpNG_Operand(0, KEY_LENGTH) def _get_value(self, sel): if sel == ModExpNG_NarrowBankEnum.A: return self.a @@ -314,18 +405,50 @@ class ModExpNG_NarrowBank(): elif sel == ModExpNG_NarrowBankEnum.D: return self.d elif sel == ModExpNG_NarrowBankEnum.E: return self.e elif sel == ModExpNG_NarrowBankEnum.N_COEFF: return self.n_coeff + elif sel == ModExpNG_NarrowBankEnum.Q: return self.q + elif sel == ModExpNG_NarrowBankEnum.EXT: return self.ext elif sel == ModExpNG_NarrowBankEnum.I: return self.i else: raise Exception("ModExpNG_NarrowBank._get_value(): Invalid selector!") + def _get_value_cache(self, sel): + if sel == ModExpNG_NarrowBankEnum.A: return self.a_cache + elif sel == ModExpNG_NarrowBankEnum.B: return self.b_cache + elif sel == ModExpNG_NarrowBankEnum.C: return self.c_cache + elif sel == ModExpNG_NarrowBankEnum.D: return self.d_cache + elif sel == ModExpNG_NarrowBankEnum.E: return self.e_cache + elif sel == ModExpNG_NarrowBankEnum.N_COEFF: return self.n_coeff_cache + elif sel == ModExpNG_NarrowBankEnum.Q: return self.q_cache + else: raise Exception("ModExpNG_NarrowBank._get_value(): Invalid selector!") + def _set_value(self, sel, value): - if sel == ModExpNG_NarrowBankEnum.A: self.a = value - elif sel == ModExpNG_NarrowBankEnum.B: self.b = value - elif sel == ModExpNG_NarrowBankEnum.C: self.c = value - elif sel == ModExpNG_NarrowBankEnum.D: self.d = value - elif sel == ModExpNG_NarrowBankEnum.E: self.e = value - elif sel == ModExpNG_NarrowBankEnum.N_COEFF: self.n_coeff = value + if sel == ModExpNG_NarrowBankEnum.A: self.a = value.copy() + elif sel == ModExpNG_NarrowBankEnum.B: self.b = value.copy() + elif sel == ModExpNG_NarrowBankEnum.C: self.c = value.copy() + elif sel == ModExpNG_NarrowBankEnum.D: self.d = value.copy() + elif sel == ModExpNG_NarrowBankEnum.E: self.e = value.copy() + elif sel == ModExpNG_NarrowBankEnum.N_COEFF: + self.n_coeff = ModExpNG_Operand(None, len(value.words)-1, value.words[:-1]) + self.ext.words[0] = value.words[-1] + elif sel == ModExpNG_NarrowBankEnum.Q: + self.q = ModExpNG_Operand(None, len(value.words)-1, value.words[:-1]) + self.ext.words[1] = value.words[-1] else: raise Exception("ModExpNG_NarrowBank._set_value(): Invalid selector!") + if sel == ModExpNG_NarrowBankEnum.A: + for i in range(len(value.words)): self.a_cache.words[i] = value.words[i] + elif sel == ModExpNG_NarrowBankEnum.B: + for i in range(len(value.words)): self.b_cache.words[i] = value.words[i] + elif sel == ModExpNG_NarrowBankEnum.C: + for i in range(len(value.words)): self.c_cache.words[i] = value.words[i] + elif sel == ModExpNG_NarrowBankEnum.D: + for i in range(len(value.words)): self.d_cache.words[i] = value.words[i] + elif sel == ModExpNG_NarrowBankEnum.E: + for i in range(len(value.words)): self.e_cache.words[i] = value.words[i] + elif sel == ModExpNG_NarrowBankEnum.N_COEFF: + for i in range(len(value.words)-1): self.n_coeff_cache.words[i] = value.words[i] + elif sel == ModExpNG_NarrowBankEnum.Q: + for i in range(len(value.words)-1): self.q_cache.words[i] = value.words[i] + class ModExpNG_CoreInput(): def __init__(self): @@ -423,6 +546,12 @@ class ModExpNG_BanksPair(): def _get_narrow(self, sel): return self.narrow._get_value(sel) + def _get_wide_cache(self, sel): + return self.wide._get_value_cache(sel) + + def _get_narrow_cache(self, sel): + return self.narrow._get_value_cache(sel) + def _set_wide(self, sel, value): self.wide._set_value(sel, value) @@ -958,7 +1087,7 @@ class ModExpNG_Worker(): c_in = c_out return ModExpNG_Operand(None, 2*ab_num_words, ab) - def multipurpose_multiply(self, a, b, n, n_coeff, ab_num_words, reduce_only=False, multiply_only=False, dump=False, dump_crt="", dump_ladder=""): + def multipurpose_multiply(self, a, b, n, n_coeff, ab_num_words, bnk, reduce_only=False, multiply_only=False, dump=False, dump_crt="", dump_ladder=""): # # 1. AB = A * B @@ -975,6 +1104,10 @@ class ModExpNG_Worker(): if dump and DUMP_VECTORS: ab.format_verilog_concat("%s_%s_AB" % (dump_crt, dump_ladder)) + if not bnk is None: + bnk._set_wide(ModExpNG_WideBankEnum.L, ab.lower_half()) + bnk._set_wide(ModExpNG_WideBankEnum.H, ab.upper_half()) + if multiply_only: return ModExpNG_Operand(None, 2*ab_num_words, ab_words) @@ -990,6 +1123,12 @@ class ModExpNG_Worker(): if dump and DUMP_VECTORS: q.format_verilog_concat("%s_%s_Q" % (dump_crt, dump_ladder)) + if not bnk is None: + bnk._set_narrow(ModExpNG_NarrowBankEnum.Q, q) + q_words = list(bnk._get_narrow(ModExpNG_NarrowBankEnum.Q).words) + q_words.append(bnk._get_narrow(ModExpNG_NarrowBankEnum.EXT).words[1]) + q = ModExpNG_Operand(None, len(q_words), q_words) + # # 3. M = Q * N # @@ -1066,7 +1205,6 @@ class ModExpNG_Worker(): a.words[x] += carry carry = a.words[x] >> _WORD_WIDTH a.words[x] &= _WORD_MASK - return carry class ModExpNG_Core(): @@ -1076,6 +1214,70 @@ class ModExpNG_Core(): self.inp = ModExpNG_CoreInput() self.out = ModExpNG_CoreOutput() + def _dump_bank_indices(self, n): + print(" ", end='') + for i in range(64): print("[ %3d ] " % i, end='') + print(""); + + def _dump_bank_seps(self, n): + print(" ", end='') + for i in range(64): print(" ------ ", end='') + print(""); + + def _dump_bank_entry_narrow(self, name, op, val, n): + print("%s.NARROW.%s " % (name, op), end='') + for i in range(n): + if i < len(val.words) and not val is None: + print("0x%05x " % val.words[i], end='') + continue + print("0xxxxxx ", end='') + print("") + + def _dump_bank_entry_wide(self, name, op, val, n): + print("%s.WIDE.%s " % (name, op), end='') + for i in range(n): + if i < len(val.words) and not val is None: + print("0x%05x " % val.words[i], end='') + else: + print("0xxxxxx ", end='') + print("") + + def _dump_bank(self, name, banks_pair): + + n = KEY_LENGTH // _WORD_WIDTH + + self._dump_bank_indices(n) + + self._dump_bank_entry_wide(name, "A: ", banks_pair._get_wide_cache(W.A), n) + self._dump_bank_entry_wide(name, "B: ", banks_pair._get_wide_cache(W.B), n) + self._dump_bank_entry_wide(name, "C: ", banks_pair._get_wide_cache(W.C), n) + self._dump_bank_entry_wide(name, "D: ", banks_pair._get_wide_cache(W.D), n) + self._dump_bank_entry_wide(name, "E: ", banks_pair._get_wide_cache(W.E), n) + self._dump_bank_entry_wide(name, "N: ", banks_pair._get_wide_cache(W.N), n) + self._dump_bank_entry_wide(name, "L: ", banks_pair._get_wide_cache(W.L), n) + self._dump_bank_entry_wide(name, "H: ", banks_pair._get_wide_cache(W.H), n) + + self._dump_bank_seps(n) + + self._dump_bank_entry_narrow(name, "A: ", banks_pair._get_narrow_cache(N.A), n) + self._dump_bank_entry_narrow(name, "B: ", banks_pair._get_narrow_cache(N.B), n) + self._dump_bank_entry_narrow(name, "C: ", banks_pair._get_narrow_cache(N.C), n) + self._dump_bank_entry_narrow(name, "D: ", banks_pair._get_narrow_cache(N.D), n) + self._dump_bank_entry_narrow(name, "E: ", banks_pair._get_narrow_cache(N.E), n) + self._dump_bank_entry_narrow(name, "COEFF:", banks_pair._get_narrow_cache(N.N_COEFF), n) + self._dump_bank_entry_narrow(name, "Q: ", banks_pair._get_narrow_cache(N.Q), n) + self._dump_bank_entry_narrow(name, "EXT: ", banks_pair._get_narrow(N.EXT), n) + + def dump_banks(self): + + print("OPCODE == STOP: BANKS DUMP FOLLOWS") + self._dump_bank("X.X", self.bnk.crt_x.ladder_x) + self._dump_bank("X.Y", self.bnk.crt_x.ladder_y) + self._dump_bank("Y.X", self.bnk.crt_y.ladder_x) + self._dump_bank("Y.Y", self.bnk.crt_y.ladder_y) + sys.exit() + + # # CRT_(X|Y) means either CRT_X or CRT_Y # LADDER_{X,Y} means both LADDER_X and LADDER_Y @@ -1084,10 +1286,16 @@ class ModExpNG_Core(): # # copy from CRT_(X|Y).LADDER_X.NARROW to OUTPUT # - def set_output_from_narrow(self, sel_output, bank_crt, sel_narrow): + def set_output_from_narrow_x(self, sel_output, bank_crt, sel_narrow): self.out._set_value(sel_output, bank_crt.ladder_x._get_narrow(sel_narrow)) # + # copy from CRT_(X|Y).LADDER_Y.NARROW to OUTPUT + # + def set_output_from_narrow_y(self, sel_output, bank_crt, sel_narrow): + self.out._set_value(sel_output, bank_crt.ladder_y._get_narrow(sel_narrow)) + + # # copy from INPUT to CRT_(X|Y).LADDER_{X,Y}.NARROW # def set_narrow_from_input(self, bank_crt, sel_narrow, sel_input): @@ -1124,17 +1332,6 @@ class ModExpNG_Core(): self.bnk.crt_y.ladder_y._set_narrow(sel_narrow_out, self.bnk.crt_y.ladder_x._get_narrow(sel_narrow_in)) # - # copy from CRT_{X,Y}.LADDER_Y.{WIDE,NARROW} to CRT_{X,Y}.LADDER_X.{WIDE,NARROW} - # - def copy_ladders_y2x(self, sel_wide_in, sel_narrow_in, sel_wide_out, sel_narrow_out): - - self.bnk.crt_x.ladder_x._set_wide(sel_wide_out, self.bnk.crt_x.ladder_y._get_wide(sel_wide_in)) - self.bnk.crt_y.ladder_x._set_wide(sel_wide_out, self.bnk.crt_y.ladder_y._get_wide(sel_wide_in)) - - self.bnk.crt_x.ladder_x._set_narrow(sel_narrow_out, self.bnk.crt_x.ladder_y._get_narrow(sel_narrow_in)) - self.bnk.crt_y.ladder_x._set_narrow(sel_narrow_out, self.bnk.crt_y.ladder_y._get_narrow(sel_narrow_in)) - - # # copy from CRT_{X,Y}.LADDER_X.{WIDE,NARROW} to CRT_{Y,X}.LADDER_Y.{WIDE,NARROW} # def cross_ladders_x2y(self, sel_wide_in, sel_narrow_in, sel_wide_out, sel_narrow_out): @@ -1157,8 +1354,14 @@ class ModExpNG_Core(): xn = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.N) yn = self.bnk.crt_y.ladder_x._get_wide(ModExpNG_WideBankEnum.N) - xn_coeff = self.bnk.crt_x.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.N_COEFF) - yn_coeff = self.bnk.crt_y.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.N_COEFF) + xn_coeff_words = list(self.bnk.crt_x.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.N_COEFF).words) + yn_coeff_words = list(self.bnk.crt_y.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.N_COEFF).words) + + xn_coeff_words.append(self.bnk.crt_x.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.EXT).words[0]) + yn_coeff_words.append(self.bnk.crt_y.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.EXT).words[0]) + + xn_coeff = ModExpNG_Operand(None, len(xn_coeff_words), xn_coeff_words) + yn_coeff = ModExpNG_Operand(None, len(yn_coeff_words), yn_coeff_words) xxa = self.bnk.crt_x.ladder_x._get_wide(sel_wide_in) xya = self.bnk.crt_x.ladder_y._get_wide(sel_wide_in) @@ -1178,11 +1381,11 @@ class ModExpNG_Core(): if not mode[1]: yb = yxb else: yb = yyb - xxp = self.wrk.multipurpose_multiply(xxa, xb, xn, xn_coeff, num_words, dump=d, dump_crt="X", dump_ladder="X") - xyp = self.wrk.multipurpose_multiply(xya, xb, xn, xn_coeff, num_words, dump=d, dump_crt="X", dump_ladder="Y") + xxp = self.wrk.multipurpose_multiply(xxa, xb, xn, xn_coeff, num_words, self.bnk.crt_x.ladder_x, dump=d, dump_crt="X", dump_ladder="X") + xyp = self.wrk.multipurpose_multiply(xya, xb, xn, xn_coeff, num_words, self.bnk.crt_x.ladder_y, dump=d, dump_crt="X", dump_ladder="Y") - yxp = self.wrk.multipurpose_multiply(yxa, yb, yn, yn_coeff, num_words, dump=d, dump_crt="Y", dump_ladder="X") - yyp = self.wrk.multipurpose_multiply(yya, yb, yn, yn_coeff, num_words, dump=d, dump_crt="Y", dump_ladder="Y") + yxp = self.wrk.multipurpose_multiply(yxa, yb, yn, yn_coeff, num_words, self.bnk.crt_y.ladder_x, dump=d, dump_crt="Y", dump_ladder="X") + yyp = self.wrk.multipurpose_multiply(yya, yb, yn, yn_coeff, num_words, self.bnk.crt_y.ladder_y, dump=d, dump_crt="Y", dump_ladder="Y") self.bnk.crt_x.ladder_x._set_wide(sel_wide_out, xxp) self.bnk.crt_x.ladder_y._set_wide(sel_wide_out, xyp) @@ -1212,10 +1415,14 @@ class ModExpNG_Core(): yd = self.wrk.serial_subtract_modular(ya, yb, yn, num_words) self.bnk.crt_x.ladder_x._set_narrow(sel_narrow_out, xd) + self.bnk.crt_x.ladder_y._set_narrow(sel_narrow_out, xd) self.bnk.crt_y.ladder_x._set_narrow(sel_narrow_out, yd) + self.bnk.crt_y.ladder_y._set_narrow(sel_narrow_out, yd) self.bnk.crt_x.ladder_x._set_wide(sel_wide_out, xd) + self.bnk.crt_x.ladder_y._set_wide(sel_wide_out, xd) self.bnk.crt_y.ladder_x._set_wide(sel_wide_out, yd) + self.bnk.crt_y.ladder_y._set_wide(sel_wide_out, yd) # # modular reduce sel_narrow_in @@ -1226,34 +1433,56 @@ class ModExpNG_Core(): xn = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.N) yn = self.bnk.crt_y.ladder_x._get_wide(ModExpNG_WideBankEnum.N) - xn_coeff = self.bnk.crt_x.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.N_COEFF) - yn_coeff = self.bnk.crt_y.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.N_COEFF) + xn_coeff_words = list(self.bnk.crt_x.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.N_COEFF).words) + yn_coeff_words = list(self.bnk.crt_y.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.N_COEFF).words) + + xn_coeff_words.append(self.bnk.crt_x.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.EXT).words[0]) + yn_coeff_words.append(self.bnk.crt_y.ladder_x._get_narrow(ModExpNG_NarrowBankEnum.EXT).words[0]) - xb = self.bnk.crt_x.ladder_x._get_narrow(sel_narrow_in) - yb = self.bnk.crt_y.ladder_x._get_narrow(sel_narrow_in) + xn_coeff = ModExpNG_Operand(None, len(xn_coeff_words), xn_coeff_words) + yn_coeff = ModExpNG_Operand(None, len(yn_coeff_words), yn_coeff_words) + + xxb = self.bnk.crt_x.ladder_x._get_narrow(sel_narrow_in) + xyb = self.bnk.crt_x.ladder_y._get_narrow(sel_narrow_in) + yxb = self.bnk.crt_y.ladder_x._get_narrow(sel_narrow_in) + yyb = self.bnk.crt_y.ladder_y._get_narrow(sel_narrow_in) - xp = self.wrk.multipurpose_multiply(None, xb, xn, xn_coeff, num_words, reduce_only=True) - yp = self.wrk.multipurpose_multiply(None, yb, yn, yn_coeff, num_words, reduce_only=True) + xxp = self.wrk.multipurpose_multiply(None, xxb, xn, xn_coeff, num_words, self.bnk.crt_x.ladder_x, reduce_only=True) + xyp = self.wrk.multipurpose_multiply(None, xyb, xn, xn_coeff, num_words, self.bnk.crt_x.ladder_y, reduce_only=True) + yxp = self.wrk.multipurpose_multiply(None, yxb, yn, yn_coeff, num_words, self.bnk.crt_y.ladder_x, reduce_only=True) + yyp = self.wrk.multipurpose_multiply(None, yyb, yn, yn_coeff, num_words, self.bnk.crt_y.ladder_y, reduce_only=True) - self.bnk.crt_x.ladder_x._set_wide(sel_wide_out, xp) - self.bnk.crt_x.ladder_y._set_wide(sel_wide_out, xp) - self.bnk.crt_y.ladder_x._set_wide(sel_wide_out, yp) - self.bnk.crt_y.ladder_y._set_wide(sel_wide_out, yp) + self.bnk.crt_x.ladder_x._set_wide(sel_wide_out, xxp) + self.bnk.crt_x.ladder_y._set_wide(sel_wide_out, xyp) + self.bnk.crt_y.ladder_x._set_wide(sel_wide_out, yxp) + self.bnk.crt_y.ladder_y._set_wide(sel_wide_out, yyp) - self.bnk.crt_x.ladder_x._set_narrow(sel_narrow_out, xp) - self.bnk.crt_x.ladder_y._set_narrow(sel_narrow_out, xp) - self.bnk.crt_y.ladder_x._set_narrow(sel_narrow_out, yp) - self.bnk.crt_y.ladder_y._set_narrow(sel_narrow_out, yp) + self.bnk.crt_x.ladder_x._set_narrow(sel_narrow_out, xxp) + self.bnk.crt_x.ladder_y._set_narrow(sel_narrow_out, xyp) + self.bnk.crt_y.ladder_x._set_narrow(sel_narrow_out, yxp) + self.bnk.crt_y.ladder_y._set_narrow(sel_narrow_out, yyp) # # propagate carries (convert to non-redundant representation) content in sel_narrow # overwrites input value # def propagate_carries(self, sel_narrow, num_words): - self.wrk.convert_nonredundant(self.bnk.crt_x.ladder_x._get_narrow(sel_narrow), num_words) - self.wrk.convert_nonredundant(self.bnk.crt_x.ladder_y._get_narrow(sel_narrow), num_words) - self.wrk.convert_nonredundant(self.bnk.crt_y.ladder_x._get_narrow(sel_narrow), num_words) - self.wrk.convert_nonredundant(self.bnk.crt_y.ladder_y._get_narrow(sel_narrow), num_words) + + xx = self.bnk.crt_x.ladder_x._get_narrow(sel_narrow) + xy = self.bnk.crt_x.ladder_y._get_narrow(sel_narrow) + yx = self.bnk.crt_y.ladder_x._get_narrow(sel_narrow) + yy = self.bnk.crt_y.ladder_y._get_narrow(sel_narrow) + + self.wrk.convert_nonredundant(xx, num_words) + self.wrk.convert_nonredundant(xy, num_words) + self.wrk.convert_nonredundant(yx, num_words) + self.wrk.convert_nonredundant(yy, num_words) + + self.bnk.crt_x.ladder_x._set_narrow(sel_narrow, xx) + self.bnk.crt_x.ladder_y._set_narrow(sel_narrow, xy) + self.bnk.crt_y.ladder_x._set_narrow(sel_narrow, yx) + self.bnk.crt_y.ladder_y._set_narrow(sel_narrow, yy) + # # copy from CRT_{X,Y}.LADDER_{X,Y}.WIDE.{H,L} to CRT_{X,Y}.LADDER_{X,Y}.NARROW @@ -1300,11 +1529,11 @@ class ModExpNG_Core(): xb = self.bnk.crt_x.ladder_x._get_narrow(sel_narrow_in) yb = self.bnk.crt_y.ladder_x._get_narrow(sel_narrow_in) - xxp = self.wrk.multipurpose_multiply(xxa, xb, None, None, num_words, multiply_only=True) - xyp = self.wrk.multipurpose_multiply(xya, xb, None, None, num_words, multiply_only=True) + xxp = self.wrk.multipurpose_multiply(xxa, xb, None, None, num_words, None, multiply_only=True) + xyp = self.wrk.multipurpose_multiply(xya, xb, None, None, num_words, None, multiply_only=True) - yxp = self.wrk.multipurpose_multiply(yxa, yb, None, None, num_words, multiply_only=True) - yyp = self.wrk.multipurpose_multiply(yya, yb, None, None, num_words, multiply_only=True) + yxp = self.wrk.multipurpose_multiply(yxa, yb, None, None, num_words, None, multiply_only=True) + yyp = self.wrk.multipurpose_multiply(yya, yb, None, None, num_words, None, multiply_only=True) xxp_lsb = xxp.lower_half() xxp_msb = xxp.upper_half() @@ -1475,7 +1704,6 @@ def sign_using_crt(): v = vector n = n_num_words pq = pq_num_words - ff = (False, False) # # A / B => different content in banks (A in WIDE, B in NARROW) @@ -1499,19 +1727,19 @@ def sign_using_crt(): c.set_narrow_from_input (c.bnk.crt_y, N.A, I.N_FACTOR) # | [XY] / N_FACTOR | ? | ? | ? | M / ? | c.set_narrow_from_input (c.bnk.crt_x, N.E, I.M) # | [XY] / N_FACTOR | ? | ? | ? | M / .. | c.set_narrow_from_input (c.bnk.crt_y, N.E, I.M) # | [XY] / N_FACTOR | ? | ? | ? | M | - # +------------------------+-------+------------------+---------+-----------+ + # +------------------------+-------+------------------+---------+-----------+ c.modular_multiply(W.A, N.A, W.B, N.B, n) # | [XY] / N_FACTOR | [XY]F | ? | ? | M | [XY]F = [XY] * N_FACTOR - c.modular_multiply(W.B, N.B, W.C, N.C, n, mode=ff) # | [XY] / N_FACTOR | [XY]F | [XY]YM | ? | M | [XY]MF = [XY]F * [XY]F + c.modular_multiply(W.B, N.B, W.C, N.C, n) # | [XY] / N_FACTOR | [XY]F | [XY]YM | ? | M | [XY]MF = [XY]F * [XY]F c.modular_multiply(W.C, N.I, W.D, N.D, n) # | [XY] / N_FACTOR | [XY]F | [XY]YM | [XY]M | M | [XY]M = [XY]MF * 1 + # +------------------------+-------+------------------+---------+-----------+ + c.propagate_carries(N.D, n) # | [XY] / N_FACTOR | [XY]F | [XY]YM | [XY]M | M | # +------------------------+-------+------------------+---------+-----------+ - c.propagate_carries(N.D, n_num_words) # | [XY] / N_FACTOR | [XY]F | [XY]YM | [XY]M | M | - # +------------------------+-------+------------------+---------+-----------+ - c.set_output_from_narrow(O.XM, c.bnk.crt_x, N.D) # | [XY] / N_FACTOR | [XY]F | [XY]YM | [XY]M | M | - c.set_output_from_narrow(O.YM, c.bnk.crt_y, N.D) # | [XY] / N_FACTOR | [XY]F | [XY]YM | [XY]M | M | + c.set_output_from_narrow_x(O.XM, c.bnk.crt_x, N.D) # | [XY] / N_FACTOR | [XY]F | [XY]YM | [XY]M | M | + c.set_output_from_narrow_x(O.YM, c.bnk.crt_y, N.D) # | [XY] / N_FACTOR | [XY]F | [XY]YM | [XY]M | M | # +------------------------+-------+------------------+---------+-----------+ c.modular_multiply(W.E, N.B, W.C, N.C, n) # | [XY] / N_FACTOR | [XY]F | [XY]MB | [XY]M | M | [XY]MB = M * [XY]F # +------------------------+-------+------------------+---------+-----------+ - c.propagate_carries(N.C, n_num_words) # | [XY] / N_FACTOR | [XY]F | [XY]MB | [XY]M | M | + c.propagate_carries(N.C, n) # | [XY] / N_FACTOR | [XY]F | [XY]MB | [XY]M | M | # +------------------------+-------+------------------+---------+-----------+ c.copy_crt_y2x(W.C, N.C) # | [XY] / N_FACTOR | [XY]F | YMB | [XY]M | M | # +------------------------+-------+------------------+---------+-----------+ @@ -1519,17 +1747,16 @@ def sign_using_crt(): c.set_wide_from_input (c.bnk.crt_y, W.N, I.Q) # | [XY] / N_FACTOR | [XY]F | YMB | [XY]M | M | c.set_wide_from_input (c.bnk.crt_x, W.A, I.P_FACTOR) # | ... / N_FACTOR | [XY]F | YMB | [XY]M | M | c.set_wide_from_input (c.bnk.crt_y, W.A, I.Q_FACTOR) # | [PQ]_FACTOR / N_FACTOR | [XY]F | YMB | [XY]M | M | - c.set_wide_from_input (c.bnk.crt_x, W.E, I.QINV) # | [PQ]_FACTOR / N_FACTOR | [XY]F | YMB | [XY]M | .. | c.set_wide_from_input (c.bnk.crt_x, W.E, I.QINV) # | [PQ]_FACTOR / N_FACTOR | [XY]F | YMB | [XY]M | QINV / M | # +------------------------+-------+------------------+---------+-----------+ c.set_narrow_from_input(c.bnk.crt_x, N.N_COEFF, I.P_COEFF) # | [PQ]_FACTOR / N_FACTOR | [XY]F | YMB | [XY]M | QINV / M | c.set_narrow_from_input(c.bnk.crt_y, N.N_COEFF, I.Q_COEFF) # | [PQ]_FACTOR / N_FACTOR | [XY]F | YMB | [XY]M | QINV / M | c.set_narrow_from_input(c.bnk.crt_x, N.A, I.P_FACTOR) # | [PQ]_FACTOR / ... | [XY]F | YMB | [XY]M | QINV / M | c.set_narrow_from_input(c.bnk.crt_y, N.A, I.Q_FACTOR) # | [PQ]_FACTOR | [XY]F | YMB | [XY]M | QINV / M | - c.set_narrow_from_input(c.bnk.crt_x, N.E, I.QINV) # | [PQ]_FACTOR | [XY]F | YMB | [XY]M | QINV / .. | c.set_narrow_from_input(c.bnk.crt_x, N.E, I.QINV) # | [PQ]_FACTOR | [XY]F | YMB | [XY]M | QINV | - # +------------------------+-------+------------------+---------+-----------+ + # +------------------------+-------+------------------+---------+-----------+ c.modular_reduce(N.C, W.D, N.D, pq) # | [PQ]_FACTOR | [XY]F | YMB | [PQ]MBZ | QINV | [PQ]MBZ = YMB mod [PQ] + # +------------------------+-------+------------------+---------+-----------+ c.modular_multiply(W.D, N.A, W.C, N.C, pq) # | [PQ]_FACTOR | [XY]F | [PQ]MB | [PQ]MBZ | QINV | [PQ]MB = [PQ]MBZ * [PQ]_FACTOR c.modular_multiply(W.C, N.A, W.D, N.D, pq) # | [PQ]_FACTOR | [XY]F | [PQ]MB | [PQ]MBF | QINV | [PQ]MBF = [PQ]MB * [PQ]_FACTOR c.modular_multiply(W.A, N.I, W.C, N.C, pq) # | [PQ]_FACTOR | [XY]F | [PQ]IF | [PQ]MBF | QINV | [PQ]IF = 1 * [PQ]_FACTOR @@ -1541,7 +1768,6 @@ def sign_using_crt(): ########################### # | | | | | | # | | | | | | for bit in range(_WORD_WIDTH * pq - 1, -1, -1): # | | | | | | - # | | | | | | m = get_ladder_mode_using_crt(v, bit) # | | | | | | dbg = bit == DUMP_LADDER_INDEX # | | | | | | # | | | | | | @@ -1569,21 +1795,19 @@ def sign_using_crt(): c.modular_multiply(W.C, N.E, W.C, N.C, pq) # | [PQ]_FACTOR | [XY]F | RSBIZ | [PQ]SB* | QINV | RSBIZ = RSB * QINV c.modular_multiply(W.C, N.A, W.C, N.C, pq) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB* | QINV | RSBI = RSBIZ * P_FACTOR # +------------------------+-------+------------------+---------+-----------+ - c.set_wide_from_input (c.bnk.crt_x, W.E, I.Q) # | [PQ]_FACTOR / N_FACTOR | [XY]F | RSBI | [PQ]SB* | .. | - c.set_wide_from_input (c.bnk.crt_x, W.E, I.Q) # | [PQ]_FACTOR / N_FACTOR | [XY]F | RSBI | [PQ]SB* | Q / QINV | + c.set_wide_from_input (c.bnk.crt_x, W.E, I.Q) # | [PQ]_FACTOR / N_FACTOR | [XY]F | RSBI | [PQ]SB* | | # +------------------------+-------+------------------+---------+-----------+ - c.set_narrow_from_input(c.bnk.crt_x, N.E, I.Q) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB* | Q / .. | - c.set_narrow_from_input(c.bnk.crt_x, N.E, I.Q) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB* | Q | + c.set_narrow_from_input(c.bnk.crt_x, N.E, I.Q) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB* | | # +------------------------+-------+------------------+---------+-----------+ - c.regular_multiply(W.E, N.C, pq) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB* | Q | = RSBI * Q + c.regular_multiply(W.E, N.C, pq) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB* | | = RSBI * Q # +------------------------+-------+------------------+---------+-----------+ - c.merge_lha(N.A, pq) # | [PQ]_FACTOR / QRSBI | [XY]F | RSBI | [PQ]SB* | Q | + c.merge_lha(N.A, pq) # | [PQ]_FACTOR / QRSBI | [XY]F | RSBI | [PQ]SB* | | # +------------------------+-------+------------------+---------+-----------+ - c.propagate_carries(N.A, n) # | [PQ]_FACTOR / QRSBI | [XY]F | RSBI | [PQ]SB* | Q | + c.propagate_carries(N.A, n) # | [PQ]_FACTOR / QRSBI | [XY]F | RSBI | [PQ]SB* | | # +------------------------+-------+------------------+---------+-----------+ - c.copy_crt_y2x(W.D, N.D) # | [PQ]_FACTOR / QRSBI | [XY]F | RSBI | QSB* | Q | + c.copy_crt_y2x(W.D, N.D) # | [PQ]_FACTOR / QRSBI | [XY]F | RSBI | QSB* | | # +------------------------+-------+------------------+---------+-----------+ - c.regular_add(N.D, N.A, N.C, pq) # | [PQ]_FACTOR / QRSBI | [XY]F | SB | QSB* | Q | SB = QSB + RSBI + c.regular_add(N.D, N.A, N.C, pq) # | [PQ]_FACTOR / QRSBI | [XY]F | SB | QSB* | | SB = QSB + RSBI # +------------------------+-------+------------------+---------+-----------+ c.set_wide_from_input (c.bnk.crt_x, W.N, I.N) # | | | | | | c.set_wide_from_input (c.bnk.crt_y, W.N, I.N) # | | | | | | @@ -1595,8 +1819,10 @@ def sign_using_crt(): # +------------------------+-------+------------------+---------+-----------+ c.propagate_carries(N.A, n) # | S | | | | | # +------------------------+-------+------------------+---------+-----------+ - c.set_output_from_narrow(O.S, c.bnk.crt_x, N.A) # | S | | | | | + c.set_output_from_narrow_x(O.S, c.bnk.crt_x, N.A) # | S | | | | | # +------------------------+-------+------------------+---------+-----------+ + #c.dump_banks() + # # try to exponentiate using only half of the quad-multiplier (one dual-ladder core) @@ -1623,19 +1849,17 @@ def sign_without_crt(): c.set_narrow_from_input (c.bnk.crt_x, N.E, I.M) c.set_narrow_from_input (c.bnk.crt_y, N.E, I.M) - c.modular_multiply(W.A, N.A, W.B, N.B, n) # [XY]F = [XY] * N_FACTOR - c.modular_multiply(W.B, N.B, W.C, N.C, n, mode=ff) # [XY]MF = [XY]F * [XY]F - c.modular_multiply(W.C, N.I, W.D, N.D, n) # [XY]M = [XY]MF * 1 + c.modular_multiply(W.A, N.A, W.B, N.B, n) # [XY]F = [XY] * N_FACTOR + c.modular_multiply(W.B, N.B, W.C, N.C, n) # [XY]MF = [XY]F * [XY]F + c.modular_multiply(W.C, N.I, W.D, N.D, n) # [XY]M = [XY]MF * 1 c.propagate_carries(N.D, n) - c.set_output_from_narrow(O.XM, c.bnk.crt_x, N.D) - c.set_output_from_narrow(O.YM, c.bnk.crt_y, N.D) + c.set_output_from_narrow_x(O.XM, c.bnk.crt_x, N.D) + c.set_output_from_narrow_x(O.YM, c.bnk.crt_y, N.D) c.modular_multiply(W.E, N.B, W.C, N.C, n) # [XY]MB = M * [XY]F - XF = c.bnk.crt_x.ladder_x._get_narrow(N.B) - c.set_wide_from_input(c.bnk.crt_x, W.A, I.N_FACTOR) c.set_wide_from_input(c.bnk.crt_y, W.A, I.N_FACTOR) @@ -1670,13 +1894,12 @@ def sign_without_crt(): c.modular_multiply(W.C, N.I, W.D, N.D, n) # SB = SBF * 1 c.modular_multiply(W.B, N.D, W.A, N.A, n, mode=ff) # S = XF * SB - - c.copy_ladders_y2x(W.A, N.A, W.B, N.B) - c.propagate_carries(N.B, n) + c.propagate_carries(N.A, n) - c.set_output_from_narrow(O.S, c.bnk.crt_y, N.B) + c.set_output_from_narrow_y(O.S, c.bnk.crt_y, N.A) + #c.dump_banks() # # main() @@ -1729,6 +1952,39 @@ if __name__ == "__main__": xm_known = pow(vector.x.number(), 2, vector.n.number()) ym_known = pow(vector.y.number(), 2, vector.n.number()) + if DUMP_VECTORS: + vector.m.format("M") + vector.n.format("N") + vector.n_factor.format("N_FACTOR") + vector.n_coeff.format("N_COEFF") + vector.x.format("X") + vector.y.format("Y") + + vector.p.format("P") + vector.q.format("Q") + + vector.p_factor.format("P_FACTOR") + vector.q_factor.format("Q_FACTOR") + + vector.p_coeff.format("P_COEFF") + vector.q_coeff.format("Q_COEFF") + + vector.d.format("D") + + vector.dp.format("DP") + vector.dq.format("DQ") + + vector.qinv.format("QINV") + + xm_known_operand = ModExpNG_Operand(xm_known, KEY_LENGTH) + ym_known_operand = ModExpNG_Operand(ym_known, KEY_LENGTH) + s_known_operand = ModExpNG_Operand(s_known, KEY_LENGTH) + + xm_known_operand.format("XM") + ym_known_operand.format("YM") + s_known_operand.format("S") + + # sign using CRT and check print("Signing using CRT...") sign_using_crt() diff --git a/vector/README.md b/vector/README.md index 3bd1853..977f207 100644 --- a/vector/README.md +++ b/vector/README.md @@ -1,5 +1,5 @@ -ModExpNG -======== +modexpng_fpga_model / vector +============================ Ranzomized test vector generation scripts for ModExpNG core model. diff --git a/vector/vector_format.py b/vector/vector_format.py index a3e7e81..7f11689 100644 --- a/vector/vector_format.py +++ b/vector/vector_format.py @@ -39,7 +39,7 @@ import vector_util SCRIPT_USAGE = "USAGE: vector_format.py [openssl_binary]" -KEY_LENGTH = 1024 +KEY_LENGTH = 512 RNG_SEED_MESSAGE = 1 RNG_SEED_BLINDING = 2 diff --git a/vector/vector_regenerate.py b/vector/vector_regenerate.py index 34c6384..b8a9373 100644 --- a/vector/vector_regenerate.py +++ b/vector/vector_regenerate.py @@ -38,7 +38,7 @@ import vector_util SCRIPT_USAGE = "USAGE: vector_regenerate.py [openssl_binary]" -KEY_LENGTH = 1024 +KEY_LENGTH = 512 if __name__ == "__main__": |