added tests for BIP-0039

This commit is contained in:
Alexey Karyabkin 2018-06-01 19:58:11 +04:00
parent 82339c74c6
commit 8adcf0a0bd
3 changed files with 153 additions and 0 deletions

30
tests/bip32_fixtures.py Normal file
View File

@ -0,0 +1,30 @@
import pytest
import random
#@pytest.fixture
#def gen_entropy(bit_size):
#rnd = random.systemRandom(123456)
#return rnd.randint(0, 255)
@pytest.fixture
def mnemonic_128():
return 'life evoke adult pen staff wrist start virtual hover cactus canoe web'
@pytest.fixture
def entropy_128():
return b'\xf8\xc40\x807?G\xa9\x7f\x9e\xa0\xa2`y8@'
@pytest.yield_fixture
def wordlist():
f = None
def select_wordlist(filename):
nonlocal f
assert f is None
f = open(filename)
return f
yield select_wordlist
if f is not None:
f.close()

6
tests/test/conftest.py Normal file
View File

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
import pytest
pytest_plugins = ['bip32_fixtures']

117
tests/test_bip32.py Normal file
View File

@ -0,0 +1,117 @@
import pybtc
import os
import random
import hashlib
import hmac
from binascii import hexlify, unhexlify
mnemonic_list=dict(english='/home/kav/develop/bitapps/pybtc/pybtc/bip-0039/english.txt')
def test_generate_seed():
assert 1 == pybtc.generate_seed()
def test_create_master_key():
assert 1
def add_checksum(data):
mask = 0b10000000
data_int = int.from_bytes(data, byteorder="big")
data_bit_len = len(data) * 8 // 32
print('databitlen', data_bit_len)
data_hash = hashlib.sha256(data).hexdigest()
fbyte_hash = unhexlify(data_hash)[0]
print(bin(fbyte_hash))
while data_bit_len:
data_bit_len -= 1
data_int = (data_int << 1) | 1 if fbyte_hash & mask else data_int << 1
mask = mask >> 1
return data_int
#def create_mnemonic(bits=256, language='english'):
def create_mnemonic(bits=256, _wordlist=[]):
#english = wordlist(mnemonic_list[language]).read().split('\n')
english = _wordlist #('/home/kav/develop/bitapps/pybtc/pybtc/bip-0039/english.txt').read().split('\n')
#print(english)
passphrase = []
entropy = os.urandom(bits // 8)
entropy_int = int.from_bytes(entropy, byteorder="big")
print(entropy)
print('ent_int', entropy_int)
print(bin(entropy_int))
entropy_bit_len = len(entropy) * 8
chk_sum_bit_len = entropy_bit_len // 32
#sentence_len = (entropy_bit_len + chk_sum_bit_len) // 11
entropy_hash = hashlib.sha256(entropy).hexdigest()
fbyte_hash = unhexlify(entropy_hash)[0]
entropy_int = add_checksum(entropy)
print(bin(entropy_int))
while entropy_int:
passphrase.append(english[entropy_int & 0b11111111111])
entropy_int = entropy_int >> 11
return ' '.join(passphrase[::-1])
def test_create_mnemonic(wordlist, entropy_128, mnemonic_128):
bits = 128
english = wordlist('/home/kav/develop/bitapps/pybtc/pybtc/bip-0039/english.txt').read().rstrip('\n').split('\n')
passphrase = create_mnemonic(bits, english)
#print(passphrase)
if bits == 128:
assert len(passphrase.split()) == 12
elif bits == 160:
assert len(passphrase.split()) == 15
elif bits == 192:
assert len(passphrase.split()) == 18
elif bits == 224:
assert len(passphrase.split()) == 21
elif bits == 256:
assert len(passphrase.split()) == 24
else:
assert 0
# entropy int bin
#0b10010101111101101101011000010010010011100001100010101110111100111000010111000001101101001111011110111010110010001101011011100011
# first byte hash entropy
#0b1111101
# added checksum to entropy int bin
#0b100101011111011011010110000100100100111000011000101011101111001110000101110000011011010011110111101110101100100011010110111000110111
# passphrase
#['shoulder', 'cup', 'stone', 'waste', 'custom', 'blade', 'keep', 'memory', 'order', 'loyal', 'repeat', 'nominee']
print(mnemonic2bytes(passphrase.split(), english))
assert 0
def mnemonic2bytes(mnemonic, english):
wordlist_pos = dict()
for pos, word in enumerate(english):
wordlist_pos[word] = pos
word_count = len(mnemonic)
ent_int = None
bit_size = word_count * 11
chk_sum_bit_len = word_count * 11 % 32
for word in mnemonic:
ent_int = (ent_int << 11) | wordlist_pos[word] if ent_int else wordlist_pos[word]
chk_sum = ent_int & (2**chk_sum_bit_len-1)
ent_int = ent_int >> chk_sum_bit_len
print('ent_int', ent_int)
print(bin(ent_int))
ent = ent_int.to_bytes((bit_size - chk_sum_bit_len) // 8, byteorder="big")
ent_hash = hashlib.sha256().hexdigest()
fb = unhexlify(ent_hash)[0]
print(fb)
print((fb >> (8 - chk_sum_bit_len)) & chk_sum)
return ent