added signedby proof

This commit is contained in:
Kevin Froman 2020-12-28 01:01:54 +00:00
parent b0dc7d75e5
commit cd53b4dde2
4 changed files with 103 additions and 1 deletions

View File

@ -8,3 +8,5 @@ AnonymousVDFBlockResult = namedtuple(
HexChecksum = NewType("HexChecksum", str)
DecChecksum = NewType("DecChecksum", int)
DecChecksumStr = NewType("DecChecksumStr", str)
RawEd25519PrivateKey = NewType("RawEd25519PrivateKey", bytes)
RawEd25519PublicKey = NewType("RawEd25519PublicKey", bytes)

View File

@ -13,7 +13,8 @@ class AnonVDFGenerator(generator.KastenBaseGenerator):
def get_ttl_seconds_per_rounds(cls, rounds: int):
# 8000 rounds = 1 second (2.8ghz python) = 1 hour storage
if rounds < 8000:
raise ValueError("Rounds must be at least 8000")
raise ValueError(
"Rounds must be at least 8000")
return (rounds / 8000) * 60
@classmethod

View File

@ -0,0 +1,55 @@
from hashlib import sha3_256
from typing import Union
from nacl.signing import SigningKey, VerifyKey
from nacl.exceptions import BadSignatureError
from kasten import generator, Kasten
from kasten.exceptions import InvalidID
from kasten.types import KastenPacked, KastenChecksum
from onionrblocks.customtypes import RawEd25519PrivateKey, RawEd25519PublicKey
class Signed(generator.KastenBaseGenerator):
@classmethod
def generate(
cls,
packed_bytes: KastenPacked,
signingKey: Union[SigningKey, RawEd25519PrivateKey]
) -> Kasten:
"""Sign a digest of packed bytes, return a Kasten instance of it."""
# Use libsodium/pynacl (ed25519)
hashed = sha3_256(packed_bytes).digest()
try:
signed = signingKey.sign(hashed)
except AttributeError:
signingKey = SigningKey(signingKey)
signed = signingKey.sign(hashed)
# The KastenChecksum will be 64 bytes message then 32 bytes of the hash
# This can be fed right back into VerifyKey without splitting up
return Kasten(signed, packed_bytes, None,
auto_check_generator=False)
@staticmethod
def validate_id(
hash: KastenChecksum,
packed_bytes: KastenPacked,
verify_key: Union[VerifyKey, RawEd25519PublicKey]) -> None:
# Hash is 64 bytes message then 32 bytes of the hash of the packed_bytes
if len(hash) != 86:
raise InvalidID("Block not have proper signature length")
actual_hash = sha3_256(packed_bytes).digest()
if not isinstance(verify_key, VerifyKey):
verify_key = VerifyKey(verify_key)
# Ensure that the digest is correct
# Done in addition of the signature bc the sha3 can still ID blocks
# and to prevent swapping sigs
if actual_hash != hash[64:]:
raise InvalidID("Invalid sha3_256 digest")
# Ensure that the signature is correct
try:
verify_key.verify(hash)
except BadSignatureError as e:
raise InvalidID(repr(e))

44
tests/test_signedby.py Normal file
View File

@ -0,0 +1,44 @@
import unittest
from onionrblocks.generators import signedby
import kasten
import hashlib
from nacl.signing import SigningKey, VerifyKey
from time import time
from math import floor
def sha3_hash_bytes(data):
return hashlib.sha3_256(data).digest()
class TestSignedByProof(unittest.TestCase):
def test_signed_by_create(self):
key = SigningKey.generate()
test_data = kasten.generator.pack.pack(
b"test", "tst")
gen = signedby.Signed.generate(test_data, key)
self.assertEqual(
gen.get_packed(),
test_data
)
hashed = hashlib.sha3_256(test_data).digest()
signed = key.sign(hashed)
self.assertEqual(signed, gen.id)
key.verify_key.verify(signed)
self.assertEqual(hashlib.sha3_256(test_data).digest(), signed[64:])
def test_signed_by_create_raw_keys(self):
key = SigningKey.generate()
test_data = kasten.generator.pack.pack(
b"test", "tst")
gen = signedby.Signed.generate(test_data, key.encode())
self.assertEqual(
gen.get_packed(),
test_data
)
hashed = hashlib.sha3_256(test_data).digest()
signed = key.sign(hashed)
self.assertEqual(signed, gen.id)
key.verify_key.verify(signed)
self.assertEqual(hashlib.sha3_256(test_data).digest(), signed[64:])
unittest.main()