added signedby proof
This commit is contained in:
parent
b0dc7d75e5
commit
cd53b4dde2
@ -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)
|
||||
|
@ -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
|
||||
|
55
onionrblocks/generators/signedby.py
Normal file
55
onionrblocks/generators/signedby.py
Normal 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
44
tests/test_signedby.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user