Refactor using of crypto functions #1796

Closed
g1itch wants to merge 14 commits from crypto into v0.6
4 changed files with 108 additions and 125 deletions
Showing only changes of commit 8942f63d06 - Show all commits

View File

@ -15,7 +15,6 @@ from addresses import decodeAddress, encodeAddress, encodeVarint
from bmconfigparser import BMConfigParser
from fallback import RIPEMD160Hash
from network import StoppableThread
from pyelliptic import arithmetic
from pyelliptic.openssl import OpenSSL
from six.moves import configparser, queue
@ -163,20 +162,10 @@ class addressGenerator(StoppableThread):
address = encodeAddress(
addressVersionNumber, streamNumber, ripe)
# 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
privSigningKey = b'\x80' + potentialPrivSigningKey
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)
privSigningKeyWIF = highlevelcrypto.encodeWalletImportFormat(
potentialPrivSigningKey)
privEncryptionKeyWIF = highlevelcrypto.encodeWalletImportFormat(
potentialPrivEncryptionKey)
BMConfigParser().add_section(address)
BMConfigParser().set(address, 'label', label)
@ -300,21 +289,12 @@ class addressGenerator(StoppableThread):
saveAddressToDisk = False
if saveAddressToDisk and live:
# 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
privSigningKey = b'\x80' + potentialPrivSigningKey
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)
privSigningKeyWIF = \
highlevelcrypto.encodeWalletImportFormat(
potentialPrivSigningKey)
privEncryptionKeyWIF = \
highlevelcrypto.encodeWalletImportFormat(
potentialPrivEncryptionKey)
try:
BMConfigParser().add_section(address)

View File

@ -193,15 +193,20 @@ class singleWorker(StoppableThread):
self.logger.info("Quitting...")
def _getKeysForAddress(self, address):
try:
privSigningKeyBase58 = BMConfigParser().get(
address, 'privsigningkey')
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(
privSigningKeyBase58))
privEncryptionKeyHex = hexlify(shared.decodeWalletImportFormat(
privEncryptionKeyBase58))
privSigningKeyHex = hexlify(
highlevelcrypto.decodeWalletImportFormat(privSigningKeyBase58))
privEncryptionKeyHex = hexlify(
highlevelcrypto.decodeWalletImportFormat(privEncryptionKeyBase58))
# The \x04 on the beginning of the public keys are not sent.
# 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"""
# Look up my stream number based on my address hash
myAddress = shared.myAddressesByHash[adressHash]
# status
_, addressVersionNumber, streamNumber, adressHash = (
decodeAddress(myAddress))
addressVersionNumber, streamNumber = decodeAddress(myAddress)[1:3]
# 28 days from now plus or minus five minutes
TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300))
@ -267,18 +270,15 @@ class singleWorker(StoppableThread):
payload += protocol.getBitfield(myAddress)
try:
# privSigningKeyHex, privEncryptionKeyHex
_, _, pubSigningKey, pubEncryptionKey = \
self._getKeysForAddress(myAddress)
except (configparser.NoSectionError, configparser.NoOptionError) as err:
self.logger.warning("Section or Option did not found: %s", err)
except Exception as err:
self.logger.error(
pubSigningKey, pubEncryptionKey = self._getKeysForAddress(
myAddress)[2:]
except ValueError:
return
except Exception:
return self.logger.error(
'Error within doPOWForMyV2Pubkey. Could not read'
' the keys from the keys.dat file for a requested'
' address. %s\n', err
)
return
' address. %s\n', exc_info=True)
payload += pubSigningKey + pubEncryptionKey
@ -316,9 +316,8 @@ class singleWorker(StoppableThread):
try:
myAddress = shared.myAddressesByHash[adressHash]
except KeyError:
# The address has been deleted.
self.logger.warning("Can't find %s in myAddressByHash", hexlify(adressHash))
return
return self.logger.warning( # The address has been deleted.
"Can't find %s in myAddressByHash", hexlify(adressHash))
if BMConfigParser().safeGetBoolean(myAddress, 'chan'):
self.logger.info('This is a chan address. Not sending pubkey.')
return
@ -349,15 +348,13 @@ class singleWorker(StoppableThread):
# , privEncryptionKeyHex
privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \
self._getKeysForAddress(myAddress)
except (configparser.NoSectionError, configparser.NoOptionError) as err:
self.logger.warning("Section or Option did not found: %s", err)
except Exception as err:
self.logger.error(
except ValueError:
return
except Exception:
return self.logger.error(
'Error within sendOutOrStoreMyV3Pubkey. Could not read'
' the keys from the keys.dat file for a requested'
' address. %s\n', err
)
return
' address. %s\n', exc_info=True)
payload += pubSigningKey + pubEncryptionKey
@ -424,15 +421,13 @@ class singleWorker(StoppableThread):
# , privEncryptionKeyHex
privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \
self._getKeysForAddress(myAddress)
except (configparser.NoSectionError, configparser.NoOptionError) as err:
self.logger.warning("Section or Option did not found: %s", err)
except Exception as err:
self.logger.error(
except ValueError:
return
except Exception:
return self.logger.error(
'Error within sendOutOrStoreMyV4Pubkey. Could not read'
' the keys from the keys.dat file for a requested'
' address. %s\n', err
)
return
' address. %s\n', exc_info=True)
dataToEncrypt += pubSigningKey + pubEncryptionKey
@ -1114,7 +1109,8 @@ class singleWorker(StoppableThread):
' from the keys.dat file for our own address. %s\n',
err)
continue
privEncryptionKeyHex = hexlify(shared.decodeWalletImportFormat(
privEncryptionKeyHex = hexlify(
highlevelcrypto.decodeWalletImportFormat(
privEncryptionKeyBase58))
pubEncryptionKeyBase256 = unhexlify(highlevelcrypto.privToPub(
privEncryptionKeyHex))[1:]

View File

@ -30,6 +30,35 @@ def calculateInventoryHash(data):
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):
"""Return a private `.pyelliptic.ECC` instance"""
private_key = a.changebase(privkey, 16, 256, minlen=32)

View File

@ -23,8 +23,6 @@ from bmconfigparser import BMConfigParser
from debug import logger
from helper_sql import sqlQuery
from pyelliptic import arithmetic
myECCryptorObjects = {}
MyECSubscriptionCryptorObjects = {}
@ -76,35 +74,6 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address):
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():
"""Reload keys for user's addresses from the config file"""
logger.debug('reloading keys from keys.dat file')
@ -118,16 +87,30 @@ def reloadMyAddressHashes():
hasEnabledKeys = False
for addressInKeysFile in BMConfigParser().addresses():
isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled')
if isEnabled:
if not isEnabled:
continue
hasEnabledKeys = True
# status
addressVersionNumber, streamNumber, hashobj = decodeAddress(
addressInKeysFile)[1:]
if addressVersionNumber in (2, 3, 4):
# Returns a simple 32 bytes of information encoded
# in 64 Hex characters, or null if there was an error.
privEncryptionKey = hexlify(decodeWalletImportFormat(
BMConfigParser().get(addressInKeysFile, 'privencryptionkey')))
if addressVersionNumber not in (2, 3, 4):
logger.error(
'Error in reloadMyAddressHashes: Can\'t handle'
' address versions other than 2, 3, or 4.')
continue
# Returns a simple 32 bytes of information encoded in 64 Hex characters.
try:
privEncryptionKey = hexlify(
highlevelcrypto.decodeWalletImportFormat(
BMConfigParser().get(addressInKeysFile, 'privencryptionkey')
))
except ValueError:
logger.error(
'Error in reloadMyAddressHashes: failed to decode'
' 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] = \
@ -137,11 +120,6 @@ def reloadMyAddressHashes():
encodeVarint(addressVersionNumber)
+ encodeVarint(streamNumber) + hashobj)[32:]
myAddressesByTag[tag] = addressInKeysFile
else:
logger.error(
'Error in reloadMyAddressHashes: Can\'t handle'
' address versions other than 2, 3, or 4.'
)
if not keyfileSecure:
fixSensitiveFilePermissions(os.path.join(