def extend_words(self): for i in range(16, 64): # now extend the rest of w[] s0_p1 = logic.rotate_bits(self.w[i-15], 7) s0_p2 = logic.rotate_bits(self.w[i-15], 18) s0_p3 = logic.shift_bits(self.w[i-15], 3) s0_xor1 = logic.xor_binary_strings(s0_p1, s0_p2)[2:] s0 = logic.xor_binary_strings(s0_xor1, s0_p3) s0 = self.extend_to_32_bit(s0) s1_p1 = logic.rotate_bits(self.w[i-2], 17) s1_p2 = logic.rotate_bits(self.w[i-2], 19) s1_p3 = logic.shift_bits(self.w[i-2], 10) s1_xor1 = logic.xor_binary_strings(s1_p1, s1_p2)[2:] s1 = logic.xor_binary_strings(s1_xor1, s1_p3) s1 = self.extend_to_32_bit(s1) add1 = logic.add_binary_strings(self.w[i-16], s0) add1 = self.extend_to_32_bit(add1) add2 = logic.add_binary_strings(self.w[i-7], s1) add2 = self.extend_to_32_bit(add2) w_i_no_padding = logic.add_binary_strings(add1, add2) w_i_no_padding = self.extend_to_32_bit(w_i_no_padding) # truncate overflow bits - cap at 32 bits w_i = logic.and_binary_strings(w_i_no_padding, '11111111111111111111111111111111')[2:] w_i = self.extend_to_32_bit(w_i) self.w[i] = w_i
def test_arithmetic(self): byte1 = '10101010' byte2 = '10010010' _xor = logic.xor_binary_strings(byte1, byte2)[2:] _xor = helper.Helper.add_leading_zeros(helper.Helper(), _xor) _and = logic.and_binary_strings(byte1, byte2)[2:] _and = helper.Helper.add_leading_zeros(helper.Helper(), _and) _not = logic.not_binary_string(byte1)[2:] _add = logic.add_binary_strings(byte1, byte2)[2:] self.assertEqual(_xor, '00111000') self.assertEqual(_and, '10000010') self.assertEqual(_not, '11111111111111111111111101010101') self.assertEqual(_add, '100111100')
def extend_words(self): # I discovered late that the extension cannot be parallelized due to # dependencies in between the array indices #input_64x32_bits = gpuarray.to_gpu(self.w) #self.extend( # input_64x32_bits, # block=(32,64,64), # grid=(1,1,1) #) #self.w = input_64x32_bits.get() for i in range(16, 64): # now extend the rest of w[] s0_p1 = logic.rotate_bits(self.w[i - 15], 7) s0_p2 = logic.rotate_bits(self.w[i - 15], 18) s0_p3 = logic.shift_bits(self.w[i - 15], 3) s0_xor1 = logic.xor_binary_strings(s0_p1, s0_p2)[2:] s0 = logic.xor_binary_strings(s0_xor1, s0_p3) s0 = self.extend_to_32_bit(s0) s1_p1 = logic.rotate_bits(self.w[i - 2], 17) s1_p2 = logic.rotate_bits(self.w[i - 2], 19) s1_p3 = logic.shift_bits(self.w[i - 2], 10) s1_xor1 = logic.xor_binary_strings(s1_p1, s1_p2)[2:] s1 = logic.xor_binary_strings(s1_xor1, s1_p3) s1 = self.extend_to_32_bit(s1) add1 = logic.add_binary_strings(self.w[i - 16], s0) add1 = self.extend_to_32_bit(add1) add2 = logic.add_binary_strings(self.w[i - 7], s1) add2 = self.extend_to_32_bit(add2) w_i_no_padding = logic.add_binary_strings(add1, add2) w_i_no_padding = self.extend_to_32_bit(w_i_no_padding) # truncate overflow bits - cap at 32 bits w_i = logic.and_binary_strings( w_i_no_padding, '11111111111111111111111111111111')[2:] w_i = self.extend_to_32_bit(w_i) self.w[i] = w_i
def compress(self): # this compression function happens for every 512-bit chunk, # so after one 512-bit chunk is compressed, it calls this function # for the next chunk to be process with the updated 'h' list # initialize working registers / variables a = self.h[0] b = self.h[1] c = self.h[2] d = self.h[3] e = self.h[4] f = self.h[5] g = self.h[6] h = self.h[7] for i in range(64): # S1 e_rot_6 = logic.rotate_bits(e, 6) e_rot_11 = logic.rotate_bits(e, 11) e_rot_25 = logic.rotate_bits(e, 25) s1_xor_1 = logic.xor_binary_strings(e_rot_6, e_rot_11) _S1 = logic.xor_binary_strings(s1_xor_1, e_rot_25)[2:] _S1 = self.extend_to_32_bit(_S1) # ch e_and_f = logic.and_binary_strings(e, f) not_e = logic.not_binary_string(e) ch_and_1 = logic.and_binary_strings(not_e, g) _ch = logic.xor_binary_strings(e_and_f, ch_and_1)[2:] _ch = self.extend_to_32_bit(_ch) # temp1 add_1 = logic.add_binary_strings(h, _S1) add_1 = logic.and_binary_strings(add_1, '11111111111111111111111111111111')[2:] add_2 = logic.add_binary_strings(_ch, self.extend_to_32_bit(bin(self.k[i])[2:])) add_2 = logic.and_binary_strings(add_2, '11111111111111111111111111111111')[2:] add_3 = logic.add_binary_strings(add_1, add_2) add_3 = logic.and_binary_strings(add_3, '11111111111111111111111111111111')[2:] _temp1 = logic.add_binary_strings(add_3, self.w[i]) _temp1 = logic.and_binary_strings(_temp1, '11111111111111111111111111111111')[2:] _temp1 = self.extend_to_32_bit(_temp1) # S0 a_rot_2 = logic.rotate_bits(a, 2) a_rot_13 = logic.rotate_bits(a, 13) a_rot_22 = logic.rotate_bits(a, 22) s0_xor_1 = logic.xor_binary_strings(a_rot_2, a_rot_13) _S0 = logic.xor_binary_strings(s0_xor_1, a_rot_22)[2:] _S0 = self.extend_to_32_bit(_S0) # maj a_and_b = logic.and_binary_strings(a, b) a_and_c = logic.and_binary_strings(a, c) b_and_c = logic.and_binary_strings(b, c) maj_xor_1 = logic.xor_binary_strings(a_and_b, a_and_c) _maj = logic.xor_binary_strings(maj_xor_1, b_and_c)[2:] _maj = self.extend_to_32_bit(_maj) # temp2 _temp2 = logic.and_binary_strings(logic.add_binary_strings(_S0, _maj)[2:], '11111111111111111111111111111111')[2:] _temp2 = self.extend_to_32_bit(_temp2) # Every ADD operation must & 0xFFFFFFFF (in case of overflow) and be extended back to 32 bits (in case < 32 bits) h = self.extend_to_32_bit(g) g = self.extend_to_32_bit(f) f = self.extend_to_32_bit(e) e = logic.and_binary_strings(logic.add_binary_strings(d, _temp1)[2:], '11111111111111111111111111111111')[2:] e = self.extend_to_32_bit(e) d = self.extend_to_32_bit(c) c = self.extend_to_32_bit(b) b = self.extend_to_32_bit(a) a = logic.and_binary_strings(logic.add_binary_strings(_temp1, _temp2)[2:], '11111111111111111111111111111111')[2:] a = self.extend_to_32_bit(a) self.h[0] = logic.and_binary_strings(logic.add_binary_strings(self.h[0], a)[2:], '11111111111111111111111111111111')[2:] self.h[0] = self.extend_to_32_bit(self.h[0]) self.h[1] = logic.and_binary_strings(logic.add_binary_strings(self.h[1], b)[2:], '11111111111111111111111111111111')[2:] self.h[1] = self.extend_to_32_bit(self.h[1]) self.h[2] = logic.and_binary_strings(logic.add_binary_strings(self.h[2], c)[2:], '11111111111111111111111111111111')[2:] self.h[2] = self.extend_to_32_bit(self.h[2]) self.h[3] = logic.and_binary_strings(logic.add_binary_strings(self.h[3], d)[2:], '11111111111111111111111111111111')[2:] self.h[3] = self.extend_to_32_bit(self.h[3]) self.h[4] = logic.and_binary_strings(logic.add_binary_strings(self.h[4], e)[2:], '11111111111111111111111111111111')[2:] self.h[4] = self.extend_to_32_bit(self.h[4]) self.h[5] = logic.and_binary_strings(logic.add_binary_strings(self.h[5], f)[2:], '11111111111111111111111111111111')[2:] self.h[5] = self.extend_to_32_bit(self.h[5]) self.h[6] = logic.and_binary_strings(logic.add_binary_strings(self.h[6], g)[2:], '11111111111111111111111111111111')[2:] self.h[6] = self.extend_to_32_bit(self.h[6]) self.h[7] = logic.and_binary_strings(logic.add_binary_strings(self.h[7], h)[2:], '11111111111111111111111111111111')[2:] self.h[7] = self.extend_to_32_bit(self.h[7])