Moved decodeWalletImportFormat() from shared to highlevelcrypto,
not addresses, where it's supposed to be because it uses pyelliptic.arithmetic, addresses.decodeBase58() returns int which needs to be encoded. Defined encodeWalletImportFormat() and replaced all uses.
This commit is contained in:
parent
15039cea94
commit
8942f63d06
|
@ -15,7 +15,6 @@ from addresses import decodeAddress, encodeAddress, encodeVarint
|
||||||
from bmconfigparser import BMConfigParser
|
from bmconfigparser import BMConfigParser
|
||||||
from fallback import RIPEMD160Hash
|
from fallback import RIPEMD160Hash
|
||||||
from network import StoppableThread
|
from network import StoppableThread
|
||||||
from pyelliptic import arithmetic
|
|
||||||
from pyelliptic.openssl import OpenSSL
|
from pyelliptic.openssl import OpenSSL
|
||||||
from six.moves import configparser, queue
|
from six.moves import configparser, queue
|
||||||
|
|
||||||
|
@ -163,20 +162,10 @@ class addressGenerator(StoppableThread):
|
||||||
address = encodeAddress(
|
address = encodeAddress(
|
||||||
addressVersionNumber, streamNumber, ripe)
|
addressVersionNumber, streamNumber, ripe)
|
||||||
|
|
||||||
# An excellent way for us to store our keys
|
privSigningKeyWIF = highlevelcrypto.encodeWalletImportFormat(
|
||||||
# is in Wallet Import Format. Let us convert now.
|
potentialPrivSigningKey)
|
||||||
# https://en.bitcoin.it/wiki/Wallet_import_format
|
privEncryptionKeyWIF = highlevelcrypto.encodeWalletImportFormat(
|
||||||
privSigningKey = b'\x80' + potentialPrivSigningKey
|
potentialPrivEncryptionKey)
|
||||||
checksum = hashlib.sha256(hashlib.sha256(
|
|
||||||
privSigningKey).digest()).digest()[0:4]
|
|
||||||
privSigningKeyWIF = arithmetic.changebase(
|
|
||||||
privSigningKey + checksum, 256, 58)
|
|
||||||
|
|
||||||
privEncryptionKey = b'\x80' + potentialPrivEncryptionKey
|
|
||||||
checksum = hashlib.sha256(hashlib.sha256(
|
|
||||||
privEncryptionKey).digest()).digest()[0:4]
|
|
||||||
privEncryptionKeyWIF = arithmetic.changebase(
|
|
||||||
privEncryptionKey + checksum, 256, 58)
|
|
||||||
|
|
||||||
BMConfigParser().add_section(address)
|
BMConfigParser().add_section(address)
|
||||||
BMConfigParser().set(address, 'label', label)
|
BMConfigParser().set(address, 'label', label)
|
||||||
|
@ -300,21 +289,12 @@ class addressGenerator(StoppableThread):
|
||||||
saveAddressToDisk = False
|
saveAddressToDisk = False
|
||||||
|
|
||||||
if saveAddressToDisk and live:
|
if saveAddressToDisk and live:
|
||||||
# An excellent way for us to store our keys is
|
privSigningKeyWIF = \
|
||||||
# in Wallet Import Format. Let us convert now.
|
highlevelcrypto.encodeWalletImportFormat(
|
||||||
# https://en.bitcoin.it/wiki/Wallet_import_format
|
potentialPrivSigningKey)
|
||||||
privSigningKey = b'\x80' + potentialPrivSigningKey
|
privEncryptionKeyWIF = \
|
||||||
checksum = hashlib.sha256(hashlib.sha256(
|
highlevelcrypto.encodeWalletImportFormat(
|
||||||
privSigningKey).digest()).digest()[0:4]
|
potentialPrivEncryptionKey)
|
||||||
privSigningKeyWIF = arithmetic.changebase(
|
|
||||||
privSigningKey + checksum, 256, 58)
|
|
||||||
|
|
||||||
privEncryptionKey = b'\x80' + \
|
|
||||||
potentialPrivEncryptionKey
|
|
||||||
checksum = hashlib.sha256(hashlib.sha256(
|
|
||||||
privEncryptionKey).digest()).digest()[0:4]
|
|
||||||
privEncryptionKeyWIF = arithmetic.changebase(
|
|
||||||
privEncryptionKey + checksum, 256, 58)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
BMConfigParser().add_section(address)
|
BMConfigParser().add_section(address)
|
||||||
|
|
|
@ -193,15 +193,20 @@ class singleWorker(StoppableThread):
|
||||||
self.logger.info("Quitting...")
|
self.logger.info("Quitting...")
|
||||||
|
|
||||||
def _getKeysForAddress(self, address):
|
def _getKeysForAddress(self, address):
|
||||||
privSigningKeyBase58 = BMConfigParser().get(
|
try:
|
||||||
address, 'privsigningkey')
|
privSigningKeyBase58 = BMConfigParser().get(
|
||||||
privEncryptionKeyBase58 = BMConfigParser().get(
|
address, 'privsigningkey')
|
||||||
address, 'privencryptionkey')
|
privEncryptionKeyBase58 = BMConfigParser().get(
|
||||||
|
address, 'privencryptionkey')
|
||||||
|
except (configparser.NoSectionError, configparser.NoOptionError):
|
||||||
|
self.logger.error(
|
||||||
|
'Could not read or decode privkey for address %s', address)
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
privSigningKeyHex = hexlify(shared.decodeWalletImportFormat(
|
privSigningKeyHex = hexlify(
|
||||||
privSigningKeyBase58))
|
highlevelcrypto.decodeWalletImportFormat(privSigningKeyBase58))
|
||||||
privEncryptionKeyHex = hexlify(shared.decodeWalletImportFormat(
|
privEncryptionKeyHex = hexlify(
|
||||||
privEncryptionKeyBase58))
|
highlevelcrypto.decodeWalletImportFormat(privEncryptionKeyBase58))
|
||||||
|
|
||||||
# The \x04 on the beginning of the public keys are not sent.
|
# The \x04 on the beginning of the public keys are not sent.
|
||||||
# This way there is only one acceptable way to encode
|
# This way there is only one acceptable way to encode
|
||||||
|
@ -252,9 +257,7 @@ class singleWorker(StoppableThread):
|
||||||
message once it is done with the POW"""
|
message once it is done with the POW"""
|
||||||
# Look up my stream number based on my address hash
|
# Look up my stream number based on my address hash
|
||||||
myAddress = shared.myAddressesByHash[adressHash]
|
myAddress = shared.myAddressesByHash[adressHash]
|
||||||
# status
|
addressVersionNumber, streamNumber = decodeAddress(myAddress)[1:3]
|
||||||
_, addressVersionNumber, streamNumber, adressHash = (
|
|
||||||
decodeAddress(myAddress))
|
|
||||||
|
|
||||||
# 28 days from now plus or minus five minutes
|
# 28 days from now plus or minus five minutes
|
||||||
TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300))
|
TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300))
|
||||||
|
@ -267,18 +270,15 @@ class singleWorker(StoppableThread):
|
||||||
payload += protocol.getBitfield(myAddress)
|
payload += protocol.getBitfield(myAddress)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# privSigningKeyHex, privEncryptionKeyHex
|
pubSigningKey, pubEncryptionKey = self._getKeysForAddress(
|
||||||
_, _, pubSigningKey, pubEncryptionKey = \
|
myAddress)[2:]
|
||||||
self._getKeysForAddress(myAddress)
|
except ValueError:
|
||||||
except (configparser.NoSectionError, configparser.NoOptionError) as err:
|
return
|
||||||
self.logger.warning("Section or Option did not found: %s", err)
|
except Exception:
|
||||||
except Exception as err:
|
return self.logger.error(
|
||||||
self.logger.error(
|
|
||||||
'Error within doPOWForMyV2Pubkey. Could not read'
|
'Error within doPOWForMyV2Pubkey. Could not read'
|
||||||
' the keys from the keys.dat file for a requested'
|
' the keys from the keys.dat file for a requested'
|
||||||
' address. %s\n', err
|
' address. %s\n', exc_info=True)
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
payload += pubSigningKey + pubEncryptionKey
|
payload += pubSigningKey + pubEncryptionKey
|
||||||
|
|
||||||
|
@ -316,9 +316,8 @@ class singleWorker(StoppableThread):
|
||||||
try:
|
try:
|
||||||
myAddress = shared.myAddressesByHash[adressHash]
|
myAddress = shared.myAddressesByHash[adressHash]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# The address has been deleted.
|
return self.logger.warning( # The address has been deleted.
|
||||||
self.logger.warning("Can't find %s in myAddressByHash", hexlify(adressHash))
|
"Can't find %s in myAddressByHash", hexlify(adressHash))
|
||||||
return
|
|
||||||
if BMConfigParser().safeGetBoolean(myAddress, 'chan'):
|
if BMConfigParser().safeGetBoolean(myAddress, 'chan'):
|
||||||
self.logger.info('This is a chan address. Not sending pubkey.')
|
self.logger.info('This is a chan address. Not sending pubkey.')
|
||||||
return
|
return
|
||||||
|
@ -349,15 +348,13 @@ class singleWorker(StoppableThread):
|
||||||
# , privEncryptionKeyHex
|
# , privEncryptionKeyHex
|
||||||
privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \
|
privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \
|
||||||
self._getKeysForAddress(myAddress)
|
self._getKeysForAddress(myAddress)
|
||||||
except (configparser.NoSectionError, configparser.NoOptionError) as err:
|
except ValueError:
|
||||||
self.logger.warning("Section or Option did not found: %s", err)
|
return
|
||||||
except Exception as err:
|
except Exception:
|
||||||
self.logger.error(
|
return self.logger.error(
|
||||||
'Error within sendOutOrStoreMyV3Pubkey. Could not read'
|
'Error within sendOutOrStoreMyV3Pubkey. Could not read'
|
||||||
' the keys from the keys.dat file for a requested'
|
' the keys from the keys.dat file for a requested'
|
||||||
' address. %s\n', err
|
' address. %s\n', exc_info=True)
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
payload += pubSigningKey + pubEncryptionKey
|
payload += pubSigningKey + pubEncryptionKey
|
||||||
|
|
||||||
|
@ -424,15 +421,13 @@ class singleWorker(StoppableThread):
|
||||||
# , privEncryptionKeyHex
|
# , privEncryptionKeyHex
|
||||||
privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \
|
privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \
|
||||||
self._getKeysForAddress(myAddress)
|
self._getKeysForAddress(myAddress)
|
||||||
except (configparser.NoSectionError, configparser.NoOptionError) as err:
|
except ValueError:
|
||||||
self.logger.warning("Section or Option did not found: %s", err)
|
return
|
||||||
except Exception as err:
|
except Exception:
|
||||||
self.logger.error(
|
return self.logger.error(
|
||||||
'Error within sendOutOrStoreMyV4Pubkey. Could not read'
|
'Error within sendOutOrStoreMyV4Pubkey. Could not read'
|
||||||
' the keys from the keys.dat file for a requested'
|
' the keys from the keys.dat file for a requested'
|
||||||
' address. %s\n', err
|
' address. %s\n', exc_info=True)
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
dataToEncrypt += pubSigningKey + pubEncryptionKey
|
dataToEncrypt += pubSigningKey + pubEncryptionKey
|
||||||
|
|
||||||
|
@ -1114,8 +1109,9 @@ class singleWorker(StoppableThread):
|
||||||
' from the keys.dat file for our own address. %s\n',
|
' from the keys.dat file for our own address. %s\n',
|
||||||
err)
|
err)
|
||||||
continue
|
continue
|
||||||
privEncryptionKeyHex = hexlify(shared.decodeWalletImportFormat(
|
privEncryptionKeyHex = hexlify(
|
||||||
privEncryptionKeyBase58))
|
highlevelcrypto.decodeWalletImportFormat(
|
||||||
|
privEncryptionKeyBase58))
|
||||||
pubEncryptionKeyBase256 = unhexlify(highlevelcrypto.privToPub(
|
pubEncryptionKeyBase256 = unhexlify(highlevelcrypto.privToPub(
|
||||||
privEncryptionKeyHex))[1:]
|
privEncryptionKeyHex))[1:]
|
||||||
requiredAverageProofOfWorkNonceTrialsPerByte = \
|
requiredAverageProofOfWorkNonceTrialsPerByte = \
|
||||||
|
|
|
@ -30,6 +30,35 @@ def calculateInventoryHash(data):
|
||||||
return double_sha512(data)[:32]
|
return double_sha512(data)[:32]
|
||||||
|
|
||||||
|
|
||||||
|
# WIF (uses arithmetic ):
|
||||||
|
def decodeWalletImportFormat(WIFstring):
|
||||||
|
"""
|
||||||
|
Convert private key from base58 that's used in the config file to
|
||||||
|
8-bit binary string.
|
||||||
|
"""
|
||||||
|
fullString = a.changebase(WIFstring, 58, 256)
|
||||||
|
privkey = fullString[:-4]
|
||||||
|
if fullString[-4:] != \
|
||||||
|
hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]:
|
||||||
|
raise ValueError('Checksum failed')
|
||||||
|
elif privkey[0:1] == b'\x80': # checksum passed
|
||||||
|
return privkey[1:]
|
||||||
|
|
||||||
|
raise ValueError('No hex 80 prefix')
|
||||||
|
|
||||||
|
|
||||||
|
# An excellent way for us to store our keys
|
||||||
|
# is in Wallet Import Format. Let us convert now.
|
||||||
|
# https://en.bitcoin.it/wiki/Wallet_import_format
|
||||||
|
def encodeWalletImportFormat(privKey):
|
||||||
|
"""
|
||||||
|
Convert private key from binary 8-bit string into base58check WIF string.
|
||||||
|
"""
|
||||||
|
privKey = b'\x80' + privKey
|
||||||
|
checksum = hashlib.sha256(hashlib.sha256(privKey).digest()).digest()[0:4]
|
||||||
|
return a.changebase(privKey + checksum, 256, 58)
|
||||||
|
|
||||||
|
|
||||||
def makeCryptor(privkey):
|
def makeCryptor(privkey):
|
||||||
"""Return a private `.pyelliptic.ECC` instance"""
|
"""Return a private `.pyelliptic.ECC` instance"""
|
||||||
private_key = a.changebase(privkey, 16, 256, minlen=32)
|
private_key = a.changebase(privkey, 16, 256, minlen=32)
|
||||||
|
|
|
@ -23,8 +23,6 @@ from bmconfigparser import BMConfigParser
|
||||||
from debug import logger
|
from debug import logger
|
||||||
from helper_sql import sqlQuery
|
from helper_sql import sqlQuery
|
||||||
|
|
||||||
from pyelliptic import arithmetic
|
|
||||||
|
|
||||||
|
|
||||||
myECCryptorObjects = {}
|
myECCryptorObjects = {}
|
||||||
MyECSubscriptionCryptorObjects = {}
|
MyECSubscriptionCryptorObjects = {}
|
||||||
|
@ -76,35 +74,6 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def decodeWalletImportFormat(WIFstring):
|
|
||||||
# pylint: disable=inconsistent-return-statements
|
|
||||||
"""
|
|
||||||
Convert private key from base58 that's used in the config file to
|
|
||||||
8-bit binary string
|
|
||||||
"""
|
|
||||||
fullString = arithmetic.changebase(WIFstring, 58, 256)
|
|
||||||
privkey = fullString[:-4]
|
|
||||||
if fullString[-4:] != \
|
|
||||||
hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]:
|
|
||||||
logger.critical(
|
|
||||||
'Major problem! When trying to decode one of your'
|
|
||||||
' private keys, the checksum failed. Here are the first'
|
|
||||||
' 6 characters of the PRIVATE key: %s',
|
|
||||||
str(WIFstring)[:6]
|
|
||||||
)
|
|
||||||
os._exit(0) # pylint: disable=protected-access
|
|
||||||
# return ""
|
|
||||||
elif privkey[0] == '\x80': # checksum passed
|
|
||||||
return privkey[1:]
|
|
||||||
|
|
||||||
logger.critical(
|
|
||||||
'Major problem! When trying to decode one of your private keys,'
|
|
||||||
' the checksum passed but the key doesn\'t begin with hex 80.'
|
|
||||||
' Here is the PRIVATE key: %s', WIFstring
|
|
||||||
)
|
|
||||||
os._exit(0) # pylint: disable=protected-access
|
|
||||||
|
|
||||||
|
|
||||||
def reloadMyAddressHashes():
|
def reloadMyAddressHashes():
|
||||||
"""Reload keys for user's addresses from the config file"""
|
"""Reload keys for user's addresses from the config file"""
|
||||||
logger.debug('reloading keys from keys.dat file')
|
logger.debug('reloading keys from keys.dat file')
|
||||||
|
@ -118,30 +87,39 @@ def reloadMyAddressHashes():
|
||||||
hasEnabledKeys = False
|
hasEnabledKeys = False
|
||||||
for addressInKeysFile in BMConfigParser().addresses():
|
for addressInKeysFile in BMConfigParser().addresses():
|
||||||
isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled')
|
isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled')
|
||||||
if isEnabled:
|
if not isEnabled:
|
||||||
hasEnabledKeys = True
|
continue
|
||||||
# status
|
|
||||||
addressVersionNumber, streamNumber, hashobj = decodeAddress(
|
hasEnabledKeys = True
|
||||||
addressInKeysFile)[1:]
|
|
||||||
if addressVersionNumber in (2, 3, 4):
|
addressVersionNumber, streamNumber, hashobj = decodeAddress(
|
||||||
# Returns a simple 32 bytes of information encoded
|
addressInKeysFile)[1:]
|
||||||
# in 64 Hex characters, or null if there was an error.
|
if addressVersionNumber not in (2, 3, 4):
|
||||||
privEncryptionKey = hexlify(decodeWalletImportFormat(
|
logger.error(
|
||||||
BMConfigParser().get(addressInKeysFile, 'privencryptionkey')))
|
'Error in reloadMyAddressHashes: Can\'t handle'
|
||||||
# It is 32 bytes encoded as 64 hex characters
|
' address versions other than 2, 3, or 4.')
|
||||||
if len(privEncryptionKey) == 64:
|
continue
|
||||||
myECCryptorObjects[hashobj] = \
|
|
||||||
highlevelcrypto.makeCryptor(privEncryptionKey)
|
# Returns a simple 32 bytes of information encoded in 64 Hex characters.
|
||||||
myAddressesByHash[hashobj] = addressInKeysFile
|
try:
|
||||||
tag = highlevelcrypto.double_sha512(
|
privEncryptionKey = hexlify(
|
||||||
encodeVarint(addressVersionNumber)
|
highlevelcrypto.decodeWalletImportFormat(
|
||||||
+ encodeVarint(streamNumber) + hashobj)[32:]
|
BMConfigParser().get(addressInKeysFile, 'privencryptionkey')
|
||||||
myAddressesByTag[tag] = addressInKeysFile
|
))
|
||||||
else:
|
except ValueError:
|
||||||
logger.error(
|
logger.error(
|
||||||
'Error in reloadMyAddressHashes: Can\'t handle'
|
'Error in reloadMyAddressHashes: failed to decode'
|
||||||
' address versions other than 2, 3, or 4.'
|
' one of the private keys for address %s', addressInKeysFile)
|
||||||
)
|
continue
|
||||||
|
# It is 32 bytes encoded as 64 hex characters
|
||||||
|
if len(privEncryptionKey) == 64:
|
||||||
|
myECCryptorObjects[hashobj] = \
|
||||||
|
highlevelcrypto.makeCryptor(privEncryptionKey)
|
||||||
|
myAddressesByHash[hashobj] = addressInKeysFile
|
||||||
|
tag = highlevelcrypto.double_sha512(
|
||||||
|
encodeVarint(addressVersionNumber)
|
||||||
|
+ encodeVarint(streamNumber) + hashobj)[32:]
|
||||||
|
myAddressesByTag[tag] = addressInKeysFile
|
||||||
|
|
||||||
if not keyfileSecure:
|
if not keyfileSecure:
|
||||||
fixSensitiveFilePermissions(os.path.join(
|
fixSensitiveFilePermissions(os.path.join(
|
||||||
|
|
Reference in New Issue
Block a user