aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modexpng_fpga_model.py450
-rw-r--r--vector/README.md4
-rw-r--r--vector/vector_format.py2
-rw-r--r--vector/vector_regenerate.py2
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__":