aboutsummaryrefslogtreecommitdiff
path: root/modexpng_fpga_model.py
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-08-19 13:57:12 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-08-19 13:57:12 +0300
commita5200cd8af68cca49978bfa023b704ad5431eae1 (patch)
tree964056fcc1054ae19e6b59f755895776d5f9686a /modexpng_fpga_model.py
parent66be583469258524ada60db7c7d134329f7f4dd1 (diff)
* Added more micro-operations
* Working microcode for CRT exponentiation * Further refactoring
Diffstat (limited to 'modexpng_fpga_model.py')
-rw-r--r--modexpng_fpga_model.py372
1 files changed, 295 insertions, 77 deletions
diff --git a/modexpng_fpga_model.py b/modexpng_fpga_model.py
index 4ef6576..f57c7b9 100644
--- a/modexpng_fpga_model.py
+++ b/modexpng_fpga_model.py
@@ -160,7 +160,18 @@ class ModExpNG_Operand():
ret += word << shift
shift += _WORD_WIDTH
return ret
-
+
+ def _get_half(self, part):
+ num_words = len(self.words)
+ num_words_half = num_words // 2
+ if not part: return ModExpNG_Operand(None, num_words_half, self.words[:num_words_half])
+ else: return ModExpNG_Operand(None, num_words_half, self.words[num_words_half:])
+
+ def lower_half(self):
+ return self._get_half(False)
+
+ def upper_half(self):
+ return self._get_half(True)
#
# Test Vector
@@ -209,6 +220,8 @@ class ModExpNG_WideBankEnum(Enum):
D = auto()
E = auto()
N = auto()
+ L = auto()
+ H = auto()
class ModExpNG_NarrowBankEnum(Enum):
A = auto()
@@ -222,12 +235,14 @@ class ModExpNG_NarrowBankEnum(Enum):
class ModExpNG_WideBank():
def __init__(self):
- self.a = None
- self.b = None
- self.c = None
- self.d = None
- self.e = None
- self.n = None
+ self.a = None
+ self.b = None
+ self.c = None
+ self.d = None
+ self.e = None
+ self.n = None
+ self.l = None
+ self.h = None
def _get_value(self, sel):
if sel == ModExpNG_WideBankEnum.A: return self.a
@@ -236,6 +251,8 @@ class ModExpNG_WideBank():
elif sel == ModExpNG_WideBankEnum.D: return self.d
elif sel == ModExpNG_WideBankEnum.E: return self.e
elif sel == ModExpNG_WideBankEnum.N: return self.n
+ elif sel == ModExpNG_WideBankEnum.L: return self.l
+ elif sel == ModExpNG_WideBankEnum.H: return self.h
else: raise Exception("ModExpNG_WideBank._get_value(): Invalid selector!")
def _set_value(self, sel, value):
@@ -245,6 +262,8 @@ class ModExpNG_WideBank():
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
else: raise Exception("ModExpNG_WideBank._set_value(): Invalid selector!")
class ModExpNG_NarrowBank():
@@ -283,11 +302,17 @@ class ModExpNG_BanksPair():
self.wide = ModExpNG_WideBank()
self.narrow = ModExpNG_NarrowBank(i)
- def _get_value_wide(self, sel):
+ def _get_wide(self, sel):
return self.wide._get_value(sel)
- def _get_value_narrow(self, sel):
+ def _get_narrow(self, sel):
return self.narrow._get_value(sel)
+
+ def _set_wide(self, sel, value):
+ self.wide._set_value(sel, value)
+
+ def _set_narrow(self, sel, value):
+ self.narrow._set_value(sel, value)
class ModExpNG_BanksLadder():
@@ -301,12 +326,12 @@ class ModExpNG_BanksLadder():
self.ladder_x.narrow._set_value(ModExpNG_NarrowBankEnum.N_COEFF, n_coeff)
self.ladder_y.narrow._set_value(ModExpNG_NarrowBankEnum.N_COEFF, n_coeff)
- def set_operand(self, sel_wide, sel_narrow, x, y):
+ def set_operands_crt_xy(self, sel_wide, sel_narrow, x, y):
if sel_wide is not None:
self.ladder_x.wide._set_value(sel_wide, x)
- self.ladder_y.wide._set_value(sel_wide, y)
+ self.ladder_y.wide._set_value(sel_wide, x)
if sel_narrow is not None:
- self.ladder_x.narrow._set_value(sel_narrow, x)
+ self.ladder_x.narrow._set_value(sel_narrow, y)
self.ladder_y.narrow._set_value(sel_narrow, y)
class ModExpNG_BanksCRT():
@@ -814,9 +839,20 @@ class ModExpNG_Worker():
# length-1, length-2, length-3, ..., 1, 0 (left-to-right)
for bit in range(_WORD_WIDTH * num_words - 1, -1, -1):
+ bit_value = (e.number() & (1 << bit)) >> bit
+
+ if bit > 500:
+ print("%s: bit=#%d (%d)" % (dump_mode, bit, bit_value))
+ print("")
+ print("%s_T1_BEFORE: %s" % (dump_mode, hex(t1.number())))
+ print("%s_T2_BEFORE: %s" % (dump_mode, hex(t2.number())))
+ print("")
+ else:
+ return None
+
+
debug_dump = bit == dump_index
- bit_value = (e.number() & (1 << bit)) >> bit
if debug_dump:
print("\rladder_mode = %d" % bit_value)
@@ -855,7 +891,7 @@ class ModExpNG_Worker():
t1.format_verilog_concat("%s_X" % dump_mode)
t2.format_verilog_concat("%s_Y" % dump_mode)
- if (bit % 8) == 0:
+ if (bit % 16) == 0:
pct = float((_WORD_WIDTH * num_words - bit) / (_WORD_WIDTH * num_words)) * 100.0
print("\rpct: %5.1f%%" % pct, end='')
@@ -913,7 +949,7 @@ class ModExpNG_Worker():
if dump: print("multiply_square(%s_%s)" % (dump_mode, dump_phase))
if reduce_only:
- ab = a
+ ab = b
else:
ab_parts = self.multiplier.multiply_square(a, b, ab_num_words, dump)
ab_words = self.recombinator.recombine_square(ab_parts, ab_num_words, dump)
@@ -1000,12 +1036,13 @@ class ModExpNG_Worker():
return ModExpNG_Operand(None, ab_num_words, R)
- def reduce(self, a, num_words):
- carry = 0
+ def reduce(self, a, num_words, carry_in=0):
+ carry = carry_in
for x in range(num_words):
a.words[x] += carry
carry = (a.words[x] >> _WORD_WIDTH) & 3
a.words[x] &= self.lowlevel._word_mask
+ return carry
class ModExpNG_CoreOutputEnum(Enum):
XM = auto()
@@ -1038,7 +1075,7 @@ class ModExpNG_Core():
self.bnk = ModExpNG_BanksCRT(i)
self.out = ModExpNG_CoreOutput()
- def multiply(self, sel_wide_in, sel_narrow_in, sel_wide_out, sel_narrow_out, num_words, mode=(True, True)):
+ def modular_multiply(self, sel_wide_in, sel_narrow_in, sel_wide_out, sel_narrow_out, num_words, mode=(True, True)):
xn = self.bnk.crt_x.ladder_x.wide._get_value(ModExpNG_WideBankEnum.N)
yn = self.bnk.crt_y.ladder_x.wide._get_value(ModExpNG_WideBankEnum.N)
@@ -1082,16 +1119,82 @@ class ModExpNG_Core():
self.bnk.crt_y.ladder_x.narrow._set_value(sel_narrow_out, yxp)
self.bnk.crt_y.ladder_y.narrow._set_value(sel_narrow_out, yyp)
- def simply_reduce(self, sel_narrow, num_words):
+ def modular_subtract(self, sel_narrow_in, sel_narrow_out, sel_wide_out, num_words):
+
+ xa = self.bnk.crt_x.ladder_x.narrow._get_value(sel_narrow_in)
+ xb = self.bnk.crt_x.ladder_y.narrow._get_value(sel_narrow_in)
+ xn = self.bnk.crt_x.ladder_x.wide._get_value(ModExpNG_WideBankEnum.N)
+
+ ya = self.bnk.crt_y.ladder_x.narrow._get_value(sel_narrow_in)
+ yb = self.bnk.crt_y.ladder_y.narrow._get_value(sel_narrow_in)
+ yn = self.bnk.crt_y.ladder_x.wide._get_value(ModExpNG_WideBankEnum.N)
+
+ xd = self.wrk.subtract(xa, xb, xn, num_words)
+ yd = self.wrk.subtract(ya, yb, yn, num_words)
+
+ self.bnk.crt_x.ladder_x.narrow._set_value(sel_narrow_out, xd)
+ self.bnk.crt_y.ladder_x.narrow._set_value(sel_narrow_out, yd)
+
+ self.bnk.crt_x.ladder_x.wide._set_value(sel_wide_out, xd)
+ self.bnk.crt_y.ladder_x.wide._set_value(sel_wide_out, yd)
+
+ def reduce_narrow(self, sel_narrow, num_words):
self.wrk.reduce(self.bnk.crt_x.ladder_x.narrow._get_value(sel_narrow), num_words)
self.wrk.reduce(self.bnk.crt_x.ladder_y.narrow._get_value(sel_narrow), num_words)
self.wrk.reduce(self.bnk.crt_y.ladder_x.narrow._get_value(sel_narrow), num_words)
self.wrk.reduce(self.bnk.crt_y.ladder_y.narrow._get_value(sel_narrow), num_words)
+
+ def merge_lha(self, sel_narrow, num_words):
+ xx_lsb = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.L)
+ xy_lsb = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.L)
+ yx_lsb = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.L)
+ yy_lsb = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.L)
+
+ xx_msb = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.H)
+ xy_msb = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.H)
+ yx_msb = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.H)
+ yy_msb = self.bnk.crt_x.ladder_x._get_wide(ModExpNG_WideBankEnum.H)
+
+ xx = xx_lsb.words + xx_msb.words
+ xy = xy_lsb.words + xy_msb.words
+ yx = yx_lsb.words + yx_msb.words
+ yy = yy_lsb.words + yy_msb.words
+
+ self.bnk.crt_x.ladder_x._set_narrow(sel_narrow, ModExpNG_Operand(None, 2*num_words, xx))
+ self.bnk.crt_x.ladder_y._set_narrow(sel_narrow, ModExpNG_Operand(None, 2*num_words, xy))
+ self.bnk.crt_y.ladder_x._set_narrow(sel_narrow, ModExpNG_Operand(None, 2*num_words, yx))
+ self.bnk.crt_y.ladder_y._set_narrow(sel_narrow, ModExpNG_Operand(None, 2*num_words, yy))
+
+ def modular_reduce(self, sel_narrow_in, sel_wide_out, sel_narrow_out, num_words):
+
+ xn = self.bnk.crt_x.ladder_x.wide._get_value(ModExpNG_WideBankEnum.N)
+ yn = self.bnk.crt_y.ladder_x.wide._get_value(ModExpNG_WideBankEnum.N)
+
+ xn_coeff = self.bnk.crt_x.ladder_x.narrow._get_value(ModExpNG_NarrowBankEnum.N_COEFF)
+ yn_coeff = self.bnk.crt_y.ladder_x.narrow._get_value(ModExpNG_NarrowBankEnum.N_COEFF)
+
+ xb = self.bnk.crt_x.ladder_x.narrow._get_value(sel_narrow_in)
+ yb = self.bnk.crt_y.ladder_x.narrow._get_value(sel_narrow_in)
+ xp = self.wrk.multiply(None, xb, xn, xn_coeff, num_words, reduce_only=True)
+ yp = self.wrk.multiply(None, yb, yn, yn_coeff, num_words, reduce_only=True)
+
+ if sel_wide_out is not None:
+ self.bnk.crt_x.ladder_x.wide._set_value(sel_wide_out, xp)
+ self.bnk.crt_x.ladder_y.wide._set_value(sel_wide_out, xp)
+ self.bnk.crt_y.ladder_x.wide._set_value(sel_wide_out, yp)
+ self.bnk.crt_y.ladder_y.wide._set_value(sel_wide_out, yp)
+
+ if sel_narrow_out is not None:
+ self.bnk.crt_x.ladder_x.narrow._set_value(sel_narrow_out, xp)
+ self.bnk.crt_x.ladder_y.narrow._set_value(sel_narrow_out, xp)
+ self.bnk.crt_y.ladder_x.narrow._set_value(sel_narrow_out, yp)
+ self.bnk.crt_y.ladder_y.narrow._set_value(sel_narrow_out, yp)
+
def set_output(self, sel_output, banks_ladder, sel_narrow):
self.out._set_value(sel_output, banks_ladder.ladder_x.narrow._get_value(sel_narrow))
- def mirror_yx(self, sel_wide, sel_narrow):
+ def move_crt_y2x(self, sel_wide, sel_narrow):
if sel_wide is not None:
self.bnk.crt_x.ladder_x.wide._set_value(sel_wide, self.bnk.crt_y.ladder_x.wide._get_value(sel_wide))
@@ -1100,6 +1203,90 @@ class ModExpNG_Core():
if sel_narrow is not None:
self.bnk.crt_x.ladder_x.narrow._set_value(sel_narrow, self.bnk.crt_y.ladder_x.narrow._get_value(sel_narrow))
self.bnk.crt_x.ladder_y.narrow._set_value(sel_narrow, self.bnk.crt_y.ladder_y.narrow._get_value(sel_narrow))
+
+ def move_ladders_x2y(self, sel_wide_in, sel_narrow_in, sel_wide_out, sel_narrow_out):
+
+ if sel_wide_out is not None:
+ self.bnk.crt_x.ladder_y.wide._set_value(sel_wide_out, self.bnk.crt_x.ladder_x.wide._get_value(sel_wide_in))
+ self.bnk.crt_y.ladder_y.wide._set_value(sel_wide_out, self.bnk.crt_y.ladder_x.wide._get_value(sel_wide_in))
+
+ if sel_narrow_out is not None:
+ self.bnk.crt_x.ladder_y.narrow._set_value(sel_narrow_out, self.bnk.crt_x.ladder_x.narrow._get_value(sel_narrow_in))
+ self.bnk.crt_y.ladder_y.narrow._set_value(sel_narrow_out, self.bnk.crt_y.ladder_x.narrow._get_value(sel_narrow_in))
+
+ def flip_ladder_y2x(self, sel_wide_in, sel_narrow_in, sel_wide_out, sel_narrow_out):
+
+ if sel_wide_out is not None:
+ self.bnk.crt_x.ladder_y.wide._set_value(sel_wide_out, self.bnk.crt_y.ladder_x.wide._get_value(sel_wide_in))
+
+ if sel_narrow_out is not None:
+ self.bnk.crt_x.ladder_y.narrow._set_value(sel_narrow_out, self.bnk.crt_y.ladder_x.narrow._get_value(sel_narrow_in))
+
+ def just_multiply(self, sel_wide_in, sel_narrow_in, num_words):
+
+ xn = self.bnk.crt_x.ladder_x.wide._get_value(ModExpNG_WideBankEnum.N)
+ yn = self.bnk.crt_y.ladder_x.wide._get_value(ModExpNG_WideBankEnum.N)
+
+ xn_coeff = self.bnk.crt_x.ladder_x.narrow._get_value(ModExpNG_NarrowBankEnum.N_COEFF)
+ yn_coeff = self.bnk.crt_y.ladder_x.narrow._get_value(ModExpNG_NarrowBankEnum.N_COEFF)
+
+ xxa = self.bnk.crt_x.ladder_x.wide._get_value(sel_wide_in)
+ xya = self.bnk.crt_x.ladder_y.wide._get_value(sel_wide_in)
+
+ yxa = self.bnk.crt_y.ladder_x.wide._get_value(sel_wide_in)
+ yya = self.bnk.crt_y.ladder_y.wide._get_value(sel_wide_in)
+
+ xb = self.bnk.crt_x.ladder_x.narrow._get_value(sel_narrow_in)
+ yb = self.bnk.crt_y.ladder_x.narrow._get_value(sel_narrow_in)
+
+ xxp = self.wrk.multiply(xxa, xb, None, None, num_words, multiply_only=True)
+ xyp = self.wrk.multiply(xya, xb, None, None, num_words, multiply_only=True)
+
+ yxp = self.wrk.multiply(yxa, yb, None, None, num_words, multiply_only=True)
+ yyp = self.wrk.multiply(yya, yb, None, None, num_words, multiply_only=True)
+
+ xxp_lsb = xxp.lower_half()
+ xxp_msb = xxp.upper_half()
+
+ xyp_lsb = xyp.lower_half()
+ xyp_msb = xyp.upper_half()
+
+ yxp_lsb = yxp.lower_half()
+ yxp_msb = yxp.upper_half()
+
+ yyp_lsb = yyp.lower_half()
+ yyp_msb = yyp.upper_half()
+
+ self.bnk.crt_x.ladder_x.wide._set_value(ModExpNG_WideBankEnum.L, xxp_lsb)
+ self.bnk.crt_x.ladder_y.wide._set_value(ModExpNG_WideBankEnum.L, xyp_lsb)
+ self.bnk.crt_y.ladder_x.wide._set_value(ModExpNG_WideBankEnum.L, yxp_lsb)
+ self.bnk.crt_y.ladder_y.wide._set_value(ModExpNG_WideBankEnum.L, yyp_lsb)
+
+ self.bnk.crt_x.ladder_x.wide._set_value(ModExpNG_WideBankEnum.H, xxp_msb)
+ self.bnk.crt_x.ladder_y.wide._set_value(ModExpNG_WideBankEnum.H, xyp_msb)
+ self.bnk.crt_y.ladder_x.wide._set_value(ModExpNG_WideBankEnum.H, yxp_msb)
+ self.bnk.crt_y.ladder_y.wide._set_value(ModExpNG_WideBankEnum.H, yyp_msb)
+
+ def just_add(self, sel_narrow_a_in, sel_narrow_b_in, sel_narrow_out, num_words):
+ xxa = self.bnk.crt_x.ladder_x._get_narrow(sel_narrow_a_in)
+ xya = self.bnk.crt_x.ladder_y._get_narrow(sel_narrow_a_in)
+ yxa = self.bnk.crt_y.ladder_x._get_narrow(sel_narrow_a_in)
+ yya = self.bnk.crt_y.ladder_y._get_narrow(sel_narrow_a_in)
+
+ xxb = self.bnk.crt_x.ladder_x._get_narrow(sel_narrow_b_in)
+ xyb = self.bnk.crt_x.ladder_y._get_narrow(sel_narrow_b_in)
+ yxb = self.bnk.crt_y.ladder_x._get_narrow(sel_narrow_b_in)
+ yyb = self.bnk.crt_y.ladder_y._get_narrow(sel_narrow_b_in)
+
+ xxc = self.wrk.add(xxa, xxb, num_words)
+ xyc = self.wrk.add(xya, xyb, num_words)
+ yxc = self.wrk.add(yxa, yxb, num_words)
+ yyc = self.wrk.add(yya, yyb, num_words)
+
+ self.bnk.crt_x.ladder_x._set_narrow(sel_narrow_out, xxc)
+ self.bnk.crt_x.ladder_y._set_narrow(sel_narrow_out, xyc)
+ self.bnk.crt_y.ladder_x._set_narrow(sel_narrow_out, yxc)
+ self.bnk.crt_y.ladder_y._set_narrow(sel_narrow_out, yyc)
if __name__ == "__main__":
@@ -1149,78 +1336,109 @@ if __name__ == "__main__":
core.bnk.crt_x.set_modulus(vector.n, vector.n_coeff)
core.bnk.crt_y.set_modulus(vector.n, vector.n_coeff)
- core.bnk.crt_x.set_operand(W.A, N.A, vector.x, vector.n_factor)
- core.bnk.crt_y.set_operand(W.A, N.A, vector.y, vector.n_factor)
-
- core.bnk.crt_x.set_operand(W.E, N.E, vector.m, vector.m)
- core.bnk.crt_y.set_operand(W.E, N.E, vector.m, vector.m)
-
- # | W | N
- # --+-----+-----------
- # A |
- # B | ? | ?
- # C | ? | ?
- # D | ? | ?
- # E | M | M
-
- # | A | B | C | D | E |
- # +----------------+-------+---------+-------+---+
- # (YF, XF) =(Y,X)*N_FACTOR | X,Y ; N_FACTOR | ? | ? | ? | M |
- core.multiply(W.A, N.A, W.B, N.B, n_num_words) # (YF, XF) =(Y,X)*N_FACTOR | X,Y ; N_FACTOR | XF,YF | ? | ? | M |
- core.multiply(W.B, N.B, W.C, N.C, n_num_words, mode=(False, False)) # (YMF,XMF)=(YF*YF,XF*XF) | X,Y ; N_FACTOR | XF,YF | YMF,XMF | ? | M |
- core.multiply(W.C, N.I, W.D, N.D, n_num_words) # (YM, XM) =(YMF,XMF)*1 | X,Y ; N_FACTOR | XF,YF | YMF,XMF | XM,YM | M |
- core.simply_reduce(N.D, n_num_words) # | | | | | |
- core.set_output(O.XM, core.bnk.crt_x, N.D) # | | | | | |
- core.set_output(O.YM, core.bnk.crt_y, N.D) # | | | | | |
- core.multiply(W.E, N.B, W.C, N.C, n_num_words, mode=(False, False)) # (MB, _) =(M*YF,M*XF) | X,Y ; N_FACTOR | XF,YF | MB,_ | XM,YM | M |
- core.mirror_yx(W.C, N.C) # | X,Y ; N_FACTOR | XF,YF | MB,MB | XM,YM | M |
- core.simply_reduce(N.C, n_num_words) # | | | | | |
-
-
- XF = core.bnk.crt_x.ladder_x.wide._get_value(W.B)
- YF = core.bnk.crt_y.ladder_x.wide._get_value(W.B)
-
- MB = core.bnk.crt_y.ladder_x.narrow._get_value(N.C)
-
- PMBZ = core.wrk.multiply(MB, None, vector.p, vector.p_coeff, pq_num_words, reduce_only=True) # mod_reduce (mod p)
- QMBZ = core.wrk.multiply(MB, None, vector.q, vector.q_coeff, pq_num_words, reduce_only=True) # mod_reduce (mod q)
-
- mp_blind = core.wrk.multiply(PMBZ, vector.p_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
- mq_blind = core.wrk.multiply(QMBZ, vector.q_factor, vector.q, vector.q_coeff, pq_num_words) # mod_multiply
+ core.bnk.crt_x.set_operands_crt_xy(W.A, N.A, vector.x, vector.n_factor)
+ core.bnk.crt_y.set_operands_crt_xy(W.A, N.A, vector.y, vector.n_factor)
+
+ core.bnk.crt_x.set_operands_crt_xy(W.E, N.E, vector.m, vector.m)
+ core.bnk.crt_y.set_operands_crt_xy(W.E, N.E, vector.m, vector.m)
+ # | A | B | C | D | E |
+ # +-----------------+-------+------------------+---------+---+
+ # | [XY] ; N_FACTOR | ? | ? | ? | M |
+ core.modular_multiply(W.A, N.A, W.B, N.B, n_num_words) # [XY]F =[XY]*N_FACTOR | [XY] ; N_FACTOR | [XY]F | ? | ? | M |
+ core.modular_multiply(W.B, N.B, W.C, N.C, n_num_words, mode=(False, False)) # [XY]MF =[XY]F*[XY]F | [XY] ; N_FACTOR | [XY]F | [XY]YM | ? | M |
+ core.modular_multiply(W.C, N.I, W.D, N.D, n_num_words) # [XY]M =[XY]MF*1 | [XY] ; N_FACTOR | [XY]F | [XY]YM | [XY]M | M |
+ core.reduce_narrow(N.D, n_num_words) # | | | | | |
+ core.set_output(O.XM, core.bnk.crt_x, N.D) # | | | | | |
+ core.set_output(O.YM, core.bnk.crt_y, N.D) # | | | | | |
+ core.modular_multiply(W.E, N.B, W.C, N.C, n_num_words) # [XY]MB =M*[XY]F | [XY] ; N_FACTOR | [XY]F | [XY]MB | [XY]M | M |
+ core.move_crt_y2x(W.C, N.C) # | [XY] ; N_FACTOR | [XY]F | YMB | [XY]M | M |
+ core.bnk.crt_x.set_modulus(vector.p, vector.p_coeff) # | | | | | |
+ core.bnk.crt_y.set_modulus(vector.q, vector.q_coeff) # | | | | | |
+ core.bnk.crt_x.set_operands_crt_xy(W.A, N.A, vector.p_factor, vector.p_factor) # | [PQ]_FACTOR | [XY]F | YMB | [XY]M | M |
+ core.bnk.crt_y.set_operands_crt_xy(W.A, N.A, vector.q_factor, vector.q_factor) # | [PQ]_FACTOR | [XY]F | YMB | [XY]M | M |
+ core.reduce_narrow(N.C, n_num_words) # | | | | | |
+ core.modular_reduce(N.C, W.D, N.D, pq_num_words) # | [PQ]_FACTOR | [XY]F | YMB | [PQ]MBZ | M |
+ core.modular_multiply(W.D, N.A, W.C, N.C, pq_num_words) # [PQ]MB =[PQ]MBZ*[PQ]_FACTOR | [PQ]_FACTOR | [XY]F | [PQ]MB | [PQ]MBZ | M |
+ core.modular_multiply(W.C, N.A, W.D, N.D, pq_num_words) # [PQ]MBF=[PQ]MB*[PQ]_FACTOR | [PQ]_FACTOR | [XY]F | [PQ]MB | [PQ]MBF | M |
+ core.modular_multiply(W.A, N.I, W.C, N.C, pq_num_words) # [PQ]MBF=[PQ]MB*[PQ]_FACTOR | [PQ]_FACTOR | [XY]F | [PQ]IF | [PQ]MBF | M |
+ core.move_ladders_x2y(W.D, N.D, W.C, N.C) # | [PQ]_FACTOR | [XY]F | [PQ]IF / [PQ]MBF | [PQ]MBF | M |
+
+ #PIF = core.bnk.crt_x.ladder_x.narrow._get_value(N.C)#
+ #QIF = core.bnk.crt_y.ladder_x.narrow._get_value(N.C)#
+
- mp_blind_factor = core.wrk.multiply(mp_blind, vector.p_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
- mq_blind_factor = core.wrk.multiply(mq_blind, vector.q_factor, vector.q, vector.q_coeff, pq_num_words) # mod_multiply
- ip_factor = core.wrk.multiply(i, vector.p_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
- iq_factor = core.wrk.multiply(i, vector.q_factor, vector.q, vector.q_coeff, pq_num_words) # mod_multiply
+########################
+ for bit in range(_WORD_WIDTH * pq_num_words - 1, -1, -1):
+
+ bit_value_p = (vector.dp.number() & (1 << bit)) >> bit
+ bit_value_q = (vector.dq.number() & (1 << bit)) >> bit
- sp_blind_factor = core.wrk.exponentiate(ip_factor, mp_blind_factor, vector.dp, vector.p, vector.p_factor, vector.p_coeff, pq_num_words, dump_index=99, dump_mode="P") # mod_multiply
- sq_blind_factor = core.wrk.exponentiate(iq_factor, mq_blind_factor, vector.dq, vector.q, vector.q_factor, vector.q_coeff, pq_num_words, dump_index=99, dump_mode="Q") # mod_multiply
+ bit_value_p = bit_value_p > 0
+ bit_value_q = bit_value_q > 0
+
+ # mode = ... (shorted the next line for better readability)
+
+ core.modular_multiply(W.C, N.C, W.C, N.C, pq_num_words, mode=(bit_value_p, bit_value_q)) # <LADDER> | [PQ]_FACTOR | [XY]F | [PQ]SBF | [PQ]MBF | M |
+
+ if (bit % 4) == 0:
+ pct = float((_WORD_WIDTH * pq_num_words - bit) / (_WORD_WIDTH * pq_num_words)) * 100.0
+ print("\rdone: %5.1f%%" % pct, end='')
+
+ print("")
- SPB = core.wrk.multiply(i, sp_blind_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
- SQB = core.wrk.multiply(i, sq_blind_factor, vector.q, vector.q_coeff, pq_num_words) # mod_multiply
+ core.modular_multiply(W.C, N.I, W.D, N.D, pq_num_words) # [PQ]SB=[PQ]SBF*1 | [PQ]_FACTOR | [XY]F | [PQ]SBF | [PQ]SB | M |
- core.wrk.reduce(SPB, len(SPB.words)) # just_reduce
- core.wrk.reduce(SQB, len(SQB.words)) # just_reduce
+############################
+
+ core.reduce_narrow(N.D, pq_num_words)
+
+ #SQB = core.bnk.crt_y.ladder_x.narrow._get_value(N.D)
+
+ core.flip_ladder_y2x(W.D, N.D, W.D, N.D)
+ core.modular_subtract(N.D, N.C, W.C, pq_num_words) # | [PQ]_FACTOR | [XY]F | RSB | [PQ]SB | M |
+ core.bnk.crt_x.set_operands_crt_xy(W.E, N.E, vector.qinv, vector.qinv) # | [PQ]_FACTOR | [XY]F | RSB | [PQ]SB | QINV |
+ core.bnk.crt_y.set_operands_crt_xy(W.E, N.E, vector.qinv, vector.qinv) # | [PQ]_FACTOR | [XY]F | RSB | [PQ]SB | QINV |
- sr_blind = core.wrk.subtract(SPB, SQB, vector.p, pq_num_words) # mod_subtract
+ core.modular_multiply(W.C, N.E, W.C, N.C, pq_num_words) # | [PQ]_FACTOR | [XY]F | RSBIZ | [PQ]SB | QINV |
+ core.modular_multiply(W.C, N.A, W.C, N.C, pq_num_words) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB | QINV |
+
+ core.bnk.crt_x.set_operands_crt_xy(W.E, N.E, vector.q, vector.q) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB | Q |
+ core.bnk.crt_y.set_operands_crt_xy(W.E, N.E, vector.q, vector.q) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB | Q |
+
+ core.just_multiply(W.E, N.C, pq_num_words) # | [PQ]_FACTOR | [XY]F | RSBI | [PQ]SB | Q |
- sr_qinv_blind_inverse_factor = core.wrk.multiply(sr_blind, vector.qinv, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
- sr_qinv_blind = core.wrk.multiply(sr_qinv_blind_inverse_factor, vector.p_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
+ core.merge_lha(N.A, pq_num_words)
- q_sr_qinv_blind = core.wrk.multiply(vector.q, sr_qinv_blind, None, None, pq_num_words, multiply_only=True) # just_multiply
+ core.reduce_narrow(N.A, n_num_words)
- core.wrk.reduce(q_sr_qinv_blind, n_num_words) # just_reduce
+ core.move_crt_y2x(W.D, N.D)
- SB = core.wrk.add(SQB, q_sr_qinv_blind, pq_num_words) # just_add
+ #RQSBI = core.bnk.crt_x.ladder_x.narrow._get_value(N.A)
+
+ core.just_add(N.D, N.A, N.C, pq_num_words) #
+ SB = core.bnk.crt_x.ladder_x._get_narrow(N.C)
+ #print(hex(SB.number()))
- S = core.wrk.multiply(SB, XF, vector.n, vector.n_coeff, n_num_words) # mod_multiply
+ #SB = core.wrk.add(SQB, RQSBI, pq_num_words) # just_add
+ #print(hex(SB.number()))
+
+
+ # check why multiplication is not commutative!?
+
+
+ XF = core.bnk.crt_x.ladder_x.wide._get_value(W.B)
- core.wrk.reduce(S, len(S.words)) # just_reduce
+ core.bnk.crt_x.set_modulus(vector.n, vector.n_coeff)
+ core.bnk.crt_y.set_modulus(vector.n, vector.n_coeff)
- # check
+ core.modular_multiply(W.B, N.C, W.A, N.A, n_num_words, mode=(False, False))
+ core.reduce_narrow(N.A, n_num_words)
+ core.set_output(O.S, core.bnk.crt_x, N.A)
+
+ S = core.out.get_value(O.S)
XM = core.out.get_value(O.XM)
YM = core.out.get_value(O.YM)