Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 2 additions & 17 deletions crypto/identity/private_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@
from crypto.configuration.network import get_network
from crypto.enums.constants import Constants

def keccak256(data: bytes) -> bytes:
"""Keccak256 hash function"""

return bytes.fromhex(keccak.new(data=data, digest_bits=256).hexdigest())

class PrivateKey(object):
def __init__(self, private_key: str):
self.private_key = PvtKey.from_hex(private_key)
Expand All @@ -26,20 +21,10 @@ def sign(self, message: bytes) -> bytes:
Returns:
bytes: signature of the signed message
"""
signature = self.private_key.sign(message)

return hexlify(signature)

def sign_compact(self, message: bytes) -> bytes:
"""Sign a message with this private key object

Args:
message (bytes): bytes data you want to sign
message_hash = bytes.fromhex(keccak.new(data=message, digest_bits=256).hexdigest())

Returns:
bytes: signature of the signed message
"""
der = self.private_key.sign_recoverable(message, hasher=keccak256)
der = self.private_key.sign_recoverable(message_hash, hasher=None)

return bytes([der[64] + Constants.ETHEREUM_RECOVERY_ID_OFFSET.value]) + der[0:64]

Expand Down
19 changes: 0 additions & 19 deletions crypto/transactions/signature.py

This file was deleted.

2 changes: 1 addition & 1 deletion crypto/transactions/types/abstract_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def sign(self, private_key: PrivateKey):

message = bytes.fromhex(transaction_hash)

transaction_signature = private_key.sign_compact(message)
transaction_signature = private_key.sign(message)

self.data['v'] = transaction_signature[0]
self.data['r'] = transaction_signature[1:33].hex()
Expand Down
53 changes: 36 additions & 17 deletions crypto/utils/message.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import json
from binascii import unhexlify
from typing import Union

from Cryptodome.Hash import keccak
from coincurve import PublicKey

from crypto.identity.private_key import PrivateKey
from crypto.transactions.signature import Signature
from typing import Union

class Message(object):
public_key: bytes
message: bytes
signature: bytes

def __init__(self, public_key: bytes, message: bytes, signature: bytes):
if type(public_key) is bytes:
self.public_key = public_key
else:
def __init__(self, public_key: Union[bytes, str], message: Union[bytes, str], signature: Union[bytes, str]):
if isinstance(public_key, str):
self.public_key = public_key.encode()

if type(message) is bytes:
self.message = message
else:
self.message = message.encode()
self.public_key = public_key

if type(signature) is bytes:
self.signature = signature
if isinstance(message, str):
self.message = message.encode()
else:
self.message = message

if isinstance(signature, str):
self.signature = signature.encode()
else:
self.signature = signature

@classmethod
def sign(cls, message: Union[bytes, str], passphrase: bytes):
def sign(cls, message: Union[bytes, str], passphrase: Union[bytes, str]):
"""Signs a message

Args:
Expand All @@ -38,13 +40,22 @@ def sign(cls, message: Union[bytes, str], passphrase: bytes):
Message: returns a message object
"""

if type(message) is str:
if isinstance(message, str):
message = message.encode()

if not isinstance(passphrase, str):
passphrase = passphrase.hex()

private_key = PrivateKey.from_passphrase(passphrase)
public_key = private_key.public_key
signature = Signature.sign(message, private_key)

transaction_signature = private_key.sign(message)

signature_v = bytes([transaction_signature[0]]).hex()
signature_r = transaction_signature[1:33].hex()
signature_s = transaction_signature[33:].hex()

signature = signature_r + signature_s + signature_v

return cls(
message=message,
Expand All @@ -59,10 +70,18 @@ def verify(self):
bool: returns a boolean - true if verified, false if not
"""

public_key = unhexlify(self.public_key)
signature = unhexlify(self.signature)
message_hash = keccak.new(data=self.message, digest_bits=256).digest()

signature_r = signature[0:32]
signature_s = signature[32:64]
signature_v = signature[64]

signature = signature_r + signature_s + bytes([signature_v - 27])

public_key = PublicKey.from_signature_and_message(signature, message_hash, hasher=None)

return Signature.verify(signature, self.message, public_key)
return public_key.format() == unhexlify(self.public_key)

def to_dict(self):
"""Return a dictionary of the message
Expand Down
11 changes: 0 additions & 11 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,3 @@ def transaction_type_9():
'serialized': 'ff011e0100000009000900000000000000023efc1da7f315f3c533a4080e491f32cd4219731cef008976c3876539e1f192d300f902950000000000728c2c5d5f090e8c5dfd433bb2b15b30442cbafb9b882117f7b6f284da4093c6a96e8456f764628ec809514ac4e8b06d5450978b9b763f7d01f696b8881f702a'
}
return data


@pytest.fixture
def message():
data = {
'publicKey': '034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192',
'signature': '22ff2371becb58439efdb95d116215f75bc41a380e1491605cc4874dd0d2c7d7958e4072da22fd307fe419c8864ba313a28bdb6fecbc6407839b6ba472395fe9', # noqa
'message': 'Hello World',
'passphrase': 'this is a top secret passphrase',
}
return data
5 changes: 5 additions & 0 deletions tests/fixtures/message-sign.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"message": "Hello, world!",
"publicKey": "0243333347c8cbf4e3cbc7a96964181d02a2b0c854faa2fef86b4b8d92afcf473d",
"signature": "0e2e53409be748834cac44052817ecef569b429a0492aa6bbc0d934eb71a09547e77aeef33d45669bbcba0498149f0e2b637fe8905186e08a5410c6f2b013bb41b"
}
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/identity/test_private_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_sign_compact(sign_compact):
private_key = PrivateKey.from_passphrase(sign_compact['passphrase'])

message = bytes.fromhex(sign_compact['data']['message'])
signature = private_key.sign_compact(message)
signature = private_key.sign(message)

assert signature[0] == sign_compact['data']['v']
assert signature[1:33] == bytes.fromhex(sign_compact['data']['r'])
Expand Down
2 changes: 1 addition & 1 deletion tests/transactions/builder/test_evm_call_builder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from crypto.transactions.builder.evm_call_builder import EvmCallBuilder

def test_evm_call_transaction(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('evm-sign')
fixture = load_transaction_fixture('transactions/evm-sign')

builder = (
EvmCallBuilder
Expand Down
6 changes: 3 additions & 3 deletions tests/transactions/builder/test_multipayment_builder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from crypto.transactions.builder.multipayment_builder import MultipaymentBuilder

def test_it_should_sign_it_with_a_passphrase(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('multipayment')
fixture = load_transaction_fixture('transactions/multipayment')

builder = (
MultipaymentBuilder
Expand All @@ -28,7 +28,7 @@ def test_it_should_sign_it_with_a_passphrase(passphrase, load_transaction_fixtur
assert builder.verify()

def test_it_should_handle_single_recipient(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('multipayment-single')
fixture = load_transaction_fixture('transactions/multipayment-single')

builder = (
MultipaymentBuilder
Expand All @@ -54,7 +54,7 @@ def test_it_should_handle_single_recipient(passphrase, load_transaction_fixture)
assert builder.verify()

def test_it_should_handle_empty_payment(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('multipayment-empty')
fixture = load_transaction_fixture('transactions/multipayment-empty')

builder = (
MultipaymentBuilder
Expand Down
2 changes: 1 addition & 1 deletion tests/transactions/builder/test_transfer_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from crypto.utils.unit_converter import UnitConverter

def test_it_should_sign_it_with_a_passphrase(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('transfer')
fixture = load_transaction_fixture('transactions/transfer')

builder = (
TransferBuilder
Expand Down
4 changes: 2 additions & 2 deletions tests/transactions/builder/test_unvote_builder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from crypto.transactions.builder.unvote_builder import UnvoteBuilder

def test_unvote_transaction(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('unvote')
fixture = load_transaction_fixture('transactions/unvote')

builder = (
UnvoteBuilder
Expand Down Expand Up @@ -29,7 +29,7 @@ def test_unvote_transaction(passphrase, load_transaction_fixture):
assert builder.verify()

def test_unvote_transaction_with_default_recipient_address(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('unvote')
fixture = load_transaction_fixture('transactions/unvote')

builder = (
UnvoteBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from crypto.transactions.builder.username_registration_builder import UsernameRegistrationBuilder

def test_username_registration_transaction(passphrase, username, load_transaction_fixture):
fixture = load_transaction_fixture('username-registration')
fixture = load_transaction_fixture('transactions/username-registration')

builder = (
UsernameRegistrationBuilder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from crypto.transactions.builder.username_resignation_builder import UsernameResignationBuilder

def test_username_resignation_transaction(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('username-resignation')
fixture = load_transaction_fixture('transactions/username-resignation')

builder = (
UsernameResignationBuilder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from crypto.transactions.builder.validator_registration_builder import ValidatorRegistrationBuilder

def test_validator_registration_transaction(passphrase, validator_public_key, load_transaction_fixture):
fixture = load_transaction_fixture('validator-registration')
fixture = load_transaction_fixture('transactions/validator-registration')

builder = (
ValidatorRegistrationBuilder
Expand Down Expand Up @@ -31,7 +31,7 @@ def test_validator_registration_transaction(passphrase, validator_public_key, lo
assert builder.verify()

def test_validator_registration_transaction_with_default_recipient_address(passphrase, validator_public_key, load_transaction_fixture):
fixture = load_transaction_fixture('validator-registration')
fixture = load_transaction_fixture('transactions/validator-registration')

builder = (
ValidatorRegistrationBuilder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from crypto.transactions.builder.validator_resignation_builder import ValidatorResignationBuilder

def test_validator_resignation_transaction(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('validator-resignation')
fixture = load_transaction_fixture('transactions/validator-resignation')

builder = (
ValidatorResignationBuilder
Expand Down Expand Up @@ -29,7 +29,7 @@ def test_validator_resignation_transaction(passphrase, load_transaction_fixture)
assert builder.verify()

def test_validator_resignation_transaction_with_default_recipient_address(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('validator-resignation')
fixture = load_transaction_fixture('transactions/validator-resignation')

builder = (
ValidatorResignationBuilder
Expand Down
4 changes: 2 additions & 2 deletions tests/transactions/builder/test_vote_builder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from crypto.transactions.builder.vote_builder import VoteBuilder

def test_vote_transaction(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('vote')
fixture = load_transaction_fixture('transactions/vote')

builder = (
VoteBuilder
Expand Down Expand Up @@ -30,7 +30,7 @@ def test_vote_transaction(passphrase, load_transaction_fixture):
assert builder.verify()

def test_vote_transaction_with_default_recipient_address(passphrase, load_transaction_fixture):
fixture = load_transaction_fixture('vote')
fixture = load_transaction_fixture('transactions/vote')

builder = (
VoteBuilder
Expand Down
16 changes: 8 additions & 8 deletions tests/transactions/test_deserializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,52 @@ def assert_deserialized(fixture, keys):
return transaction

def test_deserialize_transfer(load_transaction_fixture):
fixture = load_transaction_fixture('transfer')
fixture = load_transaction_fixture('transactions/transfer')
transaction = assert_deserialized(fixture, ['id', 'nonce', 'gasPrice', 'gasLimit', 'value', 'v', 'r', 's'])

assert isinstance(transaction, Transfer)
assert transaction.data['value'] == '100000000'

def test_deserialize_vote(load_transaction_fixture):
fixture = load_transaction_fixture('vote')
fixture = load_transaction_fixture('transactions/vote')
transaction = assert_deserialized(fixture, ['id', 'nonce', 'gasPrice', 'gasLimit', 'v', 'r', 's'])

assert isinstance(transaction, Vote)
assert transaction.data['vote'].lower() == '0xc3bbe9b1cee1ff85ad72b87414b0e9b7f2366763'
assert transaction.data['id'] == fixture['data']['id']

def test_deserialize_unvote(load_transaction_fixture):
fixture = load_transaction_fixture('unvote')
fixture = load_transaction_fixture('transactions/unvote')
transaction = assert_deserialized(fixture, ['id', 'nonce', 'gasPrice', 'gasLimit', 'v', 'r', 's'])

assert isinstance(transaction, Unvote)

def test_deserialize_validator_registration(load_transaction_fixture):
fixture = load_transaction_fixture('validator-registration')
fixture = load_transaction_fixture('transactions/validator-registration')
transaction = assert_deserialized(fixture, ['id', 'nonce', 'gasPrice', 'gasLimit', 'v', 'r', 's'])

assert isinstance(transaction, ValidatorRegistration)

def test_deserialize_validator_resignation(load_transaction_fixture):
fixture = load_transaction_fixture('validator-resignation')
fixture = load_transaction_fixture('transactions/validator-resignation')
transaction = assert_deserialized(fixture, ['id', 'nonce', 'gasPrice', 'gasLimit', 'v', 'r', 's'])

assert isinstance(transaction, ValidatorResignation)

def test_deserialize_username_registration(load_transaction_fixture):
fixture = load_transaction_fixture('username-registration')
fixture = load_transaction_fixture('transactions/username-registration')
transaction = assert_deserialized(fixture, ['id', 'nonce', 'gasPrice', 'gasLimit', 'v', 'r', 's'])

assert isinstance(transaction, UsernameRegistration)

def test_deserialize_username_resignation(load_transaction_fixture):
fixture = load_transaction_fixture('username-resignation')
fixture = load_transaction_fixture('transactions/username-resignation')
transaction = assert_deserialized(fixture, ['id', 'nonce', 'gasPrice', 'gasLimit', 'v', 'r', 's'])

assert isinstance(transaction, UsernameResignation)

def test_deserialize_multipayment(load_transaction_fixture):
fixture = load_transaction_fixture('multipayment')
fixture = load_transaction_fixture('transactions/multipayment')
transaction = assert_deserialized(fixture, ['id', 'nonce', 'gasPrice', 'gasLimit', 'value', 'v', 'r', 's'])

assert isinstance(transaction, Multipayment)
Expand Down
Loading