mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-04-29 20:25:43 +08:00
upgraded bip38 (from halfmoonlabs/badge)
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
BIP 0038
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
:copyright: (c) 2014 by Halfmoon Labs
|
||||||
|
:license: MIT, see LICENSE for more details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .bip38 import bip38_decrypt, bip38_encrypt
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#-----------------------
|
|
||||||
# Copyright 2014 Halfmoon Labs, Inc.
|
|
||||||
# All Rights Reserved
|
|
||||||
#-----------------------
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
BIP 0038
|
BIP 0038
|
||||||
~~~~~
|
~~~~~
|
||||||
@@ -14,12 +8,18 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re, os, random, struct, hashlib, binascii, scrypt
|
import re, os, random, struct, hashlib, binascii, scrypt
|
||||||
|
from binascii import hexlify, unhexlify
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
from coinkit import BitcoinKeypair, b58check_encode, b58check_decode
|
from coinkit import BitcoinKeypair, b58check_encode, b58check_decode
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
|
|
||||||
|
#----------------------------
|
||||||
|
def get_new_aes(key):
|
||||||
|
return AES.new(key, AES.MODE_ECB)
|
||||||
|
|
||||||
|
#----------------------------
|
||||||
def bip38_encrypt(private_key, passphrase, n=16384, r=8, p=8, compressed=False):
|
def bip38_encrypt(private_key, passphrase, n=16384, r=8, p=8, compressed=False):
|
||||||
# determine the flagbyte
|
# determine the flagbyte
|
||||||
if compressed:
|
if compressed:
|
||||||
flagbyte = '\xe0'
|
flagbyte = '\xe0'
|
||||||
else:
|
else:
|
||||||
@@ -36,17 +36,11 @@ def bip38_encrypt(private_key, passphrase, n=16384, r=8, p=8, compressed=False):
|
|||||||
derived_half_1 = scrypt_derived_key[0:32]
|
derived_half_1 = scrypt_derived_key[0:32]
|
||||||
derived_half_2 = scrypt_derived_key[32:64]
|
derived_half_2 = scrypt_derived_key[32:64]
|
||||||
# combine parts of the private key and scrypt hash and AES encrypt them
|
# combine parts of the private key and scrypt hash and AES encrypt them
|
||||||
aes = AES.new(derived_half_2)
|
aes = get_new_aes(derived_half_2)
|
||||||
encrypted_half_1 = aes.encrypt(
|
xor_result_1 = long(hex_private_key[0:32], 16) ^ long(hexlify(derived_half_1[0:16]), 16)
|
||||||
binascii.unhexlify(
|
xor_result_2 = long(hex_private_key[32:64], 16) ^ long(hexlify(derived_half_1[16:32]), 16)
|
||||||
'%0.32x' % (long(hex_private_key[0:32], 16) ^ long(binascii.hexlify(derived_half_1[0:16]), 16))
|
encrypted_half_1 = aes.encrypt(unhexlify('%0.32x' % (xor_result_1)))
|
||||||
)
|
encrypted_half_2 = aes.encrypt(unhexlify('%0.32x' % (xor_result_2)))
|
||||||
)
|
|
||||||
encrypted_half_2 = aes.encrypt(
|
|
||||||
binascii.unhexlify(
|
|
||||||
'%0.32x' % (long(hex_private_key[32:64], 16) ^ long(binascii.hexlify(derived_half_1[16:32]), 16))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# build the encrypted private key from the checksum and encrypted parts
|
# build the encrypted private key from the checksum and encrypted parts
|
||||||
encrypted_private_key = ('\x42' + flagbyte + address_checksum + encrypted_half_1 + encrypted_half_2)
|
encrypted_private_key = ('\x42' + flagbyte + address_checksum + encrypted_half_1 + encrypted_half_2)
|
||||||
# base 58 encode the encrypted private key
|
# base 58 encode the encrypted private key
|
||||||
@@ -54,6 +48,7 @@ def bip38_encrypt(private_key, passphrase, n=16384, r=8, p=8, compressed=False):
|
|||||||
# return the encrypted private key
|
# return the encrypted private key
|
||||||
return b58check_encrypted_private_key
|
return b58check_encrypted_private_key
|
||||||
|
|
||||||
|
#----------------------------
|
||||||
def bip38_decrypt(b58check_encrypted_private_key, passphrase, n=16384, r=8, p=8):
|
def bip38_decrypt(b58check_encrypted_private_key, passphrase, n=16384, r=8, p=8):
|
||||||
# decode private key from base 58 check to binary
|
# decode private key from base 58 check to binary
|
||||||
encrypted_private_key = b58check_decode(b58check_encrypted_private_key)
|
encrypted_private_key = b58check_decode(b58check_encrypted_private_key)
|
||||||
@@ -68,16 +63,18 @@ def bip38_decrypt(b58check_encrypted_private_key, passphrase, n=16384, r=8, p=8)
|
|||||||
derived_half_1 = scrypt_derived_key[0:32]
|
derived_half_1 = scrypt_derived_key[0:32]
|
||||||
derived_half_2 = scrypt_derived_key[32:64]
|
derived_half_2 = scrypt_derived_key[32:64]
|
||||||
# decrypt the encrypted halves
|
# decrypt the encrypted halves
|
||||||
aes = AES.new(derived_half_2)
|
aes = get_new_aes(derived_half_2)
|
||||||
decrypted_half_1 = aes.decrypt(encrypted_half_1)
|
decrypted_half_1 = aes.decrypt(encrypted_half_1)
|
||||||
decrypted_half_2 = aes.decrypt(encrypted_half_2)
|
decrypted_half_2 = aes.decrypt(encrypted_half_2)
|
||||||
# get the original private key from the encrypted halves + the derived half
|
# get the original private key from the encrypted halves + the derived half
|
||||||
decrypted_private_key = '%064x' % (long(binascii.hexlify(decrypted_half_1 + decrypted_half_2), 16) ^ long(binascii.hexlify(derived_half_1), 16))
|
xor_result = long(hexlify(decrypted_half_1 + decrypted_half_2), 16) ^ long(hexlify(derived_half_1), 16)
|
||||||
|
decrypted_private_key = '%064x' % (xor_result)
|
||||||
# get the address corresponding to the private key
|
# get the address corresponding to the private key
|
||||||
k = BitcoinKeypair(decrypted_private_key)
|
k = BitcoinKeypair(decrypted_private_key)
|
||||||
address = k.address()
|
address = k.address()
|
||||||
|
|
||||||
# make sure the address matches the checksum in the original encrypted key
|
# make sure the address matches the checksum in the original encrypted key
|
||||||
if address_checksum != sha256(sha256(address).digest()).digest()[0:4]:
|
if address_checksum != sha256(sha256(address).digest()).digest()[0:4]:
|
||||||
raise ValueError('Invalid private key and password combo.')
|
raise ValueError('Invalid private key and password combo.')
|
||||||
# return the decrypted private key
|
# return the decrypted private key
|
||||||
return k.private_key()
|
return k.wif_pk()
|
||||||
Reference in New Issue
Block a user