[Cryptech-Commits] [core/math/modexpng] 18/92: * Added more debugging options: - intentionally trigger internal overflow handler - dump MAC inputs - dump intermediate numbers during the reduction phase

git at cryptech.is git at cryptech.is
Sat Mar 14 18:18:57 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 c165ddceb00b9ba79e8cd238f9228736875dacb8
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Mon Aug 19 13:44:28 2019 +0300

    * Added more debugging options:
     - intentionally trigger internal overflow handler
     - dump MAC inputs
     - dump intermediate numbers during the reduction phase
    
    * Bus widths changes
    
    * Some cosmetic changes
---
 modexpng_fpga_model.py | 335 +++++++++++++++++++++++++++----------------------
 1 file changed, 185 insertions(+), 150 deletions(-)

diff --git a/modexpng_fpga_model.py b/modexpng_fpga_model.py
index d33f314..cc3e868 100644
--- a/modexpng_fpga_model.py
+++ b/modexpng_fpga_model.py
@@ -74,12 +74,15 @@ _VECTOR_CLASS = "Vector"
 # ------------------
 # Debugging Settings
 # ------------------
+FORCE_OVERFLOW = False
 DUMP_VECTORS = False
 DUMP_INDICES = False
+DUMP_MACS_INPUTS = False
 DUMP_MACS_CLEARING = False
 DUMP_MACS_ACCUMULATION = False
 DUMP_MULT_PARTS = False
 DUMP_RCMB = False
+DUMP_REDUCTION = False
 
 
 #
@@ -111,14 +114,14 @@ class ModExpNG_Operand():
             if i > 0:
                 if (i % 4) == 0: print("")
                 else:            print(" ", end='')
-            print("%s[%2d] = 17'h%05x;" % (name, i, self.words[i]), end='')
+            print("%s[%2d] = 18'h%05x;" % (name, i, self.words[i]), end='')
         print("")
 
     def _init_from_words(self, words, count):
 
         for i in range(count):
 
-            # word must not exceed 17 bits
+            # word must not exceed 18 bits
             if words[i] >= (2 ** (_WORD_WIDTH + 2)):
                 raise Exception("Word is too large!")
 
@@ -221,7 +224,7 @@ class ModExpNG_PartRecombinator():
         # shift to the right
         z1 = z
         y1 = y + self.z0
-        x1 = x + self.y0 + (self.x0 >> 16) # IMPORTANT: This carry can be up to two bits wide!!
+        x1 = x + self.y0 + (self.x0 >> _WORD_WIDTH) # IMPORTANT: This carry can be up to two bits wide!!
 
         # save lower 16 bits of the rightmost cell
         t = self.x0 & 0xffff
@@ -287,7 +290,8 @@ class ModExpNG_PartRecombinator():
 
         # recombine the lower half (n+1 parts)
         # the first tick produces null result, so we need n + 1 + 1 = n + 2
-        # ticks total and should only save the result word during the last n ticks
+        # ticks total and should only save the result word during the last
+        # n + 1 ticks
         self._flush_pipeline(dump)
         for i in range(ab_num_words + 2):
 
@@ -344,29 +348,9 @@ class ModExpNG_PartRecombinator():
 
         return words
 
-                
-        # flush recombinator pipeline
-        #self._flush_pipeline(dump)
-
-        # the first tick produces null result, the last part produces
-        # two words, so we need 2 * n + 2 ticks total and should only save
-        # the result word during the last 2 * n + 1 ticks
-        #for i in range(2 * ab_num_words + 2):
-
-            #next_part = parts[i] if i < (2 * ab_num_words) else 0
-            #next_word = self._push_pipeline(next_part, dump)
-
-            #if i > 0:
-                #words.append(next_word)
-
-        return words
-
 
 class ModExpNG_WordMultiplier():
 
-    _a_seen_17 = False
-    _b_seen_17 = False
-
     def __init__(self):
 
         self._macs = list()
@@ -388,38 +372,45 @@ class ModExpNG_WordMultiplier():
         if dump and DUMP_MACS_CLEARING:
             print("t=%2d, col=%2d > clear > all" % (t, col))
 
-
     def _clear_one_mac(self, x, t, col, dump):
         self._macs[x] = 0
         if dump and DUMP_MACS_CLEARING:
             print("t=%2d, col=%2d > clear > x=%d" % (t, col, x))
 
-
     def _clear_mac_aux(self, t, col, dump):
         self._mac_aux[0] = 0
         if dump and DUMP_MACS_CLEARING:
             print("t= 0, col=%2d > clear > aux" % (col))
 
+    def _update_one_mac(self, x, t, col, a, b, dump, need_aux=False):
 
-    def _update_one_mac(self, x, a, b):
-
-        if a > 0xFFFF:
-            self._a_seen_17 = True
+        if a > 0x3FFFF:
+            raise Exception("a > 0x3FFFF!")
 
         if b > 0xFFFF:
-            self._b_seen_17 = True
+            raise Exception("b > 0xFFFF!")
 
+        p = a * b
+        if dump and DUMP_MACS_INPUTS:
+            if x == 0: print("t=%2d, col=%2d > b=%05x > " % (t, col, b), end='')
+            if x > 0: print("; ", end='')
+            print("MAC[%d]: a=%05x" % (x, a), end='')
+            if x == (NUM_MULTS-1) and not need_aux: print("")
+            
+        self._macs[x] += p
+
+    def _update_mac_aux(self, y, col, a, b, dump):
+        
         if a > 0x3FFFF:
             raise Exception("a > 0x3FFFF!")
 
-        if b > 0x1FFFF:
-            raise Exception("b > 0x1FFFF!")
+        if b > 0xFFFF:
+            raise Exception("b > 0xFFFF!")
 
         p = a * b
-        self._macs[x] += p
-
-    def _update_mac_aux(self, value):
-        self._mac_aux[0] += value
+        if dump and DUMP_MACS_INPUTS:
+            print("; AUX: a=%05x" % a)
+        self._mac_aux[0] += p
 
     def _preset_indices(self, col):
         for x in range(len(self._indices)):
@@ -440,7 +431,7 @@ class ModExpNG_WordMultiplier():
     def _dump_macs(self, t, col):
         self._dump_macs_helper(t, col)
 
-    def _dump_macs_aux(self, t, col):
+    def _dump_macs_with_aux(self, t, col):
         self._dump_macs_helper(t, col, True)
 
     def _dump_indices_helper(self, t, col, aux=False):
@@ -454,7 +445,7 @@ class ModExpNG_WordMultiplier():
     def _dump_indices(self, t, col):
         self._dump_indices_helper(t, col)
 
-    def _dump_indices_aux(self, t, col):
+    def _dump_indices_with_aux(self, t, col):
         self._dump_indices_helper(t, col, True)
 
     def _rotate_indices(self, num_words):
@@ -473,16 +464,14 @@ class ModExpNG_WordMultiplier():
             print("t=%2d, col=%2d > parts[%2d]: mac[%d] = 0x%012x" %
                 (time, column, part_index, mac_index, parts[part_index]))
 
-    def _mult_store_part_aux(self, parts, time, column, part_index, mac_index, dump):
-        parts[part_index] = self._mac_aux[mac_index]
+    def _mult_store_part_aux(self, parts, time, column, part_index, dump):
+        parts[part_index] = self._mac_aux[0]
         if dump and DUMP_MULT_PARTS:
             print("t=%2d, col=%2d > parts[%2d]: mac_aux[%d] = 0x%012x" %
-                (time, column, part_index, mac_index, parts[part_index]))
+                (time, column, part_index, 0, parts[part_index]))
 
     def multiply_square(self, a_wide, b_narrow, ab_num_words, dump=False):
 
-        if dump: print("multiply_square()")
-
         num_cols = ab_num_words // NUM_MULTS
 
         parts = list()
@@ -490,8 +479,8 @@ class ModExpNG_WordMultiplier():
             parts.append(0)
 
         for col in range(num_cols):
-
-            bt_carry = 0
+        
+            b_carry = 0
         
             for t in range(ab_num_words):
 
@@ -511,15 +500,15 @@ class ModExpNG_WordMultiplier():
                 if dump and DUMP_INDICES: self._dump_indices(t, col)
 
                 # current b-word
-                bt = b_narrow.words[t] + bt_carry
-                bt_carry = bt >> _WORD_WIDTH
-                bt &= 0xffff
-                
+                # TODO: Explain how the 18th bit carry works!!
+                bt = b_narrow.words[t] + b_carry
+                b_carry = (bt & 0x30000) >> 16
+                bt &= 0xFFFF
 
                 # multiply by a-words
                 for x in range(NUM_MULTS):
                     ax = a_wide.words[self._indices[x]]
-                    self._update_one_mac(x, ax, bt)
+                    self._update_one_mac(x, t, col, ax, bt, dump)
 
                     if t == (col * NUM_MULTS + x):
                         part_index = t
@@ -540,8 +529,6 @@ class ModExpNG_WordMultiplier():
 
     def multiply_triangle(self, a_wide, b_narrow, ab_num_words, dump=False):
 
-        if dump: print("multiply_triangle()")
-
         num_cols = ab_num_words // NUM_MULTS
 
         parts = list()
@@ -571,7 +558,7 @@ class ModExpNG_WordMultiplier():
                     if t == 0: self._clear_mac_aux(t, col, dump)
 
                 # debug output
-                if dump and DUMP_INDICES: self._dump_indices_aux(t, col)
+                if dump and DUMP_INDICES: self._dump_indices_with_aux(t, col)
 
                 # current b-word
                 bt = b_narrow.words[t]
@@ -579,7 +566,7 @@ class ModExpNG_WordMultiplier():
                 # multiply by a-words
                 for x in range(NUM_MULTS):
                     ax = a_wide.words[self._indices[x]]
-                    self._update_one_mac(x, ax, bt)
+                    self._update_one_mac(x, t, col, ax, bt, dump, last_col)
 
                     if t == (col * NUM_MULTS + x):
                         part_index = t
@@ -588,14 +575,14 @@ class ModExpNG_WordMultiplier():
                 # aux multiplier
                 if last_col:
                     ax = a_wide.words[self._index_aux[0]]
-                    self._update_mac_aux(ax * bt)
+                    self._update_mac_aux(t, col, ax, bt, dump)
 
                     if t == ab_num_words:
                         part_index = t
-                        self._mult_store_part_aux(parts, t, col, part_index, 0, dump)
+                        self._mult_store_part_aux(parts, t, col, part_index, dump)
 
                 # debug output
-                if dump and DUMP_MACS_ACCUMULATION: self._dump_macs_aux(t, col)
+                if dump and DUMP_MACS_ACCUMULATION: self._dump_macs_with_aux(t, col)
 
                 # shortcut
                 if not last_col:
@@ -605,8 +592,6 @@ class ModExpNG_WordMultiplier():
 
     def multiply_rectangle(self, a_wide, b_narrow, ab_num_words, dump=False):
 
-        if dump: print("multiply_rectangle()")
-
         num_cols = ab_num_words // NUM_MULTS
 
         parts = list()
@@ -638,7 +623,7 @@ class ModExpNG_WordMultiplier():
                 # multiply by a-words
                 for x in range(NUM_MULTS):
                     ax = a_wide.words[self._indices[x]]
-                    self._update_one_mac(x, ax, bt)
+                    self._update_one_mac(x, t, col, ax, bt, dump)
 
                     # don't save one value for the very last time instant per column
                     if t < ab_num_words and t == (col * NUM_MULTS + x):
@@ -686,6 +671,7 @@ class ModExpNG_LowlevelOperator():
         return (sum_c, sum_s)
 
     def sub_words(self, a, b, b_in):
+    
         self._check_word(a)
         self._check_word(b)
         self._check_carry_borrow(b_in)
@@ -704,14 +690,12 @@ class ModExpNG_LowlevelOperator():
 
 class ModExpNG_Worker():
 
-    max_zzz = 0
-
     def __init__(self):
         self.recombinator = ModExpNG_PartRecombinator()
         self.multiplier   = ModExpNG_WordMultiplier()
         self.lowlevel     = ModExpNG_LowlevelOperator()
 
-    def exponentiate(self, iz, bz, e, n, n_factor, n_coeff, num_words):
+    def exponentiate(self, iz, bz, e, n, n_factor, n_coeff, num_words, dump_index=-1, dump_mode=""):
 
         # working variables
         t1, t2 = iz, bz
@@ -719,19 +703,51 @@ 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):
 
-            if e.number() & (1 << bit):
-                p1 = self.multiply(t1, t2, n, n_coeff, num_words)
-                p2 = self.multiply(t2, t2, n, n_coeff, num_words)
+            debug_dump = bit == dump_index
+
+            bit_value = (e.number() & (1 << bit)) >> bit
+            
+            if debug_dump:
+                print("\rladder_mode = %d" % bit_value)
+                
+                if FORCE_OVERFLOW:
+                    T1X = list(t1.words)
+                    for i in range(num_words):
+                        if i > 0:
+                            bits = T1X[i-1] & (3 << 16)
+                            if bits == 0:
+                                bits = T1X[i] & 3
+                                T1X[i] = T1X[i] ^ bits
+                                T1X[i-1] |= (bits << 16)
+                                    
+                    for i in range(num_words):
+                        t1.words[i] = T1X[i]
+                
+                if DUMP_VECTORS:
+                    print("num_words = %d" % num_words)
+                    t1.format_verilog_concat("%s_T1" % dump_mode)
+                    t2.format_verilog_concat("%s_T2" % dump_mode)
+                    n.format_verilog_concat("%s_N" % dump_mode)
+                    n_coeff.format_verilog_concat("%s_N_COEFF"  % dump_mode)
+                            # force the rarely seen overflow
+
+            if bit_value:
+                p1 = self.multiply(t1, t2, n, n_coeff, num_words, dump=debug_dump, dump_mode=dump_mode, dump_phase="X")
+                p2 = self.multiply(t2, t2, n, n_coeff, num_words, dump=debug_dump, dump_mode=dump_mode, dump_phase="Y")
             else:
-                p1 = self.multiply(t1, t1, n, n_coeff, num_words)
-                p2 = self.multiply(t2, t1, n, n_coeff, num_words)
+                p1 = self.multiply(t1, t1, n, n_coeff, num_words, dump=debug_dump, dump_mode=dump_mode, dump_phase="X")
+                p2 = self.multiply(t2, t1, n, n_coeff, num_words, dump=debug_dump, dump_mode=dump_mode, dump_phase="Y")
 
             t1, t2 = p1, p2
 
+            if debug_dump and DUMP_VECTORS:
+                t1.format_verilog_concat("%s_X" % dump_mode)
+                t2.format_verilog_concat("%s_Y" % dump_mode)
+
             if (bit % 8) == 0:
                 pct = float((_WORD_WIDTH * num_words - bit) / (_WORD_WIDTH * num_words)) * 100.0
                 print("\rpct: %5.1f%%" % pct, end='')
-
+        
         print("")
 
         return t1
@@ -780,16 +796,11 @@ class ModExpNG_Worker():
 
         return ModExpNG_Operand(None, 2*ab_num_words, ab)
 
-    def multiply(self, a, b, n, n_coeff, ab_num_words, reduce_only=False, multiply_only=False, dump=False):
+    def multiply(self, a, b, n, n_coeff, ab_num_words, reduce_only=False, multiply_only=False, dump=False, dump_mode="", dump_phase=""):
 
-        if dump and DUMP_VECTORS:
-            print("num_words = %d" % ab_num_words)
-            a.format_verilog_concat("A")
-            b.format_verilog_concat("B")
-            n.format_verilog_concat("N")
-            n_coeff.format_verilog_concat("N_COEFF")
-
-        # 1.
+        # 1. AB = A * B
+        if dump: print("multiply_square(%s_%s)" % (dump_mode, dump_phase))
+        
         if reduce_only:
             ab = a
         else:
@@ -797,61 +808,92 @@ class ModExpNG_Worker():
             ab_words = self.recombinator.recombine_square(ab_parts, ab_num_words, dump)
             ab = ModExpNG_Operand(None, 2 * ab_num_words, ab_words)
 
+        if dump and DUMP_VECTORS:
+            ab.format_verilog_concat("%s_%s_AB" % (dump_mode, dump_phase))
+
         if multiply_only:
             return ModExpNG_Operand(None, 2*ab_num_words, ab_words)
 
-        # 2.
+            
+        # 2. Q = LSB(AB) * N_COEFF
+        if dump: print("multiply_triangle(%s_%s)" % (dump_mode, dump_phase))
+        
         q_parts = self.multiplier.multiply_triangle(ab, n_coeff, ab_num_words, dump)
         q_words = self.recombinator.recombine_triangle(q_parts, ab_num_words, dump)
         q = ModExpNG_Operand(None, ab_num_words + 1, q_words)
 
-        # 3.
+        if dump and DUMP_VECTORS:
+            q.format_verilog_concat("%s_%s_Q" % (dump_mode, dump_phase))
+
+        # 3. M = Q * N
+        if dump: print("multiply_rectangle(%s_%s)" % (dump_mode, dump_phase))
+        
         m_parts = self.multiplier.multiply_rectangle(n, q, ab_num_words, dump)
         m_words = self.recombinator.recombine_rectangle(m_parts, ab_num_words, dump)
         m = ModExpNG_Operand(None, 2 * ab_num_words + 1, m_words)
+        
+        if dump and DUMP_VECTORS:
+            m.format_verilog_concat("%s_%s_M" % (dump_mode, dump_phase))
+
+        if (m.number() != (q.number() * n.number())):
+            print("MISMATCH")
+            sys.exit()
 
-        # 4.
-        cy = 0
+            
+        # 4. R = AB + M
+        
+        # 4a. compute carry (actual sum is all zeroes and need not be stored)
+        r_cy = 0 # this can be up to two bits, since we're adding extended words!!
         for i in range(ab_num_words + 1):
-            s = ab.words[i] + m.words[i] + cy
-            cy = s >> 16
+            s = ab.words[i] + m.words[i] + r_cy
+            r_cy_new = s >> 16
             
+            if dump and DUMP_REDUCTION:
+                print("[%2d] 0x%05x + 0x%05x + 0x%x => {0x%x, [0x%05x]}" %
+                    (i, ab.words[i], m.words[i], r_cy, r_cy_new, s & 0xffff))
+                
+            r_cy = r_cy_new
+        
+        
+        # 4b. Initialize empty result
         R = list()
         for i in range(ab_num_words):
             R.append(0)
 
-        R[0] = cy # !!! (cy is 2 bits, i.e. 0..3)
-        
-        if dump:
-            if ab.words[ab_num_words + 2] > 0:
-                ab.words[ab_num_words + 2] -= 1
-                ab.words[ab_num_words + 1] += 0x10000
-            if m.words[ab_num_words + 2] > 0:
-                m.words[ab_num_words + 2] -= 1
-                m.words[ab_num_words + 1] += 0x10000
-        
+        # 4c. compute the actual upper part of sum (take carry into account)
         for i in range(ab_num_words):
+        
+            if dump and DUMP_REDUCTION:
+                print("[%2d]" % i, end='')
+                
             ab_word = ab.words[ab_num_words + i + 1] if i < (ab_num_words - 1) else 0
+            if dump and DUMP_REDUCTION:
+                print(" 0x%05x" % ab_word, end='')
+                
             m_word = m.words[ab_num_words + i + 1]
-            
-            R[i] += ab_word + m_word
-
-            #if i == 0:
-                #if R[i] > self.max_zzz:
-                    #self.max_zzz = R[i]
-                    #print("self.max_zzz = %05x" % R[i])
-                #if R[i] > 0x1ffff:
-                    #sys.exit(123)
+            if dump and DUMP_REDUCTION:
+                print(" + 0x%05x" % m_word, end='')
                 
+            if i == 0: R[i] = r_cy
+            else:      R[i] = 0
             
+            if (r_cy > 3): print("\rR_CY = %d!" % r_cy)
+            
+            if dump and DUMP_REDUCTION:
+                print(" + 0x%x" % R[i], end='')
                 
+            R[i] += ab_word
+            R[i] += m_word
+            if dump and DUMP_REDUCTION:
+                print(" = 0x%05x" % R[i])
+                        
         return ModExpNG_Operand(None, ab_num_words, R)
 
     def reduce(self, a):
         carry = 0
         for x in range(len(a.words)):
             a.words[x] += carry
-            carry = (a.words[x] >> _WORD_WIDTH) & 1
+            carry = (a.words[x] >> _WORD_WIDTH) & 3
             a.words[x] &= self.lowlevel._word_mask
 
 
@@ -894,73 +936,66 @@ if __name__ == "__main__":
     #  s_crt = sq + q_sr_qinv
     # unblind s
     # mutate blinding factors
-    ip_factor                    = worker.multiply(i,                            vector.p_factor,  vector.p, vector.p_coeff, pq_num_words)
-    iq_factor                    = worker.multiply(i,                            vector.q_factor,  vector.q, vector.q_coeff, pq_num_words)
-
-    x_factor                     = worker.multiply(vector.x,                     vector.n_factor,  vector.n, vector.n_coeff, n_num_words)
-    y_factor                     = worker.multiply(vector.y,                     vector.n_factor,  vector.n, vector.n_coeff, n_num_words)
-
-    m_blind                      = worker.multiply(vector.m,                     y_factor,         vector.n, vector.n_coeff, n_num_words)
+    
+    XF  = worker.multiply(vector.x, vector.n_factor, vector.n, vector.n_coeff, n_num_words) # mod_multiply (mod n)
+    YF  = worker.multiply(vector.y, vector.n_factor, vector.n, vector.n_coeff, n_num_words) # mod_multiply (mod n)
 
-    worker.reduce(m_blind)
+    XMF = worker.multiply(XF,       XF,              vector.n, vector.n_coeff, n_num_words) # mod_multiply (mod n)
+    YMF = worker.multiply(YF,       YF,              vector.n, vector.n_coeff, n_num_words) # mod_multiply (mod n)
+    
+    XM  = worker.multiply(i,        XMF,             vector.n, vector.n_coeff, n_num_words) # mod_multiply (mod n)
+    YM  = worker.multiply(i,        YMF,             vector.n, vector.n_coeff, n_num_words) # mod_multiply (mod n)
 
-    mp_blind_inverse_factor      = worker.multiply(m_blind,                      None,             vector.p, vector.p_coeff, pq_num_words, reduce_only=True)
-    mq_blind_inverse_factor      = worker.multiply(m_blind,                      None,             vector.q, vector.q_coeff, pq_num_words, reduce_only=True)
+    MB  = worker.multiply(vector.m, YF,              vector.n, vector.n_coeff, n_num_words) # mod_multiply (mod n)
 
-    mp_blind                     = worker.multiply(mp_blind_inverse_factor,      vector.p_factor,  vector.p, vector.p_coeff, pq_num_words)
-    mq_blind                     = worker.multiply(mq_blind_inverse_factor,      vector.q_factor,  vector.q, vector.q_coeff, pq_num_words)
+    worker.reduce(MB) # just_reduce
 
-    mp_blind_factor              = worker.multiply(mp_blind,                     vector.p_factor,  vector.p, vector.p_coeff, pq_num_words, dump=True)
-    mq_blind_factor              = worker.multiply(mq_blind,                     vector.q_factor,  vector.q, vector.q_coeff, pq_num_words)
+    mp_blind_inverse_factor = worker.multiply(MB, None, vector.p, vector.p_coeff, pq_num_words, reduce_only=True) # mod_reduce (mod p)
+    mq_blind_inverse_factor = worker.multiply(MB, None, vector.q, vector.q_coeff, pq_num_words, reduce_only=True) # mod_reduce (mod q)
 
-    sp_blind_factor              = worker.exponentiate(ip_factor, mp_blind_factor, vector.dp, vector.p, vector.p_factor, vector.p_coeff, pq_num_words)
-    sq_blind_factor              = worker.exponentiate(iq_factor, mq_blind_factor, vector.dq, vector.q, vector.q_factor, vector.q_coeff, pq_num_words)
+    mp_blind = worker.multiply(mp_blind_inverse_factor, vector.p_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
+    mq_blind = worker.multiply(mq_blind_inverse_factor, vector.q_factor, vector.q, vector.q_coeff, pq_num_words) # mod_multiply
 
-    if worker.multiplier._a_seen_17:
-        print("17-bit wide A's seen.")
-    else:
-        print("17-bit wide A's not detected.")
+    mp_blind_factor = worker.multiply(mp_blind, vector.p_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
+    mq_blind_factor = worker.multiply(mq_blind, vector.q_factor, vector.q, vector.q_coeff, pq_num_words) # mod_multiply
 
-    if worker.multiplier._b_seen_17:
-        print("17-bit wide B's seen.")
-    else:
-        print("17-bit wide B's not detected.")
+    ip_factor = worker.multiply(i, vector.p_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
+    iq_factor = worker.multiply(i, vector.q_factor, vector.q, vector.q_coeff, pq_num_words) # mod_multiply
 
-        
+    sp_blind_factor = worker.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 = worker.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
 
-    sp_blind                     = worker.multiply(i,                            sp_blind_factor,  vector.p, vector.p_coeff, pq_num_words)
-    sq_blind                     = worker.multiply(i,                            sq_blind_factor,  vector.q, vector.q_coeff, pq_num_words)
+    SPB = worker.multiply(i, sp_blind_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
+    SQB = worker.multiply(i, sq_blind_factor, vector.q, vector.q_coeff, pq_num_words) # mod_multiply
 
-    sr_blind                     = worker.subtract(sp_blind, sq_blind, vector.p, pq_num_words)
+    worker.reduce(SPB) # just_reduce
+    worker.reduce(SQB) # just_reduce
 
-    sr_qinv_blind_inverse_factor = worker.multiply(sr_blind,                     vector.qinv,      vector.p, vector.p_coeff, pq_num_words)
-    sr_qinv_blind                = worker.multiply(sr_qinv_blind_inverse_factor, vector.p_factor,  vector.p, vector.p_coeff, pq_num_words)
-    q_sr_qinv_blind              = worker.multiply(vector.q,                     sr_qinv_blind,    None,     None,           pq_num_words, multiply_only=True)
+    sr_blind = worker.subtract(SPB, SQB, vector.p, pq_num_words) # mod_subtract
 
-    worker.reduce(q_sr_qinv_blind)
+    sr_qinv_blind_inverse_factor = worker.multiply(sr_blind, vector.qinv, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
+    sr_qinv_blind = worker.multiply(sr_qinv_blind_inverse_factor, vector.p_factor, vector.p, vector.p_coeff, pq_num_words) # mod_multiply
     
-    s_crt_blinded                = worker.add(sq_blind, q_sr_qinv_blind, pq_num_words)
+    q_sr_qinv_blind = worker.multiply(vector.q, sr_qinv_blind, None, None, pq_num_words, multiply_only=True) # just_multiply
 
-    s_crt_unblinded              = worker.multiply(s_crt_blinded,                x_factor,         vector.n, vector.n_coeff, n_num_words)
-
-    x_mutated_factor             = worker.multiply(x_factor,                     x_factor,         vector.n, vector.n_coeff, n_num_words)
-    y_mutated_factor             = worker.multiply(y_factor,                     y_factor,         vector.n, vector.n_coeff, n_num_words)
+    worker.reduce(q_sr_qinv_blind) # just_reduce
+    
+    SB = worker.add(SQB, q_sr_qinv_blind, pq_num_words) # just_add
 
-    x_mutated                    = worker.multiply(i,                            x_mutated_factor, vector.n, vector.n_coeff, n_num_words)
-    y_mutated                    = worker.multiply(i,                            y_mutated_factor, vector.n, vector.n_coeff, n_num_words)
+    S = worker.multiply(SB, XF, vector.n, vector.n_coeff, n_num_words) # mod_multiply
 
-    worker.reduce(s_crt_unblinded)
-    worker.reduce(x_mutated)
-    worker.reduce(y_mutated)
+    worker.reduce(S) # just_reduce
+    worker.reduce(XM) # just_reduce
+    worker.reduce(YM) # just_reduce
 
     # check
-    if s_crt_unblinded.number() != s_known:   print("ERROR: s_crt_unblinded != s_known!")
+    if S.number() != s_known:   print("ERROR: s_crt_unblinded != s_known!")
     else:                                     print("s is OK")
 
-    if x_mutated.number() != x_mutated_known: print("ERROR: x_mutated != x_mutated_known!")
+    if XM.number() != x_mutated_known: print("ERROR: x_mutated != x_mutated_known!")
     else:                                     print("x_mutated is OK")
 
-    if y_mutated.number() != y_mutated_known: print("ERROR: y_mutated != y_mutated_known!")
+    if YM.number() != y_mutated_known: print("ERROR: y_mutated != y_mutated_known!")
     else:                                     print("y_mutated is OK")
 
 



More information about the Commits mailing list