def compute_point_xy(self): in_str = self.input_seed + "point" x_hash = utils.hash_sha512(in_str) self.point_x = int(x_hash, 16) % self.prime_p end = False while not end: ring = Integers(self.prime_p) tmp = power_mod(self.point_x, 3, self.prime_p) + \ self.coeff_a * self.point_x + self.coeff_b y = ring(tmp) if not utils.is_quadratic_residue(y, self.prime_p): x_hash = utils.hash_sha512(x_hash) self.point_x = int(x_hash, 16) % self.prime_p else: sq_root = int(y.square_root()) if sq_root % 2 == 0: self.point_y = sq_root else: self.point_y = self.prime_p - sq_root end = True
def compute_coeff_b(self, prime_p, in_seed, curve_index): in_str = "b" + str(curve_index) + in_seed result = utils.hash_sha512(in_str) result_int = int(result, 16) return (result_int % prime_p)
def compute_coeff_a(self, a_type, prime_p, in_seed, curve_index): if a_type == 'fixed': in_str = "a" + in_seed result = utils.hash_sha512(in_str) result_int = int(result, 16) return (result_int % prime_p) elif a_type == 'random': in_str = "a" + str(curve_index) + in_seed result = utils.hash_sha512(in_str) result_int = int(result, 16) return (result_int % prime_p) elif a_type == 'efficient': return (prime_p - 3)
def generate_sloth_input(self): img_data = utils.read_binary_file(self.image_filepath) tw_data = utils.read_binary_file(self.tweets_filepath) img_tw_bytes = bytearray(img_data + tw_data) ret_val = utils.hash_sha512(img_tw_bytes) return ret_val
def check_commitment(self, expected_comm): sloth_input = self.generate_sloth_input() comm = utils.hash_sha512(sloth_input) if comm == expected_comm: return True else: return False
def generate(self): sloth_input = self.generate_sloth_input() self.commitment = utils.hash_sha512(sloth_input) prime_p = self.generate_prime_p(sloth_input) s_int = self.generate_s_int(sloth_input, prime_p) flip_mask = pow(2, self.sloth_prime_len / 2) - 1 ro_func_exp = (prime_p + 1) / 4 for i in xrange(self.sloth_num_iter): s_int = (s_int ^ flip_mask) % prime_p s_int = self.ro_function(s_int, ro_func_exp, prime_p) self.witness = utils.hex_strip(s_int) self.sloth_hash = utils.hash_sha512(self.witness)
def generate_s_int(self, sloth_input, prime_p): num_hashes = self.sloth_prime_len / 512 s_hex = "" for i in xrange(num_hashes): s_hex += utils.hash_sha512(sloth_input + "seed" + str(i)) s_int = int(s_hex, 16) s_int = s_int % prime_p return s_int
def generate_prime_p(self, sloth_input): # We divide with 512 because we are using sha512 hash function num_hashes = self.sloth_prime_len / 512 p0_hex = "" for i in xrange(num_hashes): p0_hex += utils.hash_sha512(sloth_input + "prime" + str(i)) p0_int = int(p0_hex, 16) p1_int = p0_int | pow(2, self.sloth_prime_len - 1) prime_p = utils.next_prime_3_mod_4(p1_int) return prime_p
def verify(self, expected_comm, expected_hash, expected_wit): sloth_input = self.generate_sloth_input() self.commitment = utils.hash_sha512(sloth_input) if self.commitment != expected_comm: self.verification = self.COMMIT_FAIL return False wit_hash = utils.hash_sha512(expected_wit) if wit_hash != expected_hash: self.verification = self.WITNES_FAIL self.witness_hash = wit_hash return False prime_p = self.generate_prime_p(sloth_input) s_int = self.generate_s_int(sloth_input, prime_p) flip_mask = pow(2, self.sloth_prime_len / 2) - 1 inv_val = int(expected_wit, 16) for i in xrange(self.sloth_num_iter): if inv_val % 2 == 0: inv_val = pow(inv_val, 2, prime_p) else: inv_val = prime_p - pow(inv_val, 2, prime_p) inv_val = (inv_val ^ flip_mask) % prime_p if inv_val != s_int: self.verification = self.HASH_FAIL return False self.verification = self.ALL_PASSED return True