Skip to content

Commit

Permalink
Refactor for API layer
Browse files Browse the repository at this point in the history
  • Loading branch information
ethankosakovsky committed Apr 19, 2020
1 parent cedb776 commit 5dd0317
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 15 deletions.
64 changes: 64 additions & 0 deletions bipentropy/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python
#
# Copyright (c) 2020 Ethan Kosakovsky <ethankosakovsky@protonmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import bipentropy


def bip39(xprv_string, language, words, index):
# 83696968'/39'/language'/words'/index'
language_lookup = {
'english': 0,
'japanese': 1,
'korean': 2,
'spanish': 3,
'chinese_simplified': 4,
'chinese_traditional': 5,
'french': 6,
'italian': 7,
'czech': 8
}
lang_code = language_lookup[language]
e = bipentropy.BIPEntropy()
path = f"83696968p/39p/{lang_code}p/{words}p/{index}p"

entropy = e.bip32_xprv_to_entropy(path, xprv_string)
return e.entropy_to_bip39(entropy, words, language)


def wif(xprv_string, index):
# m/83696968'/0'/index'
e = bipentropy.BIPEntropy()
path = f"83696968p/0p/{index}p"
return e.entropy_to_wif(e.bip32_xprv_to_entropy(path, xprv_string))


def hex(xprv_string, index, width):
# m/83696968'/0'/index'
e = bipentropy.BIPEntropy()
path = f"83696968p/128169p/{width}p/{index}p"
return e.bip32_xprv_to_hex(path, width, xprv_string)


def xprv(xprv_string, index):
# 83696968'/32'/index'
e = bipentropy.BIPEntropy()
path = f"83696968p/32p/{index}p"
return e.bip32_xprv_to_xprv(path, xprv_string)
13 changes: 7 additions & 6 deletions bipentropy/bipentropy.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@


class BIPEntropy(object):
def __decorate_path(self, path):
return path.replace("m/", "").replace("'", "p")

def __get_k_from_node(self, node):
return to_bytes_32(node.secret_exponent())

def __derive_k(self, path, xprv):
path = path.replace("m/", "").replace("'", "p")
path = self.__decorate_path(path)
node = xprv.subkey_for_path(path)
return self.__get_k_from_node(node)

Expand All @@ -50,15 +52,14 @@ def bip32_xprv_to_entropy(self, path, xprv_string):
raise ValueError('ERROR: Invalid xprv')
return self.__hmac_sha512(self.__derive_k(path, xprv))

def bip32_xprv_to_hex(self, index, width, xprv_string):
def bip32_xprv_to_hex(self, path, width, xprv_string):
# export entropy as hex
path = f"83696968p/128169p/{width}p/{index}p"
path = self.__decorate_path(path)
ent = self.bip32_xprv_to_entropy(path, xprv_string)
return ent[0:width].hex()

def bip32_xprv_to_xprv(self, index, xprv_string):
# app_no = 32 => XPRV to XPRV
path = f"83696968p/32p/{index}p"
def bip32_xprv_to_xprv(self, path, xprv_string):
path = self.__decorate_path(path)
node = BTC.parse.bip32_prv(xprv_string).subkey_for_path(path)

# if API to pycoin hadn't been shitcoined:
Expand Down
30 changes: 21 additions & 9 deletions test_entropy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from bipentropy import bipentropy
from bipentropy import app
import pytest

XPRV = 'xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb'
Expand Down Expand Up @@ -62,7 +63,7 @@ def test_wif_from_entropy():
entropy = e.bip32_xprv_to_entropy("m/83696968'/0'/0'", XPRV)
assert e.entropy_to_wif(entropy) == 'L11mqGbaozsMYDHS7dfZ2bPGL2viSH6zHr69MKwvpxuw7cCR4M1u'

def test_applications():
def test_mnemonic():
e = bipentropy.BIPEntropy()
entropy = e.bip32_xprv_to_entropy("m/83696968'/39'/0'/12'/0'", XPRV)
assert entropy[:16].hex() == 'f0337580e36fd50ef8734cd9dcfb9a78'
Expand All @@ -79,19 +80,30 @@ def test_applications():
assert e.entropy_to_bip39(entropy, 24) == \
'fabric crumble art inhale hurt crouch helmet since bike bomb twelve frog bicycle toward fox grant pulp spend sibling bunker caution nurse brain prison'

def test_xprv_application():
def test_xprv():
e = bipentropy.BIPEntropy()
result = e.bip32_xprv_to_xprv(0, XPRV)
result = e.bip32_xprv_to_xprv("83696968'/32'/0'", XPRV)
assert result == 'xprv9s21ZrQH143K3KJoGoKpsDsWdDNDBKs1wqFymBpCGJtrYXrfKzykGDBadZq5SrNde22F83X9qhFZr4uyV9TptTgLqCBc6XFN9tssphdxVeg'

@pytest.mark.parametrize('index, width, expect', [
(0, 32, '4f4ea2ef43af14e51f2453221d50762fc3767e2287dc524ca58f10e5225a6ead'),
(0, 64, '4fc6759ef9c0e12aed757ad874706a3955ef125c8f8eabb3909aeda028f5e285bf496a23265bac09f537f4cc5e1efa689f5625ded2cd996c042b2657263c6816'),
(1234, 64, 'e1a35aeae27cb3c93b0d437e94b64a891cdff9ac250537ec675d0e6a2680f1d2edf9927f4c5233b19b15fdea4063a8b62f85ff8666176d226741ed192075a8db'),
@pytest.mark.parametrize('path, width, expect', [
("83696968'/128169'/32'/0'", 32, '4f4ea2ef43af14e51f2453221d50762fc3767e2287dc524ca58f10e5225a6ead'),
("83696968'/128169'/64'/0'", 64, '4fc6759ef9c0e12aed757ad874706a3955ef125c8f8eabb3909aeda028f5e285bf496a23265bac09f537f4cc5e1efa689f5625ded2cd996c042b2657263c6816'),
("83696968'/128169'/64'/1234'", 64, 'e1a35aeae27cb3c93b0d437e94b64a891cdff9ac250537ec675d0e6a2680f1d2edf9927f4c5233b19b15fdea4063a8b62f85ff8666176d226741ed192075a8db'),
])
def test_hex_application(index, width, expect):
def test_hex(path, width, expect):
e = bipentropy.BIPEntropy()
assert e.bip32_xprv_to_hex(index, width, XPRV) == expect
assert e.bip32_xprv_to_hex(path, width, XPRV) == expect

def test_bipentropy_applications():
assert app.bip39(XPRV, 'english', 18, 0) == \
'gate neutral humble top among february junior once buyer van sand subject clip enable trade crime future protect'

assert app.xprv(XPRV, 0) == \
'xprv9s21ZrQH143K3KJoGoKpsDsWdDNDBKs1wqFymBpCGJtrYXrfKzykGDBadZq5SrNde22F83X9qhFZr4uyV9TptTgLqCBc6XFN9tssphdxVeg'

assert app.wif(XPRV, 0) == 'L11mqGbaozsMYDHS7dfZ2bPGL2viSH6zHr69MKwvpxuw7cCR4M1u'

assert app.hex(XPRV, 0, 32) == '4f4ea2ef43af14e51f2453221d50762fc3767e2287dc524ca58f10e5225a6ead'

if __name__ == "__main__":
pytest.main()
Expand Down

0 comments on commit 5dd0317

Please sign in to comment.