I am trying to use ED25519
signing and verifying blockchain transactions in my blockchain project but I am getting a
ValueError "Invalid DER input: insufficient data
when I add the encode_dss_signature, and decode_dss_signature.
I am first converting the data into json format and then encoding it into (utf-8) format. Then when I try to decode the signature using decode_dss_signature
. it gives the above Value Error.
import json
import uuid
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.utils import(
encode_dss_signature,
decode_dss_signature
)
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import serialization
class Wallet:
"""
An individual wallet for a miner.
Keeps track of the miners's balance.
Allows a miner to authorize transactions.
"""
def __init__(self):
self.address = str(uuid.uuid4())[0:8]
self.private_key = Ed25519PrivateKey.generate()
self.public_key = self.private_key.public_key()
self.serialize_public_key()
def sign(self, data):
"""
Generate a signature based on the data using the local private key.
"""
return decode_dss_signature(self.private_key.sign(
json.dumps(data).encode('utf-8')
))
def serialize_public_key(self):
"""
Reset the public key to its serialized version.
"""
self.public_key = self.public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
).decode('utf-8')
print(f'\n-- self.public_key: {self.public_key}')
@staticmethod
def verify(public_key, signature, data):
"""
Verify signature based on original public_key and data.
"""
deserialized_public_key = serialization.load_pem_public_key(
public_key.encode('utf-8')
)
print(f'\n--signature: {signature}\n')
(r, s) = signature
try:
deserialized_public_key.verify(
encode_dss_signature(r, s),
json.dumps(data).encode('utf-8')
)
return True
except InvalidSignature:
return False
def main():
wallet = Wallet()
print(f'wallet.__dict__: {wallet.__dict__}')
data = { 'foo':'bar' }
signature = wallet.sign(data)
print(f'signature: {signature}')
sign_verification = Wallet.verify(wallet.public_key, signature, data)
print(f'sign_verification: {sign_verification}')
sign_verify_failed = Wallet.verify(Wallet().public_key, signature, data)
print(f'sign_verify_failed: {sign_verify_failed}')
if __name__ == '__main__':
main()