def decrypt(encrypted_bv, key): PassPhrase = "Hopes and dreams of a million years" BLOCKSIZE = 16 numbytes = BLOCKSIZE // 8 # Reduce the passphrase to a bit array of size BLOCKSIZE: bv_iv = BitVector(bitlist = [0]*BLOCKSIZE) for i in range(0,len(PassPhrase) // numbytes): textstr = PassPhrase[i*numbytes:(i+1)*numbytes] bv_iv ^= BitVector( textstring = textstr ) # Reduce the key to a bit array of size BLOCKSIZE: key_bv = BitVector(bitlist = [0]*BLOCKSIZE) key_bv = BitVector(bitstring = key) # Create a bitvector for storing the decrypted plaintext bit array: msg_decrypted_bv = BitVector( size = 0 ) # Carry out differential XORing of bit blocks and decryption: previous_decrypted_block = bv_iv for i in range(0, len(encrypted_bv) // BLOCKSIZE): bv = encrypted_bv[i*BLOCKSIZE:(i+1)*BLOCKSIZE] temp = bv.deep_copy() bv ^= previous_decrypted_block previous_decrypted_block = temp bv ^= key_bv msg_decrypted_bv += bv # Extract plaintext from the decrypted bitvector: return msg_decrypted_bv.get_text_from_bitvector()
def AES_decrypt(key) : decrypted_data = BitVector(size=0) #Split the input key into 4, 32 bit words words_4 = get_first_four_words(BitVector( textstring = key )) #Get the key schedule based on input key key_sch = Key_Schedule(words_4) round_keys = key_sch.round_keys #Get input data in 128 bit blocks at a time encrypted_blocks = get_input_blocks("encrypted.txt") for block in encrypted_blocks : #Do the pre-round processing state_array = convert_block_to_state_array(block) state_array = add_round_key(state_array, round_keys[10]) state_array = inv_shift_rows(state_array) state_array = inv_substitute_bytes(state_array) #Do the 10 rounds of processing for i in reversed(range(1,10)) : state_array = add_round_key(state_array, round_keys[i]) state_array = inv_mix_columns(state_array) state_array = inv_shift_rows(state_array) state_array = inv_substitute_bytes(state_array) #Append decrypted data state_array = add_round_key(state_array, round_keys[0]) decrypted_data += convert_state_array_to_128bits(state_array) #Write decrypted data to file FILEOUT = open( "decrypted.txt", 'wb' ) decrypted_data.write_to_file(FILEOUT) FILEOUT.close()
def get_c_byte_step( byte, encrypt ) : byte = byte.reverse() if(encrypt) : c_d_byte = BitVector( bitstring = '11000110' ) xor_base = BitVector( bitstring = '10001111' ) else : c_d_byte = BitVector( bitstring = '10100000' ) xor_base = BitVector( bitstring = '00100101' ) newByte = BitVector( bitstring = '00000000' ) xor_lists = [xor_base.deep_copy() >> x for x in range(8)] for i, xor_list in enumerate(xor_lists) : temp = xor_list & byte newBit = get_xor_of_single_bv(temp) newBit = newBit ^ c_d_byte[i] newByte[i] = newBit newByte = newByte.reverse() return newByte
def createKeys(eVAL): ## Setup the prime generator pg = PrimeGenerator(bits=128, debug=0) while(True): p = pg.findPrime() q = pg.findPrime() ## Check p and q are different if p == q: continue ## Check left two MSB's are 1 (bin command returns 0b appended at front) if not (bin(p)[2] and bin(p)[3] and bin(q)[2] and bin(q)[3]): continue ## Check that the totients of p and q are co-prime to e if (bgcd(p-1, eVAL) != 1) or (bgcd(q-1, eVAL) !=1): continue break ## Calculate modulus n = p * q ## Calculate totient of n tn = (p - 1) * (q-1) modBV = BitVector(intVal = tn) eBV = BitVector(intVal = eVAL) ## Calculate multiplicative inverse d = eBV.multiplicative_inverse(modBV) d = int(d) ## Create public and private sets public, private = [eVAL, n], [d, n] ## Return items return public, private, p, q, eVAL
def hadamard_mat(num_bits, is_quantum=True): """ This function return a numpy array with the num_bits-fold tensor product of the 2 dim Hadamard matrix H. If is_quantum=True (False, resp.), it returns a complex (real, resp.) array. Parameters ---------- num_bits : int is_quantum : bool Returns ------- """ num_rows = (1 << num_bits) norma = np.sqrt(num_rows) if is_quantum: ty = complex else: ty = float mat = np.full((num_rows, num_rows), fill_value=1/norma, dtype=ty) bvec = BitVector(num_bits, 0) for j in range(num_rows): for k in range(num_rows): bvec.dec_rep = j & k if bvec.get_num_T_bits() % 2 == 1: mat[j, k] = - mat[j, k] return mat
def CRT_simplify(data, d, n, p, q) : Vp = binary_exp(data, d, p) Vq = binary_exp(data, d, q) # Set all values for chinese remainder thm as stated in notes # for better understanding later M = n m1 = p m2 = q M1 = M / m1 M2 = M / m2 # Convert the numbers to BitVector for easy MI m1_bv = BitVector(intVal=m1) m2_bv = BitVector(intVal=m2) M1_bv = BitVector(intVal=M1) M2_bv = BitVector(intVal=M2) M1_inv = int(M1_bv.multiplicative_inverse(m1_bv)) M2_inv = int(M2_bv.multiplicative_inverse(m2_bv)) Xp = q * M1_inv Xq = p * M2_inv result = (Vp*Xp + Vq*Xq) % n return result
def decrypt(filename, private, p, q): decrypted = [] ## Open file and get the contents encrypted = openFile(filename, False) ## Using the chinese remainder theorem ## pCRT = C^d mod p ## qCRT = C^d mod q pCRT , qCRT = [], [] for block in encrypted: pCRT.append(pow(block, private[0], p)) qCRT.append(pow(block, private[0], q)) ## Geting bitvector versions of the p * q values for their multiplicative inverses pBV = BitVector(intVal = p) qBV = BitVector(intVal = q) ## Xp = q * (q^-1 mod p) ## Xq = p * (p^-1 mod q) pX = q * int(qBV.multiplicative_inverse(pBV)) qX = p * int(pBV.multiplicative_inverse(qBV)) ## C^d mod n = (VpXp + VqXq) mod n for i in range(len(encrypted)): decrypted.append(((pCRT[i] * pX) + (qCRT[i] * qX)) % private[1]) return decrypted
def gen_w4(w3,ri): w3r = w3 << 8 print ("w"+str((ri-1)*4+3)+" after one byte circular rotation") print (w3r.get_hex_string_from_bitvector()) k_subbytes = BitVector(size = 0) for i in range(4): row = w3r[i*8:i*8+4].int_val() print (row), col = w3r[i*8+4:i*8+8].int_val() print (col), k_sub = BitVector(intVal = sbox[16*row+col], size = 8) print(k_sub), print(k_sub.get_hex_string_from_bitvector()) k_subbytes += k_sub print ("k_subbytes") print (k_subbytes), print (k_subbytes.get_hex_string_from_bitvector()) rcbv = BitVector(intVal = Rcon[ri], size = 32) print (rcbv) kg = k_subbytes ^ rcbv print ("kg") print (kg), print (kg.get_hex_string_from_bitvector()) return kg
def build_s_box(encrypt_or_decrypt): AES_modulus = BitVector(bitstring='100011011') c = BitVector(bitstring='01100011') d = BitVector(bitstring='00000101') new_sub_bytes = [] if (encrypt_or_decrypt == 'e'): for i in range(0, 256): # Build lookup table a = BitVector(intVal = i, size=8).gf_MI(AES_modulus, 8) if i != 0 else BitVector(intVal=0) # Byte scrambling a1,a2,a3,a4 = [a.deep_copy() for x in range(4)] a ^= (a1 >> 4) ^ (a2 >> 5) ^ (a3 >> 6) ^ (a4 >> 7) ^ c new_sub_bytes.append(int(a)) else: for i in range(0, 256): b = BitVector(intVal = i, size=8) # byte scrambling b1,b2,b3 = [b.deep_copy() for x in range(3)] b = (b1 >> 2) ^ (b2 >> 5) ^ (b3 >> 7) ^ d check = b.gf_MI(AES_modulus, 8) b = check if isinstance(check, BitVector) else 0 new_sub_bytes.append(int(b)) sub_byte_table = [] for i in range(16): sub_byte_table.append([]) for j in range(16): sub_byte_table[i].append(new_sub_bytes[(i * 16) + j]) return sub_byte_table
def encrypt(self, plainText, isHex=0): if isHex==0: p=self.getRandomPrime() q=self.getRandomPrime() if not p==q: #if those two primes numbers are not the same pm1=BitVector(intVal=int(p)-1, size=128) qm1=BitVector(intVal=int(q)-1, size=128) modulo_n=p.gf_multiply(q)# this is n e=BitVector(intVal=17, size=128) #this is e MI=e.multiplicative_inverse(pm1.gf_multiply(qm1)) d=BitVector(intVal=int(MI), size=256) # this is d self.e=e self.d=d self.n=modulo_n self.p=p self.q=q print "n:",int(self.n) print "e:",int(self.e) print "d:",int(self.d) print "p:",int(self.p) print "q:",int(self.q) strr=RSA.getBitVectorFromText(plainText)#just getting BitVector from the text print "plain text converted to int" print int(strr) C=pow(int(strr), int(e), int(modulo_n)) cipher=BitVector(intVal=C, size=256) cipher= RSA.getTextFromBitVector(cipher) return cipher
def inv_shift_rows(packager): print ("shift_rows begin###############") print (packager.get_hex_string_from_bitvector()) state_array = [] for i in range(4): row_array = BitVector(size=0) for j in range(4): temp = packager[(32*j+8*i):(32*j+8*i+8)] row_array += temp state_array.append(row_array) print ("state_array") for i in range(len(state_array)): print (state_array[i].get_hex_string_from_bitvector()) state_array[1] >> 8 state_array[2] >> 16 state_array[3] >> 24 print ("state_array after") for i in range(len(state_array)): print (state_array[i].get_hex_string_from_bitvector()) shiftbv = BitVector(size=0) for j in range(4): for i in range(4): shiftbv += state_array[i][j*8:j*8+8] print ("shiftbv") print (shiftbv.get_hex_string_from_bitvector()) return shiftbv
def change_one_bit(): subprocess.call(['cp message.txt temp.tmp'],shell=True) file_size = os.path.getsize(input_file) num_blocks = file_size / 8 if file_size % 8 != 0: with open(input_file,"a") as filein: for i in range(0,file_size % 8): filein.write(" ") for i in range(0,num_blocks): #subprocess.call(['cp temp.tmp temp2.tmp'],shell=True) bv = BitVector( filename = "temp.tmp" ) os.remove("message.txt") FILEOUT = open("message.txt",'ab') for j in range(0,num_blocks): bitvcec = bv.read_bits_from_file( 64 ) if j == i: rand = randint(0,63) bitvec[rand] ^= 1 bitvec.write_to_file(FILEOUT) FILEOUT.close() subprocess.call(['./DES_baio.py'],shell=True) os.close(filehandle) os.remove(input_file) move(final, input_file)
def GenerateSubTable(modeChar): #Table Generation Variables modulus_poly = BitVector(bitstring = '100011011') #irreducible polynomial used in AES --> (x^8 + x^4 + x^3 + x + 1) byte_c = BitVector(bitstring = '01100011') #Encryption Mangle-Byte byte_d = BitVector(bitstring = '00000101') #Decryption Mangle-Byte scrambledBV = BitVector(size = 8) #Initialize 16x16 Sub-Table with all 0 Bit-Vectors zeroBV = BitVector(size = 8) LookUpTable = [[zeroBV.deep_copy() for x in range(16)] for y in range(16)] #Set Each Table Entry to Multiplicative Inverse (in GF(2^8)) of Bit-Vector Concatenation of Row and Column 4-bit Bit-Vectors for x in range(16): for y in range(16): rowBV = BitVector(intVal=x, size=4) #Creat Bit Vector for Row Value colBV = BitVector(intVal=y, size=4) #Creat Bit Vector for Column Value tableBV_entry = rowBV + colBV #Perform MI & Bit-Mangling on Table Entries #If Mode is Encryption... if modeChar == 'E': #Only find MI of all bit-vectors except 0 if (x != 0) or (y != 0): tableBV_entry = tableBV_entry.gf_MI(modulus_poly, 8) #Determine MI of table entry Bit-Vector for bit_ind in range(0, 8): newBit = tableBV_entry[bit_ind]^tableBV_entry[(bit_ind+1)%8]^tableBV_entry[(bit_ind+2)%8]^tableBV_entry[(bit_ind+3)%8]^tableBV_entry[(bit_ind+4)%8]^byte_c[bit_ind] scrambledBV[bit_ind] = newBit #If Mode is Decryption... else: for bit_ind in range(0, 8): newBit = tableBV_entry[(bit_ind+6)%8]^tableBV_entry[(bit_ind+3)%8]^tableBV_entry[(bit_ind+1)%8]^byte_d[bit_ind] scrambledBV[bit_ind] = newBit #Only find MI of all bit-vectors except 0 if int(scrambledBV) != 0: scrambledBV = scrambledBV.gf_MI(modulus_poly, 8) #Determine MI of table entry Bit-Vector LookUpTable[x][y] = copy.deepcopy(scrambledBV) return LookUpTable
def diffusion_or_confusion(RE,LE,encrypt_or_decrypt,rkey,s_box): bitvec = BitVector(size=64) for i in range(16): ## write code to carry out 16 rounds of processing TMP = RE ## Expansion_permutation RE = RE.permute(expansion_permutation) # Get the order of key right if encrypt_or_decrypt == "encrypt": RE = RE ^ rkey[i] elif encrypt_or_decrypt == "decrypt": RE = RE ^ rkey[15 - i] ## Do the S_boxes subsititution k=0 output = BitVector(size = 0) for ct in range(8): row = RE[k]*pow(2,1) + RE[k+5]*pow(2,0) col = RE[k+1]*pow(2,3) + RE[k+2]*pow(2,2)+ RE[k+3]*pow(2,1) + RE[k+4]*pow(2,0) sbox_val = s_box[ct][row][col] sbox_bv = BitVector(intVal = int(sbox_val), size = 4) output += sbox_bv k += 6 ## Permutation with P-Box output = output.permute(p_box_permutation) ## XOR with original LE RE = LE ^ output LE = TMP ## Add RE and LE up bitvec = RE + LE return bitvec
def pattern_to_dest(self,pattern,X): # return -1 is reserved for random bit_len = math.ceil(math.log(self.mesh_width*self.mesh_height,2)) bv = BitVector(intVal=X,size=bit_len) if(pattern==Traffic_Patterns.random): return -1; elif(pattern==Traffic_Patterns.bit_complement): return int(~bv) elif(pattern==Traffic_Patterns.bit_reverse): return int(bv.reverse()) elif(pattern==Traffic_Patterns.bit_rotation): return int(bv<<1) elif(pattern==Traffic_Patterns.transpose): return 1 elif(pattern==Traffic_Patterns.shuffle): t = bv[bit_len-1] bv[bit_len-1] = bv[0] bv[0] = t return int(bv) elif(pattern==Traffic_Patterns.manual): return self.PE_dest[X]
def AES_encrypt(filename, key) : encrypted_data = BitVector(size=0) words_4 = get_first_four_words(BitVector( textstring = key )) key_sch = Key_Schedule(words_4) round_keys = key_sch.round_keys input_blocks = get_input_blocks(filename) for block in input_blocks : state_array = convert_block_to_state_array(block) state_array = add_round_key(state_array, round_keys[0]) for i in range(10) : state_array = substitute_bytes(state_array) state_array = shift_rows(state_array) if not (i == 9): state_array = mix_columns(state_array) state_array = add_round_key(state_array, round_keys[i+1]) encrypted_data += convert_state_array_to_128bits(state_array) FILEOUT = open( "encrypted.txt", 'wb' ) encrypted_data.write_to_file(FILEOUT) FILEOUT.close()
def AES_dec(key, message, fileout): ## Get the key kBV = BitVector( textstring = inKey ) bv = BitVector( filename = message ) FILEOUT = open(fileout, 'wb') stateArray = [[0 for x in range(4)] for x in range(4)] nextArray = [[0 for x in range(4)] for x in range(4)] while(bv.more_to_read): bitvec = bv.read_bits_from_file(128) ## Ensure that length is 128, if not pad if((bitvec.length() % 128) != 0): bitvec.pad_from_right(128-(bitvec.length() % 128)) getKeySchedule(bitvec) bitvec = addRoundKey(bitvec, roundKeys[10]) for i in range(4): for j in range(4): nextArray[j][i] = hex(bitvec[32*i + 8*j:32*i+8*(j+1)].int_val()) ## Different process for AES_dec for x in range(9): stateArray = nextArray stateArray = InvShiftRows(stateArray) stateArray = InvSubBytes(stateArray) stateArray = addRoundKey(sAr2BV(stateArray), roundKeys[9-x]) for i in range(4): for j in range(4): nextArray[j][i] = hex(stateArray[32*i + 8*j:32*i+8*(j+1)].int_val()) nextArray = InvMixColumns(nextArray) stateArray = InvShiftRows(nextArray) stateArray = InvSubBytes(stateArray) stateArray = addRoundKey(sAr2BV(stateArray), kBV) FILEOUT.write(stateArray.get_text_from_bitvector()) FILEOUT.close()
def create_keys(): #creates the keys e = BitVector(intVal = 65537) uno = BitVector(intVal = 1) tres = BitVector(intVal = 3)#used for checking the last two bits generator = PrimeGenerator( bits = 128, debug = 0 ) p = BitVector(intVal = generator.findPrime()) while (p[0:2] != tres and int (e.gcd(BitVector(intVal = int(p)-1))) != 1): p = BitVector(intVal = generator.findPrime()) q = BitVector(intVal = generator.findPrime()) while (q[0:2] != tres and int (e.gcd(BitVector(intVal = int(q)-1))) != 1 and p != q): q = BitVector(intVal = generator.findPrime()) n = int(p) *int( q) n = BitVector(intVal = n) to = BitVector(intVal =((int(p)-1)*(int(q)-1))) d = e.multiplicative_inverse(to) d = int(d) e = int (e) n = int (n) p = int (p) q = int (q) with open('private_key.txt', 'w') as f : f.write(str(d)+"\n") f.write(str(n)+"\n") f.write(str(p)+"\n") f.write(str(q)+"\n") with open('public_key.txt', 'w') as f: f.write(str(e)+"\n") f.write(str(n)+"\n")
def des(encrypt_or_decrypt, input_file, output_file, key ): bv = BitVector( filename = input_file ) FILEOUT = open( output_file, 'wb' ) bitvec = bv.read_bits_from_file( 64 ) ## assumes that your file has an integral ## multiple of 8 bytes. If not, you must pad it. print bitvec [LE, RE] = bitvec.divide_into_two()
def decryption(message): cypher = BitVector(textstring = message) stateMatrix = cypher[:128] plaintext = BitVector(size=0) block_count = 0 num_of_blocks =len(cypher)/128 ##loop until the message is all 0s for blockNum in range(num_of_blocks): block_count = block_count+1 i=num_of_rounds-1 stateMatrix = addRoundKey(i,stateMatrix) i=i-1 while(i>=0): stateMatrix = invShiftRows(stateMatrix) stateMatrix = invSubBytes(stateMatrix) stateMatrix = addRoundKey(i, stateMatrix) if(i!=0): stateMatrix = invMixCollumns(stateMatrix) i=i-1 plaintext = plaintext+stateMatrix if(blockNum != (num_of_blocks-1)): cypher = cypher[128:] stateMatrix = cypher[:128] if(len(sys.argv)==4): print "Block count",block_count print plaintext.get_bitvector_in_hex() ascii = plaintext.get_bitvector_in_ascii() return ascii[:len(ascii)-4]
def getInput_decrypt(filein): inputlist = [] bv = BitVector( filename=filein ) while (bv.more_to_read): bitvec = bv.read_bits_from_file( 256 ) #get the encrypted data by 256 bit inputlist.append(int(bitvec)) return inputlist
def messwithfile(rightf, messedf): FILEOUT = open (messedf, 'wb') lakey = DES_flegmann.get_encryption_key() round_keys = DES_flegmann.extract_round_key(lakey) tamano = os.path.getsize(rightf) tamano = tamano / 8 bv = BitVector(filename = rightf) count = 0 tot = 0 for index in range(8): while (bv.more_to_read): bitvec = bv.read_bits_from_file( 64 ) leng = bitvec.length() pad = 64 - leng if count == index: bitvec.pad_from_right(pad) bitvec[random.randint(0,15)] ^= 1 bitvec.write_to_file(FILEOUT) count = count + 1 FILEOUT.close() bv.close_file_object() DES_flegmann.des(1, rightf, 'righte.txt',round_keys) DES_flegmann.des(1, messedf, 'messede.txt', round_keys) tot += checkdiff('righte.txt', 'messede.txt') os.remove('righte.txt') os.remove('messede.txt') return tot / 8
def sigma1(w): temp1=w>>19 temp2=w>>61 temp3=BitVector(intVal=w) temp3.shift_right(6) temp3=int(temp3) sig1=temp1^temp2^temp3 return sig1
def sigma0(w): temp1=w>>1 temp2=w>>8 temp3=BitVector(intVal=w) temp3.shift_right(7) temp3=int(temp3) sig0=temp1^temp2^temp3 return sig0
def get_encryption_key(): user_given_key = raw_input("Enter encryption key: ") while (len(user_given_key) != 8): print("Error: Encryption key must be 8 characters long. Try again.") user_given_key = raw_input("Enter encryption key: ") user_key_bv = BitVector(textstring = user_given_key) key_bv = user_key_bv.permute(key_permutation_1) return key_bv
def __init__(self): self.key="thisisdakeyof16b" #key self.v=BitVector(intVal=0, size=128) self.e=BitVector(intVal=0, size=256) self.n=BitVector(intVal=0, size=256) self.d=BitVector(intVal=0, size=256) self.p=BitVector(intVal=0, size=256) self.q=BitVector(intVal=0, size=256)
def SubWord(word): for i in range(0,32,8): temp = BitVector( intVal = subBytesTable[word[i:i+8].int_val()]) if len(temp) < 8: temp.pad_from_left(8-len(temp)) word[i:i+8] = temp return word
def get_encryption_key(): # key ## ask user for input ## make sure it satisfies any constraints on the key ## next, construct a BitVector from the key user_key_bv = BitVector(text = user-supplied_key) key_bv = user_key_bv.permute( initial_permutation ) ## permute() is a BitVector function return key_bv
def get_encryption_key(): # key ## ask user for input ## make sure it satisfies any constraints on the key with open('key.txt','r') as keyfile: user_supplied_key = keyfile.read().replace('\n','') ## next, construct a BitVector from the key user_key_bv = BitVector(textstring = user_supplied_key) key_bv = user_key_bv.permute( key_permutation_1 ) ## permute() is a BitVector function return key_bv
def des(encrypt_or_decrypt, input_file, output_file, key ): bv = BitVector( filename = input_file ) FILEOUT = open( output_file, 'w' ) while(bv.more_to_read): bitvec = bv.read_bits_from_file( 64 ) ## assumes that your file has an integral mod = bitvec.length() % 64 if not mod == 0: bitvec.pad_from_right(64 - mod) ## multiple of 8 bytes. If not, you must pad it. [LE, RE] = bitvec.divide_into_two() rkey = extract_round_key(key) for i in range(16): ## write code to carry out 16 rounds of processing TMP = RE ## Expansion_permutation RE = RE.permute(expansion_permutation) # Get the order of key right if encrypt_or_decrypt == "encrypt": RE = RE ^ rkey[i] elif encrypt_or_decrypt == "decrypt": RE = RE ^ rkey[15 - i] ## Do the S_boxes subsititution firstbit = 0 midbit = 1 lastbit = 5 newBV = BitVector(size = 0) for ct in range(8): row = 2 * RE[firstbit] + RE[lastbit] col = 8 * RE[midbit] + 4 * RE[midbit + 1] + 2 * RE[midbit + 2] + RE[midbit + 3] sbox_num = s_box[ct][row][col] sbox_bitvector = BitVector(intVal = int(sbox_num), size = 4) newBV += sbox_bitvector firstbit += 6 midbit += 6 lastbit += 6 ## Permutation with P-Box newBV = newBV.permute(p_box_permutation) ## XOR with original LE RE = LE ^ newBV LE = TMP ## Add RE and LE up bitvec = RE + LE ## Output the encryption or decryption mytext = bitvec.get_text_from_bitvector() FILEOUT.write(mytext) print mytext FILEOUT.close()
def f_t1(h, ch, s_e, Wi, Ki): return BitVector(intVal=(int(h) + int(ch) + int(s_e) + int(Wi) + int(Ki)) % (2**64), size=64)
import sys from BitVector import * #(A) from pip._vendor.distlib.compat import raw_input if len(sys.argv) is not 3: #(B) sys.exit('''Needs two command-line arguments, one for ''' '''the encrypted file and the other for the ''' '''decrypted output file''') PassPhrase = "Hopes and dreams of a million years" #(C) BLOCKSIZE = 64 #(D) numbytes = BLOCKSIZE // 8 #(E) # Reduce the passphrase to a bit array of size BLOCKSIZE: bv_iv = BitVector(bitlist=[0] * BLOCKSIZE) #(F) for i in range(0, len(PassPhrase) // numbytes): #(G) textstr = PassPhrase[i * numbytes:(i + 1) * numbytes] #(H) bv_iv ^= BitVector(textstring=textstr) #(I) # Create a bitvector from the ciphertext hex string: FILEIN = open(sys.argv[1]) #(J) encrypted_bv = BitVector(hexstring=FILEIN.read()) #(K) # Get key from user: key = None if sys.version_info[0] == 3: #(L) key = input("\nEnter key: ") #(M) else: key = raw_input("\nEnter key: ") #(N) key = key.strip() #(O)
def main(): ## prompts the user for the key key = get_encryption_key() input_file = 'message.txt' ##problem II part I bv = BitVector(filename=input_file) block_ct = 0 total_diff = 0 round_key = extract_round_key(key) while (bv.more_to_read): bitvec = bv.read_bits_from_file(64) ##count how many plaintext blocks block_ct += 1 ##make sure bitvec is 64 bits, if not, pad from right bit_ct = bitvec.length() if (bit_ct != 64): bitvec.pad_from_right(64 - bit_ct) ##modify one random bit change_bit = BitVector(intVal=(1 << random.randint(0, 63)), size=64) bitvec2 = bitvec ^ change_bit [LE, RE] = bitvec.divide_into_two() [LE2, RE2] = bitvec2.divide_into_two() cypher1 = des(LE, RE, round_key) cypher2 = des(LE2, RE2, round_key) diff_bits = (cypher1 ^ cypher2).count_bits() total_diff += diff_bits ##find average difference on one block avg_diff = total_diff / block_ct print "Average ciphertext change for plaintext change is %d" % avg_diff ##problem II part II ##store original cipher in result1 bv = BitVector(filename=input_file) result1 = BitVector(size=0) while (bv.more_to_read): bitvec = bv.read_bits_from_file(64) bit_ct = bitvec.length() if (bit_ct != 64): bitvec.pad_from_right(64 - bit_ct) [LE, RE] = bitvec.divide_into_two() cypher1 = des(LE, RE, round_key) result1 += cypher1 ##randomly change S_box for the first time and store result in result2 for i in range(8): for j in range(4): row = [] row = random.sample(range(16), 16) s_box[i][j] = row bv = BitVector(filename=input_file) result2 = BitVector(size=0) while (bv.more_to_read): bitvec = bv.read_bits_from_file(64) bit_ct = bitvec.length() if (bit_ct != 64): bitvec.pad_from_right(64 - bit_ct) [LE, RE] = bitvec.divide_into_two() cypher2 = des(LE, RE, round_key) result2 += cypher2 ##randomly change S_box for the second time and store result in result3 for i in range(8): for j in range(4): row = [] row = random.sample(range(16), 16) s_box[i][j] = row bv = BitVector(filename=input_file) result3 = BitVector(size=0) while (bv.more_to_read): bitvec = bv.read_bits_from_file(64) bit_ct = bitvec.length() if (bit_ct != 64): bitvec.pad_from_right(64 - bit_ct) [LE, RE] = bitvec.divide_into_two() cypher3 = des(LE, RE, round_key) result3 += cypher3 ##find differences and find average for one block diff_bits1 = (result1 ^ result2).count_bits() diff_bits2 = (result1 ^ result3).count_bits() avg_diff = (diff_bits1 + diff_bits2) / 2 / block_ct print "Average ciphertext change for S_box change is %d" % avg_diff ##problem II part IIII total_key = 0 ##try 5 different modified keys for ct in range(5): bv = BitVector(filename=input_file) change_bit = BitVector(intVal=(1 << random.randint(0, 63)), size=64) alter_key = key ^ change_bit round_key = extract_round_key(alter_key) result4 = BitVector(size=0) while (bv.more_to_read): bitvec = bv.read_bits_from_file(64) bit_ct = bitvec.length() if (bit_ct != 64): bitvec.pad_from_right(64 - bit_ct) [LE, RE] = bitvec.divide_into_two() cypher4 = des(LE, RE, round_key) result4 += cypher4 diff_key = (result1 ^ result4).count_bits() total_key += diff_key avg_key = total_key / 5 / block_ct print "Average ciphertext change for key change is %d" % avg_key
def mixColumns(bitVec, dec_or_enc): matrix = [[0 for i in range(4)] for i in range(4)] for i in range(4): for y in range(4): matrix[y][i] = bitVec[i * 32 + y * 8:i * 32 + y * 8 + 8] if dec_or_enc == "e": for row in [x * 32 for x in range(0, 4)]: for colm in range(4): bitVec[(colm * 8 + row) % 128:((colm * 8 + row +8)) % 129] = bitVec[(colm * 8 + row) % 128:((colm * 8 + row +8)) % 129].gf_multiply_modular(BitVector( intVal=0x02, size=8),modulous,8) \ ^ bitVec[((colm + 1) * 8 + row) % 128:(((colm + 1) * 8 + row + 8)) % 129].gf_multiply_modular(BitVector( intVal=0x03, size=8),modulous,8) \ ^ bitVec[((colm + 2) * 8 + row) % 128:(((colm + 2) * 8 + row + 8)) % 129] \ ^ bitVec[(((colm + 3) * 8 + row) % 128):((((colm + 3) * 8 + row +8)) % 129)] else: for row in [x * 32 for x in range(0, 4)]: for colm in range(4): bitVec[(colm * 8 + row) % 128:((colm * 8 + row +8)) % 129] = bitVec[(colm * 8 + row) % 129:((colm * 8 + row +8)) % 129].gf_multiply_modular(BitVector( intVal=0x0E, size=32),modulous,8) \ ^ bitVec[((colm + 1) * 8 + row) % 128:(((colm + 1) * 8 + row + 8)) % 129].gf_multiply_modular(BitVector(intVal=0x0B, size=8),modulous,8) \ ^ bitVec[((colm + 2) * 8 + row) % 128:(((colm + 2) * 8 + row + 8)) % 129].gf_multiply_modular(BitVector(intVal=0x0D, size=8),modulous,8) \ ^ bitVec[(((colm + 3) * 8 + row) % 128):((((colm + 3) * 8 + row +8)) % 129)].gf_multiply_modular(BitVector(intVal=0x09, size=8),modulous,8) for i in range(4): for y in range(4): bitVec[i * 32 + y * 8:i * 32 + y * 8 + 8] = matrix[y][i] return bitVec
h0 = BitVector(intVal=(int(h0) + int(a)) & 0xFFFFFFFFFFFFFFFF, size=64) h1 = BitVector(intVal=(int(h1) + int(b)) & 0xFFFFFFFFFFFFFFFF, size=64) h2 = BitVector(intVal=(int(h2) + int(c)) & 0xFFFFFFFFFFFFFFFF, size=64) h3 = BitVector(intVal=(int(h3) + int(d)) & 0xFFFFFFFFFFFFFFFF, size=64) h4 = BitVector(intVal=(int(h4) + int(e)) & 0xFFFFFFFFFFFFFFFF, size=64) h5 = BitVector(intVal=(int(h5) + int(f)) & 0xFFFFFFFFFFFFFFFF, size=64) h6 = BitVector(intVal=(int(h6) + int(g)) & 0xFFFFFFFFFFFFFFFF, size=64) h7 = BitVector(intVal=(int(h7) + int(h)) & 0xFFFFFFFFFFFFFFFF, size=64) # Concatenate the contents of the hash buffer to obtain a 512-element BitVector object: message_hash = h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 # Get the hex representation of the binary hash value: hash_hex_string = message_hash.getHexStringFromBitVector() output.write(hash_hex_string) return # argv[0] argv[1] argv[2] # sha512.py <name of input file to hash> <name of hashed file (output)> if __name__ == "__main__": input = sys.argv[1] output = sys.argv[2] input_file = open(input, 'r') output_file = open(output, 'w') message = input_file.read() message = BitVector(textstring=message) sha512(message, output_file) input_file.close() output_file.close()
def checkbitvector(bitvector): return int(bitvector & BitVector.BitVector(size=26, intVal=int(bitvector) - 1)) == 0
a = 0 b = 0 if response.ok: res = response.json() print(res) a, b = res['a'], res['b'] #Binary polynomials a and b else: print(response.json()) ##SOLUTION #You need to calculate c and a_inv #c = a(x)*b(x) #a_inv is inverse of a print("****************") a = bit.BitVector(bitstring=a) b = bit.BitVector(bitstring=b) c = a.gf_multiply(b) n = 8 md = bit.BitVector(bitstring='100011011') quo, rmndr = c.gf_divide_by_modulus(md, n) print("Answer of part a ") print("C(x) is: ", rmndr) print("****************") c = str(rmndr) inv_a = a.gf_MI(md, n)
#!/usr/bin/env python """AES ENCRYPTION DECRYPTION ALGO""" #Homework Number:hw04 #Name:Dimcho karakashev #ECN Login: dkarakas #Due Date: 02/10/17 from BitVector import * modulous = BitVector(bitstring="100011011") def ask_user_for_key(): key = input("Enter key:") key = key.strip() key = key[0:16] # takes care of longer keys than 16 bytes key += '0' * (16 - len(key)) # takes care of smaller length keys key_bv = BitVector(textstring=key) return key_bv def loadFile(nameOfFile): with open(nameOfFile, "r") as fileInput: rtn_file = fileInput.read().replace('\n', '') return rtn_file def subBytes(wordToSubBytes, enc_dec): """word_to_gee_2 needs to be 32 bit""" word_into_bytes = []
def sha512(data): #initialization h0 = BitVector(hexstring='6a09e667f3bcc908') h1 = BitVector(hexstring='bb67ae8584caa73b') h2 = BitVector(hexstring='3c6ef372fe94f82b') h3 = BitVector(hexstring='a54ff53a5f1d36f1') h4 = BitVector(hexstring='510e527fade682d1') h5 = BitVector(hexstring='9b05688c2b3e6c1f') h6 = BitVector(hexstring='1f83d9abfb41bd6b') h7 = BitVector(hexstring='5be0cd19137e2179') ktext = [ "428a2f98d728ae22", "7137449123ef65cd", "b5c0fbcfec4d3b2f", "e9b5dba58189dbbc", "3956c25bf348b538", "59f111f1b605d019", "923f82a4af194f9b", "ab1c5ed5da6d8118", "d807aa98a3030242", "12835b0145706fbe", "243185be4ee4b28c", "550c7dc3d5ffb4e2", "72be5d74f27b896f", "80deb1fe3b1696b1", "9bdc06a725c71235", "c19bf174cf692694", "e49b69c19ef14ad2", "efbe4786384f25e3", "0fc19dc68b8cd5b5", "240ca1cc77ac9c65", "2de92c6f592b0275", "4a7484aa6ea6e483", "5cb0a9dcbd41fbd4", "76f988da831153b5", "983e5152ee66dfab", "a831c66d2db43210", "b00327c898fb213f", "bf597fc7beef0ee4", "c6e00bf33da88fc2", "d5a79147930aa725", "06ca6351e003826f", "142929670a0e6e70", "27b70a8546d22ffc", "2e1b21385c26c926", "4d2c6dfc5ac42aed", "53380d139d95b3df", "650a73548baf63de", "766a0abb3c77b2a8", "81c2c92e47edaee6", "92722c851482353b", "a2bfe8a14cf10364", "a81a664bbc423001", "c24b8b70d0f89791", "c76c51a30654be30", "d192e819d6ef5218", "d69906245565a910", "f40e35855771202a", "106aa07032bbd1b8", "19a4c116b8d2d0c8", "1e376c085141ab53", "2748774cdf8eeb99", "34b0bcb5e19b48a8", "391c0cb3c5c95a63", "4ed8aa4ae3418acb", "5b9cca4f7763e373", "682e6ff3d6b2b8a3", "748f82ee5defb2fc", "78a5636f43172f60", "84c87814a1f0ab72", "8cc702081a6439ec", "90befffa23631e28", "a4506cebde82bde9", "bef9a3f7b2c67915", "c67178f2e372532b", "ca273eceea26619c", "d186b8c721c0c207", "eada7dd6cde0eb1e", "f57d4f7fee6ed178", "06f067aa72176fba", "0a637dc5a2c898a6", "113f9804bef90dae", "1b710b35131c471b", "28db77f523047d84", "32caab7b40c72493", "3c9ebe0a15c9bebc", "431d67c49c100d4c", "4cc5d4becb3e42b6", "597f299cfc657e2a", "5fcb6fab3ad6faec", "6c44198c4a475817" ] K = [BitVector(hexstring=x) for x in ktext] mBV = BitVector(textstring=data) # Calculate the length mLength = len(mBV) # Append the length appendBV = mBV + BitVector(bitstring="1") # Calculate the zeroes to append zeroes = [0] * ((896 - len(appendBV)) % 1024) # Pad the message padBV = appendBV + BitVector(bitlist=zeroes) # Calculate the final message final = padBV + BitVector(intVal=mLength, size=128) W = [None] * 80 # Move through all the blocks in final, by size 1024 for n in range(0, len(final), 1024): # Create the block we're using c_block = final[n:n + 1024] # Set the first 16 words based on the input W[0:16] = [c_block[i:i + 64] for i in range(0, 1024, 64)] # Generate the rest of the W as well as sigma0 and sigma1 for i in range(16, 80): # circular right shift of the 64 bits arg by n bits Wi_15 = W[i - 15] Wi_2 = W[i - 2] # Sigma functions for message schedule sigma_0 = ((Wi_15.deep_copy() >> 1) ^ (Wi_15.deep_copy() >> 8) ^ (Wi_15.deep_copy().shift_right(7))) sigma_1 = ((Wi_2.deep_copy() >> 19) ^ (Wi_2.deep_copy() >> 61) ^ (Wi_2.deep_copy().shift_right(6))) # Rest of the 80 W W[i] = BitVector(intVal=(int(W[i - 16]) + int(sigma_0) + int(W[i - 7]) + int(sigma_1)) % (2**64), size=64) # Copy in initial hash buffer a, b, c, d, e, f, g, h = h0, h1, h2, h3, h4, h5, h6, h7 # 80 rounds of processing for each 1024 block for i in range(80): # Sum a and e from notes s_a = ((a.deep_copy()) >> 28) ^ ((a.deep_copy()) >> 34) ^ ( (a.deep_copy()) >> 39) s_e = ((e.deep_copy()) >> 14) ^ ((e.deep_copy()) >> 18) ^ ( (e.deep_copy()) >> 41) # CH function ch = f_ch(e, f, g) # Maj function maj = f_maj(a, b, c) # T function t1 = f_t1(h, ch, s_e, W[i], K[i]) t2 = f_t2(s_a, maj) # Round function h = g g = f f = e e = BitVector(intVal=(int(d) + int(t1)) % (2**64), size=64) d = c c = b b = a a = BitVector(intVal=(int(t1) + int(t2)) % (2**64), size=64) # Final addition of beginning hash buffer to post 80 rounds h0 = BitVector(intVal=(int(h0) + int(a)) % (2**64), size=64) h1 = BitVector(intVal=(int(h1) + int(b)) % (2**64), size=64) h2 = BitVector(intVal=(int(h2) + int(c)) % (2**64), size=64) h3 = BitVector(intVal=(int(h3) + int(d)) % (2**64), size=64) h4 = BitVector(intVal=(int(h4) + int(e)) % (2**64), size=64) h5 = BitVector(intVal=(int(h5) + int(f)) % (2**64), size=64) h6 = BitVector(intVal=(int(h6) + int(g)) % (2**64), size=64) h7 = BitVector(intVal=(int(h7) + int(h)) % (2**64), size=64) hash_buff = h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 hash_hex = hash_buff.get_hex_string_from_bitvector() return hash_hex, hash_buff
## gen_key_schedule.py ## Avi Kak (April 10, 2016, bug fix: January 27, 2017) ## This script is for demonstrating the AES algorithm for generating the ## key schedule. ## It will prompt you for the key size, which must be one of 128, 192, 256. ## It will also prompt you for a key. If the key you enter is shorter ## than what is needed for the AES key size, we add zeros on the right of ## the key so that its length is as needed by the AES key size. import sys from BitVector import * AES_modulus = BitVector(bitstring='100011011') def main(): key_words = [] keysize, key_bv = get_key_from_user() if keysize == 128: key_words = gen_key_schedule_128(key_bv) elif keysize == 192: key_words = gen_key_schedule_192(key_bv) elif keysize == 256: key_words = gen_key_schedule_256(key_bv) else: sys.exit("wrong keysize --- aborting") key_schedule = [] print(
import BitVector import unittest bv1 = BitVector.BitVector(bitstring='00110011') bv2 = BitVector.BitVector(bitlist=[1, 1, 1, 1, 0, 0, 1, 1]) bv3 = BitVector.BitVector(bitstring='00000000111111110000000') bv4 = BitVector.BitVector(bitstring='') bv5 = BitVector.BitVector(size=0) logicTests = [ ((bv1, bv2, '&'), '00110011'), ((bv1, bv3, '&'), ''), ((bv1, bv4, '&'), ''), ((bv1, bv5, '&'), ''), ((bv1, bv2, '|'), '11110011'), ((bv1, bv3, '|'), ''), ((bv1, bv4, '|'), ''), ((bv1, bv5, '|'), ''), ((bv1, '', '~'), '11001100'), ] class BooleanLogicTestCase(unittest.TestCase): def checkLogicOp(self): print("\nTesting Boolean operators") for args, expected in logicTests: try: op = args[2] if (op == '&'): actual = args[0] & args[1] elif (op == '|'):
def CRT(int_block, p, q, d, n): Vp = pow(int_block, d, p) Vq = pow(int_block, d, q) Xp = q * int(BitVector(intVal=q).multiplicative_inverse(BitVector(intVal=p))) Xq = p * int(BitVector(intVal=p).multiplicative_inverse(BitVector(intVal=q))) return (Vp * Xp + Vq * Xq) % n
def des(encrypt_or_decrypt, input_file, output_file, key): new_bv = BitVector(size=64) new_bv1 = BitVector(size=64) bv = BitVector(filename=input_file) FILEOUT = open(output_file, 'w') FILE = open("out1.txt", 'w') count = 0 ## counts number of times the while loop runs sum = 0 ## sums number of bits changed across all the blocks sum1 = 0 ## sums number of bits changed across all the blocks->confusion while (bv.more_to_read): bitvec = bv.read_bits_from_file( 64) ## assumes that your file has an integral bitvec.pad_from_right( 64 - len(bitvec)) ## multiple of 8 bytes. If not, you must pad it. [LE, RE] = bitvec.divide_into_two() ### diffusion ### bit = randint(0, 31) #generates index of the random bit to be changed diff_bv = RE.deep_copy() #new bitvector generated to measure diffusion if diff_bv[bit] == 0: diff_bv[bit] = 1 else: diff_bv[bit] = 0 ###################### ### confusion ### bit1 = randint(0, 47) diff_key = key.deep_copy() if diff_key[bit1] == 0: diff_key[bit1] = 1 else: diff_key[bit1] = 0 ###################### rkey = extract_round_key(key) rkey1 = extract_round_key(diff_key) ## generating different bitvector accounting confusion and diffusion new_bv = diffusion_or_confusion(diff_bv, LE, encrypt_or_decrypt, rkey, s_box) new_bv1 = diffusion_or_confusion(RE, LE, encrypt_or_decrypt, rkey1, s_box) for i in range(16): ## write code to carry out 16 rounds of processing TMP = RE ## Expansion_permutation RE = RE.permute(expansion_permutation) # Get the order of key right if encrypt_or_decrypt == "encrypt": RE = RE ^ rkey[i] elif encrypt_or_decrypt == "decrypt": RE = RE ^ rkey[15 - i] ## Do the S_boxes subsititution k = 0 output = BitVector(size=0) for ct in range(8): row = RE[k] * pow(2, 1) + RE[k + 5] * pow(2, 0) col = RE[k + 1] * pow(2, 3) + RE[k + 2] * pow( 2, 2) + RE[k + 3] * pow(2, 1) + RE[k + 4] * pow(2, 0) sbox_val = s_box[ct][row][col] sbox_bv = BitVector(intVal=int(sbox_val), size=4) output += sbox_bv k += 6 ## Permutation with P-Box output = output.permute(p_box_permutation) ## XOR with original LE RE = LE ^ output LE = TMP ## Add RE and LE up bitvec = RE + LE new_bv ^= bitvec new_bv1 ^= bitvec sum += new_bv.count_bits() count += 1 sum1 += new_bv1.count_bits() ## Output the encryption or decryption mytext = bitvec.get_text_from_bitvector() FILEOUT.write(mytext) print 'Average number of bits changed for diffusion is', sum / count print 'Average number of bits changed for confusion is', sum1 / count FILEOUT.close()
def f_t2(s_a, maj): return BitVector(intVal=(int(s_a) + int(maj)) % (2**64), size=64)
def createbitvector(phrase): bitvector = BitVector.BitVector(size=26) for letter in phrase: x = lettertoint(letter) bitvector = toggle(bitvector, x) return bitvector
def des(encrypt_or_decrypt, input_file, output_file, key): if (encrypt_or_decrypt == "encrypt" or encrypt_or_decrypt == "decrypt"): bv = BitVector(filename=input_file) FILEOUT = open(output_file, 'wb') bitvec = bv.read_bits_from_file( 64) ## assumes that your file has an integral ## multiple of 8 bytes. If not, you must pad it. elif (encrypt_or_decrypt == 'encrypt_nf'): bitvec = input_file #print bitvec [LE, RE] = bitvec.divide_into_two() # get all 16 round keys round_key = extract_round_key(key) if (encrypt_or_decrypt == "encrypt" or encrypt_or_decrypt == "encrypt_nf"): for i in range(16): ## write code to carry out 16 rounds of processing #print LE + RE # permute the 32 bit half, expanstion permutation RE_expanded = RE.permute(expansion_permutation) # xor the right half with the corresponding round key xored_RE = RE_expanded ^ round_key[i] # s-box subsubstitution with right half s_box_subbed_RE = s_box_sub(xored_RE) # p-box permutation with right half p_box_permuted_RE = s_box_subbed_RE.permute(p_box_permutation) # next left half is current right half LE = RE # next right half is fiestaled prev right half xor current left half RE = p_box_permuted_RE ^ LE # print binary and character encryption representation to file if (output_file != 'none'): encrypt_bin = LE + RE FILEOUT.write('Binary encryption: ' + str(encrypt_bin) + '\n') encrypt_int = int('0b' + str(encrypt_bin), 2) encrypt_char = binascii.unhexlify('%x' % encrypt_int) FILEOUT.write('Character encryption: ' + encrypt_char + '\n') if (encrypt_or_decrypt == "decrypt"): for i in range(15, -1, -1): #permute the 32 bit half, expanstion permutation RE_expanded = RE.permute(expansion_permutation) # xor the right half with the corresponding round key xored_RE = RE_expanded ^ round_key[i] # s-box subsubstitution with right half s_box_subbed_RE = s_box_sub(xored_RE) # p-box permutation with right half p_box_permuted_RE = s_box_subbed_RE.permute(p_box_permutation) # next left half is current right half LE = RE # next right half is fiestaled prev right half xor current left half RE = p_box_permuted_RE ^ LE # print binary and character encryption representation to file encrypt_bin = LE + RE FILEOUT.write('Binary decryption: ' + str(encrypt_bin) + '\n') encrypt_int = int('0b' + str(encrypt_bin), 2) encrypt_char = binascii.unhexlify('%x' % encrypt_int) FILEOUT.write('Character decryption: ' + encrypt_char + '\n') return LE + RE
import sys from BitVector import * #(A) if len(sys.argv) is not 3: #(B) sys.exit('''Needs two command-line arguments, one for ''' '''the message file and the other for the ''' '''encrypted output file''') PassPhrase = "Hopes and dreams of a million years" #(C) BLOCKSIZE = 64 #(D) numbytes = BLOCKSIZE // 8 #(E) # Reduce the passphrase to a bit array of size BLOCKSIZE: bv_iv = BitVector(bitlist = [0]*BLOCKSIZE) #(F) for i in range(0,len(PassPhrase) // numbytes): #(G) textstr = PassPhrase[i*numbytes:(i+1)*numbytes] #(H) bv_iv ^= BitVector( textstring = textstr ) #(I) # Get key from user: key = None if sys.version_info[0] == 3: #(J) key = input("\nEnter key: ") #(K) else: key = raw_input("\nEnter key: ") #(L) key = key.strip() #(M) # Reduce the key to a bit array of size BLOCKSIZE: key_bv = BitVector(bitlist = [0]*BLOCKSIZE) #(N) for i in range(0,len(key) // numbytes): #(O)
def find_d_instring(a, b): s = BitVector(intVal=a) mod = BitVector(intVal=b) d_bits = BitVector.multiplicative_inverse(s, mod) return int(str(d_bits), 2)
according to the (length, data) pairs. So it will look at the first four bytes to figure out how many bytes to read next for the algorithm name. After that it will look at the next four bytes to figure out how many bytes to examine for the public exponent, etc. ''' import sys import base64 import BitVector if len(sys.argv) != 2: sys.stderr.write("Usage: %s <public key file>\n" % sys.argv[0]) sys.exit(1) keydata = base64.b64decode(open(sys.argv[1]).read().split(None)[1]) bv = BitVector.BitVector( rawbytes = keydata ) parts = [] while bv.length() > 0: bv_length = int(bv[:32]) # read 4 bytes for length of data data_bv = bv[32:32+bv_length*8] # read the data parts.append(data_bv) bv.shift_left(32+bv_length*8) # shift the starting BV and bv = bv[0:-32-bv_length*8] # and truncate its length public_exponent = int(parts[1]) modulus = int(parts[2]) print("public exponent: ", public_exponent) print("modulus: ", modulus)
# Shulin Wang # HW 07 # ECE 404 # This is the script that process the SHA-512. Most of the codes were referenced from the lecture code # collection(SHA-256). The call syntax is: # # python3 wang_hw07.py message.txt output.txt # # The comparsion of the scrip result and hashlib result are included at the end # The 8 32-words used for initializing the 1024-bit hash buffer before we start scanning the # input message block for its hashing. See page 13 (page 17 of the PDF) of the NIST standard. # Note that the hash buffer consists of 8 64-bit words named h0, h1, h2, h3, h4, h5, h6, and h7. h0 = BitVector(hexstring='6a09e667f3bcc908') h1 = BitVector(hexstring='bb67ae8584caa73b') h2 = BitVector(hexstring='3c6ef372fe94f82b') h3 = BitVector(hexstring='a54ff53a5f1d36f1') h4 = BitVector(hexstring='510e527fade682d1') h5 = BitVector(hexstring='9b05688c2b3e6c1f') h6 = BitVector(hexstring='1f83d9abfb41bd6b') h7 = BitVector(hexstring='5be0cd19137e2179') # The K constants (also referred to as the "round constants") are used in round-based processing of # each 1024-bit input message block. There is a 64-bit constant for each of the 80 rounds. These are # as provided on page 10 (page 14 of the PDF) of the NIST standard. Note that these are ONLY USED # in STEP 3 of the hashing algorithm where we take each 1024-bit input message block through 64 # rounds of processing. K = [ "428a2f98d728ae22", "7137449123ef65cd", "b5c0fbcfec4d3b2f",
def SHA512(message, output): global h0, h1, h2, h3, h4, h5, h6, h7 # Read the message string from file with open(message, 'r') as myFile: content = myFile.read() bv = BitVector(textstring=content) # Pad the bit vector to multiple of 1024 bv = Padding(bv) # Initialize the array of "words" for storing the message schedule for a block of the input message: words = [None] * 80 for n in range(0, bv.length(), 1024): block = bv[n:n + 1024] # Create the message schedule. First 16 words of the message schedule # are obtained directly from the 1024-bit input block words[0:16] = [block[i:i + 64] for i in range(0, 1024, 64)] for i in range(16, 80): i_minus_2_word = words[i - 2] i_minus_15_word = words[i - 15] # The sigma1 function is applied to the i_minus_2_word and the sigma0 function is applied to # the i_minus_15_word: sigma0 = (i_minus_15_word.deep_copy() >> 1) ^ ( i_minus_15_word.deep_copy() >> 8) ^ ( i_minus_15_word.deep_copy().shift_right(7)) sigma1 = (i_minus_2_word.deep_copy() >> 19) ^ ( i_minus_2_word.deep_copy() >> 61) ^ ( i_minus_2_word.deep_copy().shift_right(6)) words[i] = BitVector(intVal=(int(words[i - 16]) + int(sigma1) + int(words[i - 7]) + int(sigma0)) & 0xFFFFFFFFFFFFFFFF, size=64) a, b, c, d, e, f, g, h = h0, h1, h2, h3, h4, h5, h6, h7 for i in range(80): # Hash algorithm ch = (e & f) ^ (~e & g) maj = (a & b) ^ (a & c) ^ (b & c) sum_a = (a.deep_copy() >> 28) ^ (a.deep_copy() >> 34) ^ ( a.deep_copy() >> 39) sum_e = (e.deep_copy() >> 14) ^ (e.deep_copy() >> 18) ^ ( e.deep_copy() >> 41) t1 = BitVector(intVal=(int(h) + int(ch) + int(sum_e) + int(words[i]) + int(K_bv[i])) & 0xFFFFFFFFFFFFFFFF, size=64) t2 = BitVector(intVal=(int(sum_a) + int(maj)) & 0xFFFFFFFFFFFFFFFF, size=64) h = g g = f f = e e = BitVector(intVal=(int(d) + int(t1)) & 0xFFFFFFFFFFFFFFFF, size=64) d = c c = b b = a a = BitVector(intVal=(int(t1) + int(t2)) & 0xFFFFFFFFFFFFFFFF, size=64) # Update the hash buffer h0 = BitVector(intVal=(int(h0) + int(a)) & 0xFFFFFFFFFFFFFFFF, size=64) h1 = BitVector(intVal=(int(h1) + int(b)) & 0xFFFFFFFFFFFFFFFF, size=64) h2 = BitVector(intVal=(int(h2) + int(c)) & 0xFFFFFFFFFFFFFFFF, size=64) h3 = BitVector(intVal=(int(h3) + int(d)) & 0xFFFFFFFFFFFFFFFF, size=64) h4 = BitVector(intVal=(int(h4) + int(e)) & 0xFFFFFFFFFFFFFFFF, size=64) h5 = BitVector(intVal=(int(h5) + int(f)) & 0xFFFFFFFFFFFFFFFF, size=64) h6 = BitVector(intVal=(int(h6) + int(g)) & 0xFFFFFFFFFFFFFFFF, size=64) h7 = BitVector(intVal=(int(h7) + int(h)) & 0xFFFFFFFFFFFFFFFF, size=64) # Concatenate the contents of the hash buffer message_hash = h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 with open(output, 'w') as myFile: myFile.write(message_hash.get_bitvector_in_hex())
# Homework Number: 5 # Name: Michael Tam # ECN Login: tam14 # Due Date: 02/25/2020 from BitVector import * import sys AES_modulus = BitVector(bitstring='100011011') sub_bytes_table = [] inv_sub_bytes_table = [] mul_col_const = [ BitVector(hexstring='02'), BitVector(hexstring='03'), BitVector(hexstring='01'), BitVector(hexstring='01') ] inv_col_const = [ BitVector(hexstring='0E'), BitVector(hexstring='0B'), BitVector(hexstring='0D'), BitVector(hexstring='09') ] def gen_tables(): c = BitVector(bitstring='01100011') d = BitVector(bitstring='00000101') for i in range(0, 256): # gen encryption sub box table
import sys import BitVector if BitVector.__version__ < '3.2': sys.exit("You need BitVector module of version 3.2 or higher") from BitVector import * if len(sys.argv) != 2: sys.stderr.write("Usage: %s <string to be hashed>\n" % sys.argv[0]) sys.exit(1) message = sys.argv[1] # Initialize hashcode for the first block. Subsequetnly, the # output for each 1024-bit block of the input message becomes # the hashcode for the next block of the message. h0 = BitVector(hexstring='67452301') h1 = BitVector(hexstring='efcdab89') h2 = BitVector(hexstring='98badcfe') h3 = BitVector(hexstring='10325476') h4 = BitVector(hexstring='c3d2e1f0') bv = BitVector(textstring=message) length = bv.length() bv1 = bv + BitVector(bitstring="1") length1 = bv1.length() howmanyzeros = (448 - length1) % 1024 zerolist = [0] * howmanyzeros bv2 = bv1 + BitVector(bitlist=zerolist) bv3 = BitVector(intVal=length, size=64) bv4 = bv2 + bv3
p_file.write('The value of p is:\n' + str(p)) p_file.close() q_file = open('q.txt', 'w') q_file.write('The value of q is:\n' + str(q)) q_file.close() # find n and totient(n) n = p * q tot_n = (p - 1) * (q - 1) # outputs encrypted text to correct file encrypt = open(sys.argv[3], 'w') for i in range(len(message) // 16): # calculate c_block c_block = int( BitVector(textstring=(prepend + message[16 * i:16 * i + 16]))) c_block = exp_mod(c_block, e, n) c_block = BitVector(intVal=c_block, size=256) # output text output_text = c_block.getHexStringFromBitVector() encrypt.write(output_text) encrypt.close() # decryption algorithm elif sys.argv[1] == '-d' and len(sys.argv) == 4: # reads p and q from files p_file = open('p.txt', 'r') p_file.readline() p = int(p_file.readline())
def extractMessageFromMedium( self): #the function to extract message from medium xmlString = '' #the final XML string from hopefully the extracted message(XML if valid, else random if (self.dir == 'horizontal'): #if horizontal rasterisation pix = list(self.im.getdata() ) #get the list of pixel data from object image strc = '00111100001011110110110101100101011100110111001101100001011001110110010100111110' #the bit level 80-bit representation for '</message>' #now we iterate through pixel list using their LSB values until we find </message>, and at that point we break, and use th value of the stopping byte found = 0 #to check if we find the XML string or not for i in range(0, len(pix) - 80): string = '' for j in range(i, i + 80): #since 10 characters long is </message> s = bin(pix[j])[2:].rjust( 8, '0' )[7] #get the LSB of 8bit level representation of each pixel value string = string + s if (string == strc): #we've found it found = 1 #to indicte that have indeed found an XML string break if (found == 1): #only if it is an XML string r = j % 8 #find out the remainder that j is not a multiple of 8 by, since otherwise characters only work for 8-bit multiples l = j - r m = l + 8 #to get the next byte from j if any remainder tot = '' #the total string to get th XML form out of for i in range(0, m): b = bin(pix[i])[2:].rjust(8, '0')[7] tot = tot + b xmlString = BitVector(bitstring=tot).get_text_from_bitvector( ) #the final xml string, if it is an XML string else: #if not xml string, then make the returned xml string to be empty pass else: #i.e, the rasterisation direction is vertical #now make a list that gets all the pixels in Top-Bottom, L-R direction pixels = self.im.load() #get 2D array of pixels values pix = [] #th elist to eventually store the pixel values for i in range(self.width): #for all width for j in range(self.height): #for all height p = pixels[i, j] #print(p) pix.append(p) #append the pixel values #now, its essentially the same process as horizontal strc = '00111100001011110110110101100101011100110111001101100001011001110110010100111110' #the bit level 80-bit representation for '</message>' #now we iterate through pixel list using their LSB values until we find </message>, and at that point we break, and use th value of the stopping byte found = 0 #to check if we find the XML string or not for i in range(0, len(pix) - 80): string = '' for j in range(i, i + 80): #since 10 characters long is </message> s = bin(pix[j])[2:].rjust( 8, '0' )[7] #get the LSB of 8bit level representation of each pixel value string = string + s if (string == strc): #we've found it found = 1 #to indicte that have indeed found an XML string break if (found == 1): #only if it is an XML string r = j % 8 #find out the remainder that j is not a multiple of 8 by, since otherwise characters only work for 8-bit multiples l = j - r m = l + 8 #to get the next byte from j if any remainder tot = '' #the total string to get th XML form out of for i in range(0, m): b = bin(pix[i])[2:].rjust(8, '0')[7] tot = tot + b xmlString = BitVector(bitstring=tot).get_text_from_bitvector( ) #the final xml string, if it is an XML string else: #if not xml string, then make the returned xml string to be empty pass if (xmlString == '' ): #i.e, probable xml string is empty, then return None return None #now that we have the string that could probably be the XML string else: #otherwise, return an onject of Message type extractedMessage = Message(XmlString=xmlString) return extractedMessage
def checkIfMessageExists( self ): #the function to check if the medium ctually contains a message #first check if the direction that the message is embedded in is horizontal if (self.dir == 'horizontal'): #for horizontal rasterization pix = list(self.im.getdata()) #get the list of pixels #now, we will check if the first line (the first 39 characters are '<?xml version="1.0" encoding="UTF-8"?>\n') first_line = '<?xml version="1.0" encoding="UTF-8"?>\n' #the first line to be compared with this st1 = '' #the string of bits that will make the first 39 characters extracted out of the medium for i in range(0, 312): st1 = st1 + bin(pix[i])[2:].rjust(8, '0')[ 7] #just get the LSB of each pixel 8 bit representation bv_comp = BitVector( bitstring=st1) #get the equivalent bitvector representation txt = bv_comp.get_text_from_bitvector( ) #get the equivalent text from the first 39 characters of the medium if (txt != first_line): #if the first line is not matched tup = (False, None) #the tuple is now (false, None) return tup #return the tuple indicating that the medium has no message else: #if the first line is as it is supposed to be #now, in this case, the next step will be to find out of the underlying message is a Text, GrayImage, or ColorImage) #before we proceed with the code, first of all let us note one important observation that the first 39 characters have been consumed by the statement represented byb first_line variable. The next 15 characters is the string '<message type="', and then this implies that the first (39+15)=54 characters are constant at this point. The 55th characters, however, corresponds to a 'C'(ColorImage), 'G'(GrayImage) or 'T'(Text), an this is what we will exploit to find out the type of image st2 = '' #the string of bits holding the byte representation of the 55th character for i in range(432, 440): #for the 55th character st2 = st2 + bin(pix[i])[2:].rjust( 8, '0' )[7] #just get the LSB of each pixel 8 bit representation bv_comp2 = BitVector( bitstring=st2 ) #get the equivalent bitvector representation txt2 = bv_comp2.get_text_from_bitvector( ) #get the equivalent text from the first 39 characters of the medium if (txt2 == 'C'): #if C, then ColorImage tup = (True, 'ColorImage') #make the corresponding tuple return tup #return the tuple elif (txt2 == 'G'): #if G, then GrayImage tup = (True, 'GrayImage') #make the corresponding tuple return tup #return the tuple elif (txt2 == 'T'): #if T, then Text tup = (True, 'Text') #make the corresponding tuple return tup #return the tuple else: pass else: #if vertical rasterization on the medium pixels = self.im.load() #2-D array of pixels of the medium image pix = [ ] #to store list of pixels in a vertical rasterization format for i in range( self.width): #performing a vertical scanning(L-R,T-B) for j in range(self.height): p = pixels[i, j] #get the corresponding pixel pix.append( p ) #append the number/pixel gotten into the new pixel list #now, we will check if the first line (the first 39 characters are '<?xml version="1.0" encoding="UTF-8"?>\n') first_line = '<?xml version="1.0" encoding="UTF-8"?>\n' #the first line to be compared with this st1 = '' #the string of bits that will make the first 39 characters extracted out of the medium for i in range(0, 312): st1 = st1 + bin(pix[i])[2:].rjust(8, '0')[ 7] #just get the LSB of each pixel 8 bit representation bv_comp = BitVector( bitstring=st1) #get the equivalent bitvector representation txt = bv_comp.get_text_from_bitvector( ) #get the equivalent text from the first 39 characters of the medium if (txt != first_line): #if the first line is not matched tup = (False, None) #the tuple is now (false, None) return tup #return the tuple indicating that the medium has no message else: #if the first line is as it is supposed to be #now, in this case, the next step will be to find out of the underlying message is a Text, GrayImage, or ColorImage) #before we proceed with the code, first of all let us note one important observation that the first 39 characters have been consumed by the statement represented byb first_line variable. The next 15 characters is the string '<message type="', and then this implies that the first (39+15)=54 characters are constant at this point. The 55th characters, however, corresponds to a 'C'(ColorImage), 'G'(GrayImage) or 'T'(Text), an this is what we will exploit to find out the type of image st2 = '' #the string of bits holding the byte representation of the 55th character for i in range(432, 440): #for the 55th character st2 = st2 + bin(pix[i])[2:].rjust( 8, '0' )[7] #just get the LSB of each pixel 8 bit representation bv_comp2 = BitVector( bitstring=st2 ) #get the equivalent bitvector representation txt2 = bv_comp2.get_text_from_bitvector( ) #get the equivalent text from the first 39 characters of the medium if (txt2 == 'C'): #if C, then ColorImage tup = (True, 'ColorImage') #make the corresponding tuple return tup #return the tuple elif (txt2 == 'G'): #if G, then GrayImage tup = (True, 'GrayImage') #make the corresponding tuple return tup #return the tuple elif (txt2 == 'T'): #if T, then Text tup = (True, 'Text') #make the corresponding tuple return tup #return the tuple else: pass
def embedMessageInMedium( self, message, targetImagePath ): #the function to embed the message inside of the medium image, then save the overall image to the targetImagePath image file message.getXmlString() if ( message.getMessageSize() > self.maxSize ): #basically the embedding medium cannot embed everything in the original message raise ValueError( 'The Embedding Medium is of lesser size than required to embed message!!!' ) #the TypeError message mess = message.xmlForm #get the XML string of the message #now the first task is to check if the direction is horizontal or vertical if (self.dir == 'horizontal'): #if horizontal direction tup = tuple #make the tuple to store the width and height of medium tup = (int(self.width), int(self.height)) all_pixels = list( self.im.getdata()) #get all the pixels in int form #since it is horizontal rasterisation, we can just scan through all_pixels while we try to compare the LSB for embedding the message text = '' #the bit value storing string for the message XML for i in range( 0, len(mess) ): #get the bit level representation (each 8 bit long per character) by iterating throught the entire message XML bit = bin(ord(mess[i]))[2:].rjust( 8, '0') #get the 8-bit long representation of each character text = text + bit #append to the text to get 8-bit long representation for all the characters of the message XML fin_pix = [ ] #the final pixel list that will store the changed bits (LSB) for each pixel for i in range(0, len(text)): #iterate through the entire bits bv = BitVector(intVal=all_pixels[i], size=8) #byte representation of each pixel #if LSB not equal to corresponding bit, then change if (bv[7] == 1 and text[i] != '1'): bv[7] = 0 elif (bv[7] == 0 and text[i] != '0'): bv[7] = 1 else: pass newnum = int(bv) #the changed/unchanged number fin_pix.append( newnum) #append the new number to final pixel array #now just copy the remaining pixel values from the original pixels to the final pixel list for i in range(len(fin_pix), len(all_pixels)): fin_pix.append(all_pixels[i]) #store the new pixels with the embedded data in a new image ''' c=0 for i in range(0,len(fin_pix)): if(fin_pix[i]!=all_pixels[i]): c=c+1 print('Number different: ', c) ''' im = Image.new('L', tup) im.putdata(fin_pix) im.save(targetImagePath) #finished for horizontal rasterisation else: #for vertical rasterisation tup = tuple #make the tuple to store the width and height of medium tup = (int(self.width), int(self.height)) #a=list(self.im.getdata()) #tmp = time.time(); all_pixels = self.im.load() #to get all the pixels in 2D format mat = [ [0] * self.width for i in range(self.height) ] #a 2-D list with width x height dimensions, initialized to 0 text = '' #the bit value storing string for the message XML for i in range( 0, len(mess) ): #get the bit level representation (each 8 bit long per character) by iterating throught the entire message XML bit = bin(ord(mess[i]))[2:].rjust( 8, '0') #get the 8-bit long representation of each character text = text + bit #append to the text to get 8-bit long representation for all the characters of the message XML #now, put the vertically scanned pixels into the 2D list of lists mat for i in range(0, self.width): for j in range(0, self.height): mat[j][i] = all_pixels[i, j] #now, it's time to emdeb into the mat[][] list the LSB values by comparing with the embed message #print('Time Taken: {0}\n', time.time() - tmp) count = 0 #to store the current element relative to text bit string for i in range(0, self.width): for j in range(0, self.height): if count == len( text): #if count becomes equal, then come out break else: #perform the comparison and change the pixels accordingly bv = BitVector( intVal=mat[j][i], size=8) #byte representation of each pixel #if LSB not equal to corresponding bit, then change if (bv[7] == 1 and text[count] != '1'): bv[7] = 0 elif (bv[7] == 0 and text[count] != '0'): bv[7] = 1 else: pass newnum = int(bv) #the changed/unchanged number mat[j][i] = newnum #assign the new pixel value in mat count = count + 1 #increment the value of count #now, make the final pixel list out of the mat[][] list of lists fin_pix = [] for i in range(0, self.height): for j in range(0, self.width): #print('i: ' + str(i)) #print('j: ' + str(j)) fin_pix.append(mat[i][j]) #store the new pixels with the embedded data in a new image ''' c=0 for i in range(0,len(fin_pix)): if(fin_pix[i]!=a[i]): c=c+1 print('Number different: ', c) ''' im = Image.new('L', tup) im.putdata(fin_pix) im.save(targetImagePath)
import cryptBreak from BitVector import * for key in range(0, 2**16): someRandomInteger = key # Arbitrary integer for creating a BitVector key_bv = BitVector(intVal=someRandomInteger, size=16) decryptedMessage = cryptBreak.cryptBreak('encrypted.txt', key_bv) if 'Mark Twain' in decryptedMessage: print('Encryption Broken!') print(key) break else: print('Not decrypted yet') print(key)
def sha512(message): bv = BitVector(textstring=message) h0 = BitVector(hexstring='6a09e667f3bcc908') h1 = BitVector(hexstring='bb67ae8584caa73b') h2 = BitVector(hexstring='3c6ef372fe94f82b') h3 = BitVector(hexstring='a54ff53a5f1d36f1') h4 = BitVector(hexstring='510e527fade682d1') h5 = BitVector(hexstring='9b05688c2b3e6c1f') h6 = BitVector(hexstring='1f83d9abfb41bd6b') h7 = BitVector(hexstring='5be0cd19137e2179') K = [0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817] K = [str(hex(x)[2:]) for x in K] K_bv = [BitVector(hexstring=k_constant) for k_constant in K] length = bv.length() bv1 = bv + BitVector(bitstring="1") length1 = bv1.length() howmanyzeros = (1024 - 128 - length1) % 1024 zerolist = [0] * howmanyzeros bv2 = bv1 + BitVector(bitlist=zerolist) bv3 = BitVector(intVal=length, size=128) bv4 = bv2 + bv3 # Initialize the array of "words" for storing the message schedule for a block of the input message: words = [None for i in range(80)] for n in range(0, bv4.length(), 1024): block = bv4[n:n + 1024] words[0:16] = [block[i:i + 64] for i in range(0, 1024, 64)] for i in range(16, 80): i_minus_2_word = words[i - 2] i_minus_15_word = words[i - 15] sigma0 = (i_minus_15_word.deep_copy() >> 1) ^ (i_minus_15_word.deep_copy() >> 8) ^ \ (i_minus_15_word.deep_copy().shift_right(7)) sigma1 = (i_minus_2_word.deep_copy() >> 19) ^ (i_minus_2_word.deep_copy() >> 61) ^ \ (i_minus_2_word.deep_copy().shift_right(6)) words[i] = BitVector(intVal=(int(words[i - 16]) + int(sigma1) + int(words[i - 7]) + \ int(sigma0)) & 0xFFFFFFFFFFFFFFFF, size=64) a, b, c, d, e, f, g, h = h0, h1, h2, h3, h4, h5, h6, h7 for i in range(80): ch = (e & f) ^ ((~e) & g) maj = (a & b) ^ (a & c) ^ (b & c) sum_a = ((a.deep_copy()) >> 28) ^ ((a.deep_copy()) >> 34) ^ ((a.deep_copy()) >> 39) sum_e = ((e.deep_copy()) >> 14) ^ ((e.deep_copy()) >> 18) ^ ((e.deep_copy()) >> 41) t1 = BitVector(intVal=(int(h) + int(ch) + int(sum_e) + int(words[i]) + int(K_bv[i])) & \ 0xFFFFFFFFFFFFFFFF, size=64) t2 = BitVector(intVal=(int(sum_a) + int(maj)) & 0xFFFFFFFFFFFFFFFF, size=64) h = g g = f f = e e = BitVector(intVal=(int(d) + int(t1)) & 0xFFFFFFFFFFFFFFFF, size=64) d = c c = b b = a a = BitVector(intVal=(int(t1) + int(t2)) & 0xFFFFFFFFFFFFFFFF, size=64) h0 = BitVector(intVal=(int(h0) + int(a)) & 0xFFFFFFFFFFFFFFFF, size=64) h1 = BitVector(intVal=(int(h1) + int(b)) & 0xFFFFFFFFFFFFFFFF, size=64) h2 = BitVector(intVal=(int(h2) + int(c)) & 0xFFFFFFFFFFFFFFFF, size=64) h3 = BitVector(intVal=(int(h3) + int(d)) & 0xFFFFFFFFFFFFFFFF, size=64) h4 = BitVector(intVal=(int(h4) + int(e)) & 0xFFFFFFFFFFFFFFFF, size=64) h5 = BitVector(intVal=(int(h5) + int(f)) & 0xFFFFFFFFFFFFFFFF, size=64) h6 = BitVector(intVal=(int(h6) + int(g)) & 0xFFFFFFFFFFFFFFFF, size=64) h7 = BitVector(intVal=(int(h7) + int(h)) & 0xFFFFFFFFFFFFFFFF, size=64) # Concatenate the contents of the hash buffer to obtain a 512-element BitVector object: message_hash = h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 # Get the hex representation of the binary hash value: hash_hex_string = message_hash.getHexStringFromBitVector() return hash_hex_string
msg_decrypted_bv = BitVector(size=0) # (T) # Carry out differential XORing of bit blocks and decryption: previous_decrypted_block = bv_iv # (U) for i in range(0, len(encrypted_bv) // BLOCKSIZE): # (V) bv = encrypted_bv[i * BLOCKSIZE:(i + 1) * BLOCKSIZE] # (W) temp = bv.deep_copy() # (X) bv ^= previous_decrypted_block # (Y) previous_decrypted_block = temp # (Z) bv ^= key_bv # (a) msg_decrypted_bv += bv # (b) # Extract plaintext from the decrypted bitvector: outputtext = msg_decrypted_bv.get_text_from_bitvector() # (c) return outputtext if __name__ == '__main__': for i in range(2**16): someRandomInteger = 9999 # Arbitrary integer for creating a BitVector key_bv = BitVector(intVal=i, size=16) decryptedMessage = cryptBreak('encrypted.txt', key_bv) print(decryptedMessage) print("\n") if 'Mark Twain' in decryptedMessage: print('Encryption Broken!') print(i) break else: print('Not decrypted yet')