#d = 112355821013181156334579806714681205113924101983091861382414581448074528853593605127763129459607001465442516908138238424303909864293999123027639058680152442574950795353128551552720849511889171655164974758120631156315783552861760016539440473035738314285696233932793785419140238228427811142518736338748655534216 #d = 133857774395556098823468076626040347428204866818519542402902008784242273588316831913605996105230853461276135011422723944412845259711225048858837394986306394647391907198726511192712952714328510682163669967335973252036472304294328739156120877752865219694442283089125533996403824366372974853733187988425356295024 #d = 92672982967554862852872006766567885353927794137150728379364376690926427171759450260823444154424352669428620565618041049755868480284199412293078394066055239894180641830867546527203202271291597555024007333879865905283486866630899589672475264171999801451395902946562129189391119900984175066161729889310646122594 #d = 113813244351128015985725472713799074858302071177559053942112014638788671381991253282405181172424524305518788455655662991697764200854729806319332367596212279599001943195420594782844193398223385020569219824365726550599798813591088325549820289065752592119059411046289242404680945642950558285906917488427350067624 #d = 154306836123321631119810799993069910562141298931598323240160602873671313236111868972030294077912144521304411731326072185184552318703310573606495608896444935154732549995879559329450180425460887277250996580725663464080385147621501500334111997031535773362131377142103450071529478728786081711354141515585781890867 #d = 144158195593448605833804358266959731071319524602506883655484058320858197715337147221541236215995256052433774784893470051901675638209433372179900041158152554361983763960343665324874540181999367855835609860134390778783899662849805853369844243552402213219357445415050466245170450596556905770235758017088277438463 #d = 133882584169402263649273269380196608150084375269146243075496885327405606895985408568168074590228694708438736519641709599822579193115157935449659948346845017681175549217934255050505731490489216233723387151881486768711240179550970803743221393089463044661701791371054424648342246977177087977856380921510782107615 #d = 89890143019078095666205291519192456199494286740069204913245222910175469067352905557250874673542291519764568367690661504881757821856674244313802393186064887816981967011575839272828011803696604070384573895899003090207346702274748477045360023825244474240081997951823651945005117885273906197385377692060280309872 #d = 179769313486231550846377820112651619934450204046286207089508497640609636080136379993475607411279856471548734596191771850457170532144305191108817379111947852937804676159408642833589618669094281927243886543216063460892657915213572256793106748888238068024466511814056459351928721043252931840952970109551898525693 #d = 138077524384358897387044254528942666865362436963425081806222678029623527212561397169625919256841085997842460692685629820335432379563877502861077662100645851747408164039505064751503719854570729630741324273793686789643069754389888125919913610491927011554612571257339014291317914843276351034098443218764569772032 #d = 112399902876706645855193200215846797377686746602348093309395081305273711708872277912471569972950225871079503530829845264090289742903812768541381031778883678678641113130026814629247250025509579187903678182812889146989970235966832273151062245438395886319290591445432792632323908362447250818793593858283557355522 #d = 102292777480667301538680215936936970283092621829031321200241989331682699365974716872354801193947415645909294390183956243605147184376659696804092413123017374096080271856608472255086366623878981317181944936395399158744668440601249710010755921860415444235147513673664907034438157378610303883773088414762812422029 d = 179769313486230293476729321456568711106334152553137915895549523442135975529688892045243765355877820600277606527886009475314273959881378474590711686871215518410475081291639017048244081934993792064218187859314222021261959843396508002327741826742350432873271262317803816765741246938839638072935076868657199972351 print('\n\n************* {0}回目 ***************'.format(i + 1)) print('******** c = {0} , d = {1}, {2} ********\n'.format( c, bin.binary_d(d), d)) #print('******** c = {0} , d = {1}, {2} , e = {3} ********\n'.format(c, bin.binary_d(d), d, e)) # 以下, バイナリ法の実施により, # 平文mとカウント数countを計算 print('*************binary_method*************') m1, mod_count1, mult_count1 = bin.binary_method(c, d, N) binary_mod_count_list.append(mod_count1) binary_mult_count_list.append(mult_count1) binary_sum_count_list.append(mod_count1 + mult_count1) bin.average(binary_mod_count_list) bin.average(binary_mult_count_list) bin.average(binary_sum_count_list) #print('c = {0}, d = {1}, N = {2}'.format(c, d, N)) print('binary(c, d, N) = {0}'.format(m1)) print('mod_count = {0}'.format(mod_count1))
def crt(c, d, N, p, q): mod_count = 0 mult_count = 0 # # あらかじめ計算しておく部分 # d_p = d % (p - 1) d_q = d % (q - 1) #d_p, _ = bin.modulo(d, p-1, mod_count) #d_q, _ = bin.modulo(d, q-1, mod_count) q_dash = mod_equal_1_crt(q, p) #print('q_dash = {0}'.format(q_dash)) """ # Q, Pの計算 # countの操作はしなくて良い. # あらかじめ計算しなければいけないものなので. y = mod_equal_1_crt(q, p) x = mod_equal_1_crt(p, q) # 以下の二つはcountを操作しなくて良い # あらかじめ計算しなければいけないものなので. Q, _ = bin.modulo(q*y, N, 0) P, _ = bin.modulo(p*x, N, 0) """ # # 以上, あらかじめ計算しておく部分 # """ #print('\n\nc={0}, d={1}, N={2}, p={3}, q={4}'.format(c,d,N,p,q)) print('================= CRT(c:{0}, d:{1}, N:{2}, p:{3}, q:{4}) ================='.format(c, d, N, p, q)) a, mod_count1, mult_count1 = mon.mod_bin(c, d, p) print('c**d mod p = {0}'.format(a)) b, mod_count2, mult_count2 = mon.mod_bin(c, d, q) print('c**d mod q = {0}'.format(b)) #print('\na = {0}, b = {1}'.format(a, b)) mod_count = mod_count1 + mod_count2 mult_count = mult_count1 + mult_count2 aq, mult_count = bin.multiply(a, Q, mult_count) bp, mult_count = bin.multiply(b, P, mult_count) aqbp = aq + bp ans, mod_count = bin.modulo(aqbp, N, mod_count) """ #print('================= CRT(c:{0}, d:{1}, N:{2}, p:{3}, q:{4}) ================='.format(c, d, N, p, q)) #c_p = c % p c_p, mod_count = bin.modulo(c, p, mod_count) #print('c_p = c % p = {0} % {1} = {2}'.format(c, p, c_p)) print('d_p = d % (p-1) = {0} % {1} = {2}'.format(d, p - 1, d_p)) print('d_pの2進数表現 = {0}'.format(bin.binary_d(d_p))) #c_q = c % q c_q, mod_count = bin.modulo(c, q, mod_count) #print('c_q = c % q = {0} % {1} = {2}'.format(c, q, c_q)) print('d_q = d % (q-1) = {0} % {1} = {2}'.format(d, q - 1, d_q)) print('d_qの2進数表現 = {0}'.format(bin.binary_d(d_q))) m_p, mod_count1, mult_count1, _, _, _, _ = mon.mod_bin(c_p, d_p, p) #print('(c_p)**(d_p) mod p = {0}'.format(m_p)) m_q, mod_count2, mult_count2, _, _, _, _ = mon.mod_bin(c_q, d_q, q) #print('(c_q)**(d_q) mod q = {0}'.format(m_q)) mod_count += (mod_count1 + mod_count2) mult_count += (mult_count1 + mult_count2) x, mult_count = bin.multiply(q_dash, (m_p - m_q), mult_count) y, mod_count = bin.modulo(x, p, mod_count) z, mult_count = bin.multiply(y, q, mult_count) ans = m_q + z #ans = m_q + (q_dash * (m_p - m_q) mod p) return ans, mod_count, mult_count
def mod_bin(c, d, N): global countMM global countMC global countNG_MM global countNG_MC global MM_list global MC_list countMM = 0 countMC = 0 countNG_MM = 0 countNG_MC = 0 array_N = bin.binary_d(N) #print('\n\narray_N = {0}'.format(array_N)) length_N = len(array_N) #print('length_N = {0}'.format(length_N)) R = 2**length_N R_2 = R * R % N N_dash = mod_equal_minus_1(N, R) mod_count = 0 mult_count = 0 #print('c = {0}, d = {1}, N = {2}'.format(c, d, N)) #print('c={0}, d={1}, N={2}, R={3}, R_2={4}, N_dash={5}'.format(c,d,N,R,R_2,N_dash)) """ 質問その4:RとR_2の計算はカウント対象でない (ついでにRの計算方法があっているかを確認する). """ #print('length_N: {0}, R : {1}, R_2 : {2}, N_dash : {3}'.format(length_N, R, R_2, N_dash)) cr, mult_count = bin.multiply(c, R_2, mult_count) #print('cr = c * R_2 = {0}'.format(cr)) #print('MR(c*R_2)の実行>>>') large_C, mod_count, mult_count = MR(cr, mod_count, mult_count, N_dash, N) print('largc_C = {0}'.format(large_C)) #print('MR({1}): large_C={0}'.format(large_C, cr)) large_M = large_C array_d = bin.binary_d(d) l = len(array_d) for i in range(1, l): mm, mult_count = bin.multiply(large_M, large_M, mult_count) #print('MM = {0}'.format(mm)) #print('MR(M*M)の実行>>>') large_M, mod_count, mult_count = MR(mm, mod_count, mult_count, N_dash, N) #MM_list.append(large_M // 100000000000) #print('MR({1}) large_M={0}'.format(large_M, mm)) if array_d[i] == 1: mc, mult_count = bin.multiply(large_M, large_C, mult_count) #print('MC = {0}'.format(mc)) #print('MR(M*C)の実行>>>') large_M, mod_count, mult_count = MR(mc, mod_count, mult_count, N_dash, N) #MC_list.append(large_M // 100000000000) #print('MR({1}) large_M={0}'.format(large_M, mc)) #print('MR(M)の実行>>>') bin.flag = 0 m, mod_count, mult_count = MR(large_M, mod_count, mult_count, N_dash, N) #print('MR({1}) m={0}'.format(m, large_M)) print('countMM = {0}'.format(countMM)) print('countMC = {0}'.format(countMC)) print('countNG_MM = {0}'.format(countNG_MM)) print('countNG_MC = {0}'.format(countNG_MC)) return m, mod_count, mult_count, countMM, countMC, countNG_MM, countNG_MC
def MR(T, mod_count, mult_count, N_dash, N): global countMM global countMC global countNG_MM global countNG_MC #global flag #print('N: {0}'.format(N)) array_N = bin.binary_d(N) length_N = len(array_N) R = 2**length_N #print('R: {0}'.format(R)) #print('N_dash: {0}'.format(N_dash)) R_2 = R * R % N #print('N={0}, R={1}, R_2={2}, N_dash={3}'.format(N,R,R_2,N_dash)) #print(' ~~~~~~~~~~~~ MR(T:{0}, mod_count:{1}, mult_count:{2}, N_dash:{3}, N:{4}) ~~~~~~~~~~~~'.format(T, mod_count, mult_count, N_dash, N)) flag = bin.flag tr, mod_count = bin.modulo(T, R, mod_count) # tr <= T % R の計算 #print('tr = T % R = {0} % {1} = {2}'.format(T, R, tr)) trn, mult_count = bin.multiply(tr, N_dash, mult_count) # trn <= (T % R) * N'の計算 #print('trn = tr * N_dash = {0} * {1} = {2}'.format(tr, N_dash, trn)) m_1, mod_count = bin.modulo(trn, R, mod_count) # m_1 <= ((T % R) * N') % Rの計算 #print('m_1 = trn % R = {0} % {1} = {2}'.format(trn, R, m_1)) mn, mult_count = bin.multiply(m_1, N, mult_count) #print('mn = m_1 * N = {0} * {1} = {2}'.format(m_1, N, mn)) """ 質問その2:m_2計算時の「//」はmod_countをインクリメントしなくて良いか. """ m_2 = (T + mn) // R #print('m_2 = (T + mn)//R = ({0} + {1})//{2} = {3}'.format(T, mn, R, m_2)) if m_2 <= N: #print('MRにおいてmod_countを余分にインクリメントしませんでした.\n') #print('@@@@@@@ flag = {0}'.format(flag)) #countNG += 1 #print('NO: countNG = {0}'.format(countNG)) if flag == 1: countNG_MM += 1 #print('NO: countNG = {0}'.format(countNG)) #print('') else: countNG_MC += 1 #print('余分に剰余計算しなかった結果 = {0}'.format(m_2)) return m_2, mod_count, mult_count else: #print('MRにおいてmod_countを余分にインクリメントしました. m_2 = {0}'.format(m_2)) """ 質問その3:m_2 > Nのとき, mod_countを1インクリメントすべきかどうか. """ if flag == 1: countMM += 1 #print('```````````````````````````countMM: m_2 = m_2 - N = {0} - {1} = {2}\n'.format(m_2, N, m_2-N)) #print('YES: countMM={0}'.format(countMM)) else: countMC += 1 #print('///////////////////////////countMC: m_2 = m_2 - N = {0} - {1} = {2}\n'.format(m_2, N, m_2-N)) #print('YES: countMC={0}'.format(countMC)) mod_count += 1 #print('m_2 = m_2 - N = {0} - {1} = {2}\n'.format(m_2, N, m_2-N)) return m_2 - N, mod_count, mult_count
# # ModBinを実行するプログラム # import math import main import binary as bin p = main.p q = main.q N = main.N phi_N = main.phi_N array_N = bin.binary_d(N) length_N = len(array_N) R = 2**length_N R_2 = R * R % N countMM = 0 countMC = 0 countNG_MM = 0 countNG_MC = 0 MM_list = [] MC_list = [] # # N*(N') mod R = -1となるN'を返す. # """ def mod_equal_minus_1(N, R):