always pack all values, bump version

This commit is contained in:
Kevin Froman 2020-12-11 03:27:52 +00:00
parent 27698f929a
commit 903e203c63
8 changed files with 63 additions and 28 deletions

View File

@ -2,6 +2,12 @@
This project uses Semantic Versioning This project uses Semantic Versioning
## 1.0.0
+ Serialize all official header keys, always (breaks header order of prev versions)
## 0.1.0 ## 0.1.0
+ Added custom args support to kasten auto check + Added custom args support to kasten auto check

View File

@ -45,18 +45,34 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
def pack(data: bytes, data_type: '', def pack(data: bytes, data_type: str,
enc_mode: 'KastenEncryptionModeID', enc_mode: 'KastenEncryptionModeID',
signer: bytes = None, signature: bytes = None, signer: bytes = None, signature: bytes = None,
app_metadata: 'KastenSerializeableDict' = None, app_metadata: 'KastenSerializeableDict' = None,
timestamp: int = None timestamp: int = None
) -> KastenPacked: ) -> KastenPacked:
"""Create KastenPacked bytes sequence but do not ID or run through generator""" """Create KastenPacked bytes sequence but do not ID or run through generator"""
# Final data will be:
# msgpack.packb([data_type, enc_mode, timestamp, (signer, signature), {app_metadata}]) \
# + b'\n' + data
# Ensure data type does not exceed 4 characters # Ensure data type does not exceed 4 characters
if not data_type or len(data_type) > 4: if not data_type or len(data_type) > 4:
raise exceptions.InvalidKastenTypeLength raise exceptions.InvalidKastenTypeLength
try:
data_type = data_type.decode('utf8')
except AttributeError:
pass
if signer:
if signature is None:
raise ValueError("Signer specified without signature")
else:
signer = b''
signature = b''
# Ensure encryption mode is in [0, 100) # Ensure encryption mode is in [0, 100)
try: try:
enc_mode = int(enc_mode) enc_mode = int(enc_mode)
@ -74,12 +90,8 @@ def pack(data: bytes, data_type: '',
timestamp = int(timestamp) timestamp = int(timestamp)
kasten_header = [data_type, enc_mode, timestamp] kasten_header = [data_type, enc_mode, timestamp]
if signer: kasten_header.append((signer, signature))
if signature is None: kasten_header.append(app_metadata)
raise ValueError("Signer specified without signature")
kasten_header.extend((signer, signature))
if app_metadata is not None:
kasten_header.append(app_metadata)
kasten_header = packb(kasten_header) + b'\n' kasten_header = packb(kasten_header) + b'\n'
return kasten_header + data return kasten_header + data

View File

@ -58,9 +58,13 @@ class Kasten:
ret = func() ret = func()
except IndexError: except IndexError:
return None return None
except TypeError:
return None
return ret return ret
return pack.pack(self.data, self.get_data_type(), return pack.pack(self.data, self.get_data_type(),
self.get_encryption_mode(), self.get_encryption_mode(),
signer=_get_or_none(self.get_signer),
signature=_get_or_none(self.get_signature),
app_metadata=_get_or_none(self.get_metadata), app_metadata=_get_or_none(self.get_metadata),
timestamp=self.get_timestamp()) timestamp=self.get_timestamp())
@ -70,4 +74,8 @@ class Kasten:
def get_timestamp(self): return self.header[2] def get_timestamp(self): return self.header[2]
def get_metadata(self): return self.header[3] def get_signer(self): return self.header[3][0]
def get_signature(self): return self.header[3][1]
def get_metadata(self): return self.header[4]

View File

@ -6,7 +6,7 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
long_description = f.read() long_description = f.read()
setup(name='kasten', setup(name='kasten',
version='0.2.0', version='1.0.0',
description='Efficient, secure data serialization format with extensibility.', description='Efficient, secure data serialization format with extensibility.',
author='Kevin Froman', author='Kevin Froman',
author_email='beardog@mailbox.org', author_email='beardog@mailbox.org',

View File

@ -7,14 +7,23 @@ from kasten.generator import KastenBaseGenerator
class TestBaseGenerator(unittest.TestCase): class TestBaseGenerator(unittest.TestCase):
def test_base_generator(self): def test_base_generator(self):
k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest'
invalid = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntes2' k = b'\x95\xa3tst\x00\x00\xc0\xc0\ntest data'
K = KastenBaseGenerator.generate(k) invalid = b'\x95\xa3tst\x00\x00\xc0\xc0\ntest datb'
h = sha3_384(k).digest()
self.assertTrue(len(K.get_packed()) > 0) correct_K = KastenBaseGenerator.generate(k)
KastenBaseGenerator.validate_id(h, k) hash_test = sha3_384(k).digest()
self.assertRaises(exceptions.InvalidID, KastenBaseGenerator.validate_id, h, invalid)
self.assertEqual(K.get_packed(), k) self.assertTrue(len(correct_K.get_packed()) > 0)
# k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest'
# invalid = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntes2'
# K = KastenBaseGenerator.generate(k)
# h = sha3_384(k).digest()
# self.assertTrue(len(K.get_packed()) > 0)
# KastenBaseGenerator.validate_id(h, k)
# self.assertRaises(exceptions.InvalidID, KastenBaseGenerator.validate_id, h, invalid)
# self.assertEqual(K.get_packed(), k)
unittest.main() unittest.main()

View File

@ -8,11 +8,11 @@ from kasten.generator import KastenBaseGenerator, pack
class TestKastenBaseGenerator(unittest.TestCase): class TestKastenBaseGenerator(unittest.TestCase):
def test_kasten(self): def test_kasten(self):
k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data'
K = Kasten(sha3_384(k).digest(), k, KastenBaseGenerator) K = Kasten(sha3_384(k).digest(), k, KastenBaseGenerator)
def test_kasten_invalid(self): def test_kasten_invalid(self):
k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data'
self.assertRaises( self.assertRaises(
exceptions.InvalidID, exceptions.InvalidID,
Kasten, sha3_384(k + b'invalid').digest(), k, KastenBaseGenerator) Kasten, sha3_384(k + b'invalid').digest(), k, KastenBaseGenerator)

View File

@ -9,8 +9,8 @@ from kasten import Kasten
class TestMimcGenerator(unittest.TestCase): class TestMimcGenerator(unittest.TestCase):
def test_mimc_generator(self): def test_mimc_generator(self):
k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data'
invalid = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntes2' invalid = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest dat2'
K = KastenMimcGenerator.generate(k) K = KastenMimcGenerator.generate(k)
#h = sha3_384(k).digest() #h = sha3_384(k).digest()
h = mimcvdf.vdf_create(k, 5000, dec=True) h = mimcvdf.vdf_create(k, 5000, dec=True)
@ -20,8 +20,8 @@ class TestMimcGenerator(unittest.TestCase):
self.assertEqual(K.get_packed(), k) self.assertEqual(K.get_packed(), k)
def test_mimc_generator_wrong_rounds(self): def test_mimc_generator_wrong_rounds(self):
k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data'
invalid = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntes2' invalid = b'\x95\xa3tst\x00\x00\xc0\xc0\ntest dat2'
K = KastenMimcGenerator.generate(k) K = KastenMimcGenerator.generate(k)
#h = sha3_384(k).digest() #h = sha3_384(k).digest()
h = mimcvdf.vdf_create(k, 1000, dec=True) h = mimcvdf.vdf_create(k, 1000, dec=True)
@ -31,7 +31,7 @@ class TestMimcGenerator(unittest.TestCase):
self.assertEqual(K.get_packed(), k) self.assertEqual(K.get_packed(), k)
def test_mimc_generator_kasten_auto_validate(self): def test_mimc_generator_kasten_auto_validate(self):
k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data'
K = KastenMimcGenerator.generate(k, 1000) K = KastenMimcGenerator.generate(k, 1000)
Kasten(int.from_bytes(K.id, byteorder="big"), K.get_packed(), KastenMimcGenerator, *[1000]) Kasten(int.from_bytes(K.id, byteorder="big"), K.get_packed(), KastenMimcGenerator, *[1000])

View File

@ -19,7 +19,7 @@ class TestPack(unittest.TestCase):
self.assertEqual(unpacked[0], 'bin') self.assertEqual(unpacked[0], 'bin')
self.assertEqual(unpacked[1], 0) self.assertEqual(unpacked[1], 0)
self.assertAlmostEqual(unpacked[2], t) self.assertAlmostEqual(unpacked[2], t)
self.assertEqual(len(unpacked), 3) self.assertEqual(len(unpacked), 5)
def test_unsigned_with_meta(self): def test_unsigned_with_meta(self):
data = os.urandom(10) data = os.urandom(10)
@ -30,8 +30,8 @@ class TestPack(unittest.TestCase):
self.assertEqual(unpacked[0], 'bin') self.assertEqual(unpacked[0], 'bin')
self.assertEqual(unpacked[1], 0) self.assertEqual(unpacked[1], 0)
self.assertAlmostEqual(unpacked[2], t) self.assertAlmostEqual(unpacked[2], t)
self.assertEqual(unpacked[3], {"meme": "doge"}) self.assertEqual(unpacked[4], {"meme": "doge"})
self.assertEqual(len(unpacked), 4) self.assertEqual(len(unpacked), 5)
def test_linebreak_data(self): def test_linebreak_data(self):
data = os.urandom(10) + b'\n' data = os.urandom(10) + b'\n'