def transformPsi(bl): """ Transforms block bl according following rule: transformP(y16|y15|...|y1)=(y1+y2+y3+y4+y13+y16)|y16|y15|..|y3|y2 """ y = [] bl_cut = bl for i in range(16): y.append(cryptBlocks.getRight(bl_cut, 16, True)) bl_cut = cryptBlocks.cutRight(bl_cut, 16, True) resBl = 0 leftSide = y[0]^y[1]^y[2]^y[3]^y[12]^y[15] resBl = cryptBlocks.concat(leftSide, bl>>16, 240) return resBl
def transformP(bl): """ Transforms block bl according following rule: transformP(y32|y31|...|y1)=yfi(32)|yfi(31)|...|yfi(1) """ fi = getFi() y = [] for i in range(32): y.append(cryptBlocks.getRight(bl, 8, True)) bl = cryptBlocks.cutRight(bl, 8, True) resBl = 0 for i in range(1,33): resBl = cryptBlocks.concat(resBl, y[fi[33-i]-1], 8) return resBl
def functionF(A, K): """ The function f(Ai, Ki). Ai - righ side of the block, Ki - key. """ if makeReport: reporter.addBold(" шаговая функция(%s, %s)"%(hex(A), hex(K))) # 1. Summing modulo 2^32 # summ = (A + K) % (2**32) summ = A+K # 0x100000000 - 2**32 if summ > 0x100000000: summ = summ - 0x100000000 if makeReport: reporter.add(" Сумма по модулю 2<sup>32</sup>: "+hex(summ)+"<br>") # summ = (A+K) - (((A+K)>>32)<<32) # 2. Replacing S-Box blocks = [] # splitting by 4 bits. youngest bits will be blocks[0] for i in range(8): blocks.append(cryptBlocks.getRight(summ, 4, True)) summ = cryptBlocks.cutRight(summ, 4, True) # blocks.reverse() # if makeReport: # reporter.addList([hex(x) for x in blocks]) # replacing... blocksReplaced = blocks if makeReport: reporter.add(" Заменяем по каждые 4 бита согласно таблице замен (S-box):<br>") for i in range(8): if makeReport: reporter.add(" %d. %s(%d) → %s(%d)<br>"%(i+1, hex(blocks[i]),blocks[i],hex(Sbox[i][blocks[i]]),Sbox[i][blocks[i]])) blocksReplaced[i] = Sbox[i][blocks[i]] res = cryptBlocks.getIntegerFromHalfByteArray(blocksReplaced) if makeReport: reporter.add(" В результате замены имеем: %s<br>"%(hex(res),)) # 3. Cycle shift 11 res = cryptBlocks.shiftCycleLeft(res, 11,32) if makeReport: reporter.add(" Циклический сдвиг влево на 11 бит: %s<br>"%(hex(res),)) return res
def genKeys(key): """ Generates key list K1..K32. Every K_j is 4 bytes(or 32 bit) long. We would have to just iterate for each K element. """ K = [] # K1..K8 key_cut = key for i in range(8): K.append(cryptBlocks.getRight(key_cut, 4)) key_cut = cryptBlocks.cutRight(key_cut, 4) #K9..K24 for j in range(2): for i in range(8): K.append(K[i]) #K25..K32 for i in range(8): K.append(K[7-i]) return K
def stepFunction(Hin, m): """ Step function f(Hin, m) """ if makeReport: reporter.addHeader2("stepFunction(%s,%s)"%(hex(Hin), hex(m))) # step1. generating keys C2 = 0 C3 = 0xff00ffff000000ffff0000ff00ffff0000ff00ff00ff00ffff00ff00ff00ff00 C4 = 0 U = Hin V = m W = U ^ V K1 = transformP(W) U = transformA(U)^C2 V = transformA(transformA(V)) W = U ^ V K2 = transformP(W) U = transformA(U)^C3 V = transformA(transformA(V)) W = U ^ V K3 = transformP(W) U = transformA(U)^C4 V = transformA(transformA(V)) W = U ^ V K4 = transformP(W) if makeReport: reporter.addBold("Generated keys:") reporter.addList([hex(K1), hex(K2), hex(K3), hex(K4)]) # step2. crypting tranformation Hin_cut = Hin # we need Hin for the next step, but this step cuts Hin h1 = cryptBlocks.getRight(Hin_cut, 64, True) Hin_cut = cryptBlocks.cutRight(Hin_cut, 64, True) h2 = cryptBlocks.getRight(Hin_cut, 64, True) Hin_cut = cryptBlocks.cutRight(Hin_cut, 64, True) h3 = cryptBlocks.getRight(Hin_cut, 64, True) Hin_cut = cryptBlocks.cutRight(Hin_cut, 64, True) h4 = cryptBlocks.getRight(Hin_cut, 64, True) Hin_cut = cryptBlocks.cutRight(Hin_cut, 64, True) s1 = gost28147.cryptBlock(h1, K1) s2 = gost28147.cryptBlock(h2, K2) s3 = gost28147.cryptBlock(h3, K3) s4 = gost28147.cryptBlock(h4, K4) S = s4 S = cryptBlocks.concat(S, s3, 64) S = cryptBlocks.concat(S, s2, 64) S = cryptBlocks.concat(S, s1, 64) if makeReport: reporter.addBold("Crypting transformation:") reporter.addList([ "gost28147(%s,%s)=%s"%(hex(h1),hex(K1),hex(s1)), "gost28147(%s,%s)=%s"%(hex(h2),hex(K2),hex(s2)), "gost28147(%s,%s)=%s"%(hex(h3),hex(K3),hex(s3)), "gost28147(%s,%s)=%s"%(hex(h4),hex(K4),hex(s4)), ]) reporter.addBold("S="+hex(S)) # Step 3. Shuffle transforming. Hout = transformPsi(S) for i in range(12): Hout = transformPsi(Hout) Hout = transformPsi(Hout ^ m)^Hin for i in range(61): Hout = transformPsi(Hout) return Hout