def stream_decrypt(self, salt, ciphertext): """Decrypt ciphertext with given salt, return (preprocessed) word.""" left_ciphertext = self.left_part(ciphertext) stream_prefix = self.stream_prefix(salt) left_part = crypto.xor(left_ciphertext, stream_prefix) word_key = self.word_key(left_part) stream_suffix = self.stream_suffix(word_key, stream_prefix) return crypto.xor(ciphertext, stream_prefix + stream_suffix)
def stream_encrypt(self, salt, preword): """Encrypt a (preprocessed) word with given salt.""" left_part = self.left_part(preword) word_key = self.word_key(left_part) stream_prefix = self.stream_prefix(salt) stream_suffix = self.stream_suffix(word_key, stream_prefix) return crypto.xor(preword, stream_prefix + stream_suffix)
def match(b64field, b64query): """Return True if the given query matches the field. Parameters: b64field -- a concatenation of salt and ciphertext, each BLOCK_BYTES long, encoded in base64 b64query -- a concatenation of preword and word_key, each BLOCK_BYTES long, encoded in base64 """ # Ensure byte strings. if isinstance(b64field, str): b64field = str.encode(b64field) elif not isinstance(b64field, (bytes, bytearray)): return False if isinstance(b64query, str): b64query = str.encode(b64query) elif not isinstance(b64query, (bytes, bytearray)): print('bad instance', type(b64query), b64query) return False # Decode from base64. try: field = base64.decodebytes(b64field) query = base64.decodebytes(b64query) except: return False # Require correct sizes. if len(query) != 2 * BLOCK_BYTES or len(field) != 2 * BLOCK_BYTES: return False # Check using Song et al.'s Final Scheme. preword, word_key = query[:BLOCK_BYTES], query[BLOCK_BYTES:] _, ciphertext = field[:BLOCK_BYTES], field[BLOCK_BYTES:] block = crypto.xor(ciphertext, preword) prefix, suffix = block[:LEFT_BYTES], block[LEFT_BYTES:] hashed_prefix = crypto.prfunction(word_key, prefix, length=MATCH_BYTES) return hashed_prefix == suffix
def test_xor(self): test_block = b"t" * constants.BLOCK_BYTES null_block = b"\0" * constants.BLOCK_BYTES self.assertEqual(crypto.xor(null_block, test_block), test_block) self.assertEqual(crypto.xor(test_block, test_block), null_block)