diff --git a/onionrblocks/create.py b/onionrblocks/create.py new file mode 100644 index 0000000..2824232 --- /dev/null +++ b/onionrblocks/create.py @@ -0,0 +1,50 @@ +from typing import Union +from time import time + +import kasten + +from .types import AnonymousVDFBlockResult + + +def __str_to_bytes(data: str): + try: + return data.encode('utf-8') + except AttributeError: + return data + + +def _packer(block_data: bytes, **kasten_header) -> kasten.main.KastenPacked: + def __get_optional(key, default): + try: + return kasten_header[key] + except KeyError: + return default + # Todo: validate length sanities + return kasten.generator.pack.pack( + block_data, + kasten_header['type'], + kasten_header['encrypt mode'], + __get_optional('signer', b''), + __get_optional('signature', b''), + __get_optional('metadata', None), + int(time()//60 * 60) + ) + +# Block creation functions handle calling the proof and compiling blocks +# They do not handle sigs or encryption (at least never directly) + + +def create_block_anonymous_vdf( + rounds: int, + block_data: Union[str, bytes], + **block_header) -> AnonymousVDFBlockResult: + block_data = __str_to_bytes(block_data) + # Block with anonymous VDF as proof + + packed: kasten.types.KastenPacked = _packer(block_data, **block_header) + kasten_result: kasten.Kasten = \ + kasten.generator.KastenMimcGenerator.generate(packed, rounds) + + return AnonymousVDFBlockResult( + kasten_result.id, + kasten_result.get_packed()) diff --git a/onionrblocks/loadblockobject.py b/onionrblocks/loadblockobject.py new file mode 100644 index 0000000..ecac971 --- /dev/null +++ b/onionrblocks/loadblockobject.py @@ -0,0 +1,19 @@ +from typing import Union + +from kasten.types import KastenPacked +from kasten import Kasten +from kasten.generator import KastenMimcGenerator + +from .types import DecChecksum, DecChecksumStr, HexChecksum + + +def load_anonymous_vdf_block( + expected_id: Union[DecChecksum, DecChecksumStr, HexChecksum], + raw_block: KastenPacked, + rounds: 'MimcRoundsInt') -> Kasten: + """Load a block created with the KastenMimcGenerator + + take expected checksum, bytes and rounds + + Throws kasten.generator.InvalidID if data does not match raw bytes""" + return Kasten(expected_id, raw_block, KastenMimcGenerator, *[rounds]) \ No newline at end of file diff --git a/onionrblocks/types.py b/onionrblocks/types.py new file mode 100644 index 0000000..ea8a3af --- /dev/null +++ b/onionrblocks/types.py @@ -0,0 +1,10 @@ +from collections import namedtuple +from typing import NewType + + +AnonymousVDFBlockResult = namedtuple( + 'AnonymousVDFBlockResult', ['dec_checksum', 'raw_bytes']) + +HexChecksum = NewType("HexChecksum", str) +DecChecksum = NewType("DecChecksum", int) +DecChecksumStr = NewType("DecChecksumStr", str)