[Cryptech-Commits] [core/math/modexpng] 20/92: * Added more micro-operations

git at cryptech.is git at cryptech.is
Sat Mar 14 18:18:59 UTC 2020


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch master
in repository core/math/modexpng.

commit a5200cd8af68cca49978bfa023b704ad5431eae1
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Mon Aug 19 13:57:12 2019 +0300

    * Added more micro-operations
    
    * Working microcode for CRT exponentiation
    
    * Further refactoring
---
 modexpng_fpga_model.py | 372 +++++++++++++++++++++++++++++++++++++++----------
 1 file 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)
     



More information about the Commits mailing list