From 6f8a64a17a2d6cf31dc5b012baa31211d272a8ab Mon Sep 17 00:00:00 2001 From: roks0n Date: Mon, 13 Aug 2018 19:36:34 +0200 Subject: [PATCH 1/5] add get_epoch to slot + write tests --- crypto/slot.py | 5 +++++ tests/test_slot.py | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/test_slot.py diff --git a/crypto/slot.py b/crypto/slot.py index 725144c..5073d7c 100644 --- a/crypto/slot.py +++ b/crypto/slot.py @@ -13,3 +13,8 @@ def get_time(): network = get_network() diff = (now - network['epoch']).seconds return diff + + +def get_epoch(): + network = get_network() + return network['epoch'] diff --git a/tests/test_slot.py b/tests/test_slot.py new file mode 100644 index 0000000..b04ef89 --- /dev/null +++ b/tests/test_slot.py @@ -0,0 +1,15 @@ +from datetime import datetime +from crypto.conf import use_network +from crypto.slot import get_epoch, get_time + + +def test_get_epoch(): + use_network('devnet') + result = get_epoch() + assert isinstance(result, datetime) + + +def test_get_time(): + use_network('devnet') + result = get_time() + assert isinstance(result, int) From 8a01cba46173f0864fd6d64270288eb7eaed8780 Mon Sep 17 00:00:00 2001 From: roks0n Date: Mon, 13 Aug 2018 21:03:51 +0200 Subject: [PATCH 2/5] identity: fix typo in function name + add functions for address + tests --- crypto/identity/address.py | 41 +++++++++++++++++++++++++++++++++- crypto/identity/keys.py | 2 +- crypto/message.py | 4 ++-- tests/identity/test_address.py | 18 ++++++++++++++- tests/identity/test_keys.py | 6 ++--- 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/crypto/identity/address.py b/crypto/identity/address.py index 6905c29..383e248 100644 --- a/crypto/identity/address.py +++ b/crypto/identity/address.py @@ -6,6 +6,7 @@ from binary.unsigned_integer.writer import write_bit8 from crypto.conf import get_network +from crypto.identity.keys import private_key_from_passphrase, compress_ecdsa_public_key def address_from_public_key(public_key, network_version=None): @@ -22,7 +23,45 @@ def address_from_public_key(public_key, network_version=None): network = get_network() network_version = network['version'] - network_version = network_version ripemd160 = hashlib.new('ripemd160', unhexlify(public_key)) seed = write_bit8(network_version) + ripemd160.digest() return b58encode_check(seed) + + +def address_from_private_key(private_key, network_version=None): + """Get an address from private key + + Args: + private_key (string): + network_version (int, optional): + + Returns: + TYPE: Description + """ + if not network_version: + network = get_network() + network_version = network['version'] + + public_key = compress_ecdsa_public_key(unhexlify(private_key)) + ripemd160 = hashlib.new('ripemd160', unhexlify(public_key)) + seed = write_bit8(network_version) + ripemd160.digest() + return b58encode_check(seed) + + +def address_from_passphrase(passphrase, network_version=None): + """Get an address from passphrase + + Args: + passphrase (bytes): + network_version (int, optional): + + Returns: + TYPE: Description + """ + if not network_version: + network = get_network() + network_version = network['version'] + + private_key = hashlib.sha256(passphrase).hexdigest() + address = address_from_private_key(private_key) + return address diff --git a/crypto/identity/keys.py b/crypto/identity/keys.py index 15f4363..da613e4 100644 --- a/crypto/identity/keys.py +++ b/crypto/identity/keys.py @@ -6,7 +6,7 @@ from ecdsa.util import number_to_string -def privat_key_from_passphrase(passphrase): +def private_key_from_passphrase(passphrase): """Get a private key from a given passphrase Args: diff --git a/crypto/message.py b/crypto/message.py index 4227ec6..e8ce57d 100644 --- a/crypto/message.py +++ b/crypto/message.py @@ -7,7 +7,7 @@ from crypto.exceptions import ArkBadDigestException, ArkBadSignatureException from crypto.identity.keys import ( - privat_key_from_passphrase, public_key_from_passphrase, uncompress_ecdsa_public_key + private_key_from_passphrase, public_key_from_passphrase, uncompress_ecdsa_public_key ) @@ -21,7 +21,7 @@ def sign_message(message, passphrase): Returns: dict: dict containing message, public_key and a signature data """ - private_key = privat_key_from_passphrase(passphrase) + private_key = private_key_from_passphrase(passphrase) signin_key = SigningKey.from_string(unhexlify(private_key), SECP256k1) signature = hexlify( signin_key.sign_deterministic(message, hashfunc=sha256, sigencode=sigencode_der_canonize) diff --git a/tests/identity/test_address.py b/tests/identity/test_address.py index d1c1859..8008113 100644 --- a/tests/identity/test_address.py +++ b/tests/identity/test_address.py @@ -1,5 +1,7 @@ from crypto.conf import use_network -from crypto.identity.address import address_from_public_key +from crypto.identity.address import ( + address_from_public_key, address_from_passphrase, address_from_private_key +) def test_address_from_public_key(): @@ -7,3 +9,17 @@ def test_address_from_public_key(): public_key = '03bd4f16e39aaba5cba6a87b7498b08ce540f279be367e68ae96fb05dfabe203ad'.encode() address = address_from_public_key(public_key) assert address == 'DBi2HdDY8TqMCD2aFLVomEF92gzeDmEHmR'.encode() + + +def test_address_from_private_key(): + use_network('devnet') + private_key = 'd8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712'.encode() + address = address_from_private_key(private_key) + assert address == 'D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib'.encode() + + +def test_address_from_passphrase(): + use_network('devnet') + passphrase = 'this is a top secret passphrase'.encode() + address = address_from_passphrase(passphrase) + assert address == 'D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib'.encode() diff --git a/tests/identity/test_keys.py b/tests/identity/test_keys.py index f20f514..33c7760 100644 --- a/tests/identity/test_keys.py +++ b/tests/identity/test_keys.py @@ -1,8 +1,8 @@ -from crypto.identity.keys import privat_key_from_passphrase, public_key_from_passphrase +from crypto.identity.keys import private_key_from_passphrase, public_key_from_passphrase -def test_privat_key_from_passphrase(): - private_key = privat_key_from_passphrase('this is a top secret passphrase'.encode()) +def test_private_key_from_passphrase(): + private_key = private_key_from_passphrase('this is a top secret passphrase'.encode()) assert private_key == b'd8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712' From 51b5f0707ad4b653bf3d6d040907b6139031c9ce Mon Sep 17 00:00:00 2001 From: roks0n Date: Mon, 13 Aug 2018 21:27:29 +0200 Subject: [PATCH 3/5] create wif_from_passphrase function + add test --- crypto/identity/wif.py | 26 ++++++++++++++++++++++++++ tests/identity/test_wif.py | 8 ++++++++ 2 files changed, 34 insertions(+) create mode 100644 crypto/identity/wif.py create mode 100644 tests/identity/test_wif.py diff --git a/crypto/identity/wif.py b/crypto/identity/wif.py new file mode 100644 index 0000000..f24c28f --- /dev/null +++ b/crypto/identity/wif.py @@ -0,0 +1,26 @@ +import hashlib + +from base58 import b58encode_check + +from binary.unsigned_integer.writer import write_bit8 + +from crypto.conf import get_network + + +def wif_from_passphrase(passphrase, network_wif=None): + """Get wif from passphrase + + Args: + passphrase (bytes): + network_wif (int, optional): + + Returns: + string: wif + """ + if not network_wif: + network = get_network() + network_wif = network['wif'] + + private_key = hashlib.sha256(passphrase) + seed = write_bit8(network_wif) + private_key.digest() + write_bit8(0x01) + return b58encode_check(seed) diff --git a/tests/identity/test_wif.py b/tests/identity/test_wif.py new file mode 100644 index 0000000..cc79f24 --- /dev/null +++ b/tests/identity/test_wif.py @@ -0,0 +1,8 @@ +from crypto.conf import use_network +from crypto.identity.wif import wif_from_passphrase + + +def test_wif_from_passphrase(): + use_network('devnet') + result = wif_from_passphrase('this is a top secret passphrase'.encode()) + assert result == 'SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA'.encode() From 0683fe26d0685aac10e805cfe96d5f5b895ed9d3 Mon Sep 17 00:00:00 2001 From: roks0n Date: Mon, 13 Aug 2018 21:28:02 +0200 Subject: [PATCH 4/5] lint fixes --- crypto/identity/address.py | 4 ++-- tests/identity/test_address.py | 2 +- tests/test_slot.py | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crypto/identity/address.py b/crypto/identity/address.py index 383e248..4d3bc27 100644 --- a/crypto/identity/address.py +++ b/crypto/identity/address.py @@ -6,7 +6,7 @@ from binary.unsigned_integer.writer import write_bit8 from crypto.conf import get_network -from crypto.identity.keys import private_key_from_passphrase, compress_ecdsa_public_key +from crypto.identity.keys import compress_ecdsa_public_key def address_from_public_key(public_key, network_version=None): @@ -56,7 +56,7 @@ def address_from_passphrase(passphrase, network_version=None): network_version (int, optional): Returns: - TYPE: Description + string: address """ if not network_version: network = get_network() diff --git a/tests/identity/test_address.py b/tests/identity/test_address.py index 8008113..68e77b4 100644 --- a/tests/identity/test_address.py +++ b/tests/identity/test_address.py @@ -1,6 +1,6 @@ from crypto.conf import use_network from crypto.identity.address import ( - address_from_public_key, address_from_passphrase, address_from_private_key + address_from_passphrase, address_from_private_key, address_from_public_key ) diff --git a/tests/test_slot.py b/tests/test_slot.py index b04ef89..cc70193 100644 --- a/tests/test_slot.py +++ b/tests/test_slot.py @@ -1,4 +1,5 @@ from datetime import datetime + from crypto.conf import use_network from crypto.slot import get_epoch, get_time From 217ddad7ce258749972b000b164da0b4876fc230 Mon Sep 17 00:00:00 2001 From: roks0n Date: Mon, 13 Aug 2018 21:30:49 +0200 Subject: [PATCH 5/5] checkboxes in readme --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 166dde5..9401af7 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,9 @@ We will not be accepting new PRs until we are happy with the base of the client - [x] toJson - it returns a dictionary object ### Address Identity -- [ ] fromPassphrase -- [ ] fromPublicKey -- [ ] fromPrivateKey +- [x] fromPassphrase +- [x] fromPublicKey +- [x] fromPrivateKey - [ ] validate ### Private Key Identity @@ -83,7 +83,7 @@ We will not be accepting new PRs until we are happy with the base of the client - [ ] fromHex ### WIF Identity -- [ ] fromPassphrase +- [x] fromPassphrase ### Configuration - [x] getNetwork @@ -93,7 +93,7 @@ We will not be accepting new PRs until we are happy with the base of the client ### Slot - [x] time -- [ ] epoch +- [x] epoch ### Networks (Mainnet, Devnet & Testnet) - [x] epoch