def test_get_base64_invalid_length(self): """ Test that trying to read a number of bits that is not a multiple of 8 as base64 data raises an exception. """ bitstream = BitStream() bitstream.put_base64("Zm9vYmE=") # 40 bits bitstream.seek(0) self.assertRaises(ValueError, bitstream.get_base64, 26) # read 3.25 bytes?
def test_base64_basic(self): """ This method tests put_base64's and get_base64's basic functionality. """ bitstream = BitStream() # We use the Base64 Test Vectors defined in RFC4648. # http://www.ietf.org/rfc/rfc4648.txt test_vectors = [("",""), ("f","Zg=="), ("fo","Zm8="), ("foo","Zm9v"), ("foob","Zm9vYg=="), ("fooba","Zm9vYmE="), ("foobar","Zm9vYmFy")] # STEP 1: # For each test vector, we write its value to the bitstream as a string # then read it as base64 data. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val)*8 bitstream.put_string(str_val) bitstream.seek(0) self.assertEquals(bitstream.get_base64(vector_bit_length), base64_val) bitstream.seek(0) # NOTE that we are overwriting multiple times our bitstream, this is # also a feature of BitStream we are testing in this test case. # STEP 2: # For each test vector, we write its value to the bitstream as base64 # data, then read it as string *and* base64 data. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val)*8 bitstream.put_base64(base64_val) bitstream.seek(0) self.assertEquals(bitstream.get_string(vector_bit_length), str_val) bitstream.seek(0) self.assertEquals(bitstream.get_base64(vector_bit_length), base64_val) bitstream.seek(0) # STEP 3: # For each test vector, we write its value to a NEW bitstream as base64 # data, and make sure the length of the stream is the expected one. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val)*8 new_bs = BitStream() new_bs.put_base64(base64_val) self.assertEquals(new_bs.get_length(), vector_bit_length) self.assertEquals(new_bs.get_current_pos(), vector_bit_length)
def test_get_base64_zero_bits(self): """ Test that reading zero bits from the stream as base64 data results in getting the empty string: \"\". """ bitstream = BitStream() self.assertEquals(bitstream.get_base64(0), "") # Store some base64 data in the stream. bitstream.put_base64("Zm9vYmE=") # 40 bits bitstream.seek(0) self.assertEquals(bitstream.get_base64(0), "")
def test_base64_basic(self): """ This method tests put_base64's and get_base64's basic functionality. """ bitstream = BitStream() # We use the Base64 Test Vectors defined in RFC4648. # http://www.ietf.org/rfc/rfc4648.txt test_vectors = [("", ""), ("f", "Zg=="), ("fo", "Zm8="), ("foo", "Zm9v"), ("foob", "Zm9vYg=="), ("fooba", "Zm9vYmE="), ("foobar", "Zm9vYmFy")] # STEP 1: # For each test vector, we write its value to the bitstream as a string # then read it as base64 data. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val) * 8 bitstream.put_string(str_val) bitstream.seek(0) self.assertEquals(bitstream.get_base64(vector_bit_length), base64_val) bitstream.seek(0) # NOTE that we are overwriting multiple times our bitstream, this is # also a feature of BitStream we are testing in this test case. # STEP 2: # For each test vector, we write its value to the bitstream as base64 # data, then read it as string *and* base64 data. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val) * 8 bitstream.put_base64(base64_val) bitstream.seek(0) self.assertEquals(bitstream.get_string(vector_bit_length), str_val) bitstream.seek(0) self.assertEquals(bitstream.get_base64(vector_bit_length), base64_val) bitstream.seek(0) # STEP 3: # For each test vector, we write its value to a NEW bitstream as base64 # data, and make sure the length of the stream is the expected one. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val) * 8 new_bs = BitStream() new_bs.put_base64(base64_val) self.assertEquals(new_bs.get_length(), vector_bit_length) self.assertEquals(new_bs.get_current_pos(), vector_bit_length)
def test_get_base64_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_base64(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_base64, 8) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0) bitstream.put_base64("Zm9vYmE=") # 40 bits bitstream.seek(0) # Read beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_base64, 48) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0)
def test_get_base64_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_base64(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_base64, 8) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0) bitstream.put_base64("Zm9vYmE=") # 40 bits bitstream.seek(0) # Read beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_base64, 48) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0)
def from_file(cls, filename, SerializerClass=serialize.XMLSerializer): """ Loads an instance of Ciphertext from the given file. Arguments: filename::string -- The name of a file containing the ciphertext in serialized form. SerializerClass::class -- The class that provides the deserialization. XMLSerializer by default. Must inherit from serialize.BaseSerializer and provide an adequate deserialize_from_file method. Note that often the same class used to serialize the data must be used to deserialize it. (see utilities/serialize.py documentation for more information) Throws: InvalidPloneVoteCryptoFileError -- If the file is not a valid PloneVoteCryptoLib stored ciphertext file. """ # Create a new serializer object for the Ciphertext structure definition serializer = SerializerClass(Ciphertext_serialize_structure_definition) # Deserialize the Ciphertext instance from file try: data = serializer.deserialize_from_file(filename) except serialize.InvalidSerializeDataError as e: # Convert the exception to an InvalidPloneVoteCryptoFileError raise InvalidPloneVoteCryptoFileError(filename, "File \"%s\" does not contain a valid ciphertext. The " \ "following error occurred while trying to deserialize the " \ "file contents: %s" % (filename, str(e))) # Get the values from the deserialized data try: nbits = int(data["PloneVoteCiphertext"]["nbits"]) except ValueError: raise InvalidPloneVoteCryptoFileError(filename, "File \"%s\" does not contain a valid ciphertext. The " \ "stored value for nbits is not a valid (decimal) integer." \ % filename) fingerprint_str = data["PloneVoteCiphertext"]["PKFingerprint"] enc_data_str = data["PloneVoteCiphertext"]["EncryptedData"] # Construct a new Ciphertext object with the given nbits and fingerprint ciphertext = cls(nbits, fingerprint_str) # Load the encrypted data bitstream = BitStream() bitstream.put_base64(enc_data_str) bitstream.seek(0) length = bitstream.get_length() # number of gamma and delta blocks in the bitstream: blocks = length // (nbits * 2) for i in range(0, blocks): gamma_val = bitstream.get_num(nbits) delta_val = bitstream.get_num(nbits) ciphertext.append(gamma_val, delta_val) # Return the ciphertext return ciphertext