Skip to content

Commit c1ca704

Browse files
g1itchLee Miller
authored andcommitted
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.
1 parent 17a09a6 commit c1ca704

4 files changed

Lines changed: 107 additions & 118 deletions

File tree

src/class_addressGenerator.py

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from bmconfigparser import config
1717
from fallback import RIPEMD160Hash
1818
from network import StoppableThread
19-
from pyelliptic import arithmetic
2019
from pyelliptic.openssl import OpenSSL
2120
from tr import _translate
2221

@@ -164,20 +163,10 @@ def run(self):
164163
address = encodeAddress(
165164
addressVersionNumber, streamNumber, ripe)
166165

167-
# An excellent way for us to store our keys
168-
# is in Wallet Import Format. Let us convert now.
169-
# https://en.bitcoin.it/wiki/Wallet_import_format
170-
privSigningKey = b'\x80' + potentialPrivSigningKey
171-
checksum = hashlib.sha256(hashlib.sha256(
172-
privSigningKey).digest()).digest()[0:4]
173-
privSigningKeyWIF = arithmetic.changebase(
174-
privSigningKey + checksum, 256, 58)
175-
176-
privEncryptionKey = b'\x80' + potentialPrivEncryptionKey
177-
checksum = hashlib.sha256(hashlib.sha256(
178-
privEncryptionKey).digest()).digest()[0:4]
179-
privEncryptionKeyWIF = arithmetic.changebase(
180-
privEncryptionKey + checksum, 256, 58)
166+
privSigningKeyWIF = highlevelcrypto.encodeWalletImportFormat(
167+
potentialPrivSigningKey)
168+
privEncryptionKeyWIF = highlevelcrypto.encodeWalletImportFormat(
169+
potentialPrivEncryptionKey)
181170

182171
config.add_section(address)
183172
config.set(address, 'label', label)
@@ -303,21 +292,12 @@ def run(self):
303292
saveAddressToDisk = False
304293

305294
if saveAddressToDisk and live:
306-
# An excellent way for us to store our keys is
307-
# in Wallet Import Format. Let us convert now.
308-
# https://en.bitcoin.it/wiki/Wallet_import_format
309-
privSigningKey = b'\x80' + potentialPrivSigningKey
310-
checksum = hashlib.sha256(hashlib.sha256(
311-
privSigningKey).digest()).digest()[0:4]
312-
privSigningKeyWIF = arithmetic.changebase(
313-
privSigningKey + checksum, 256, 58)
314-
315-
privEncryptionKey = b'\x80' + \
316-
potentialPrivEncryptionKey
317-
checksum = hashlib.sha256(hashlib.sha256(
318-
privEncryptionKey).digest()).digest()[0:4]
319-
privEncryptionKeyWIF = arithmetic.changebase(
320-
privEncryptionKey + checksum, 256, 58)
295+
privSigningKeyWIF = \
296+
highlevelcrypto.encodeWalletImportFormat(
297+
potentialPrivSigningKey)
298+
privEncryptionKeyWIF = \
299+
highlevelcrypto.encodeWalletImportFormat(
300+
potentialPrivEncryptionKey)
321301

322302
try:
323303
config.add_section(address)

src/class_singleWorker.py

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,18 @@ def run(self):
197197
self.logger.info("Quitting...")
198198

199199
def _getKeysForAddress(self, address):
200-
privSigningKeyBase58 = config.get(
201-
address, 'privsigningkey')
202-
privEncryptionKeyBase58 = config.get(
203-
address, 'privencryptionkey')
200+
try:
201+
privSigningKeyBase58 = config.get(address, 'privsigningkey')
202+
privEncryptionKeyBase58 = config.get(address, 'privencryptionkey')
203+
except (configparser.NoSectionError, configparser.NoOptionError):
204+
self.logger.error(
205+
'Could not read or decode privkey for address %s', address)
206+
raise ValueError
204207

205-
privSigningKeyHex = hexlify(shared.decodeWalletImportFormat(
206-
privSigningKeyBase58))
207-
privEncryptionKeyHex = hexlify(shared.decodeWalletImportFormat(
208-
privEncryptionKeyBase58))
208+
privSigningKeyHex = hexlify(
209+
highlevelcrypto.decodeWalletImportFormat(privSigningKeyBase58))
210+
privEncryptionKeyHex = hexlify(
211+
highlevelcrypto.decodeWalletImportFormat(privEncryptionKeyBase58))
209212

210213
# The \x04 on the beginning of the public keys are not sent.
211214
# This way there is only one acceptable way to encode
@@ -256,9 +259,7 @@ def doPOWForMyV2Pubkey(self, adressHash):
256259
message once it is done with the POW"""
257260
# Look up my stream number based on my address hash
258261
myAddress = shared.myAddressesByHash[adressHash]
259-
# status
260-
_, addressVersionNumber, streamNumber, adressHash = (
261-
decodeAddress(myAddress))
262+
addressVersionNumber, streamNumber = decodeAddress(myAddress)[1:3]
262263

263264
# 28 days from now plus or minus five minutes
264265
TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300))
@@ -271,17 +272,15 @@ def doPOWForMyV2Pubkey(self, adressHash):
271272
payload += protocol.getBitfield(myAddress)
272273

273274
try:
274-
# privSigningKeyHex, privEncryptionKeyHex
275-
_, _, pubSigningKey, pubEncryptionKey = \
276-
self._getKeysForAddress(myAddress)
277-
except (configparser.NoSectionError, configparser.NoOptionError) as err:
278-
self.logger.warning("Section or Option did not found: %s", err)
279-
except Exception as err:
275+
pubSigningKey, pubEncryptionKey = self._getKeysForAddress(
276+
myAddress)[2:]
277+
except ValueError:
278+
return
279+
except Exception: # pylint:disable=broad-exception-caught
280280
self.logger.error(
281281
'Error within doPOWForMyV2Pubkey. Could not read'
282282
' the keys from the keys.dat file for a requested'
283-
' address. %s\n', err
284-
)
283+
' address. %s\n', exc_info=True)
285284
return
286285

287286
payload += pubSigningKey + pubEncryptionKey
@@ -320,8 +319,8 @@ def sendOutOrStoreMyV3Pubkey(self, adressHash):
320319
try:
321320
myAddress = shared.myAddressesByHash[adressHash]
322321
except KeyError:
323-
# The address has been deleted.
324-
self.logger.warning("Can't find %s in myAddressByHash", hexlify(adressHash))
322+
self.logger.warning( # The address has been deleted.
323+
"Can't find %s in myAddressByHash", hexlify(adressHash))
325324
return
326325
if config.safeGetBoolean(myAddress, 'chan'):
327326
self.logger.info('This is a chan address. Not sending pubkey.')
@@ -353,14 +352,13 @@ def sendOutOrStoreMyV3Pubkey(self, adressHash):
353352
# , privEncryptionKeyHex
354353
privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \
355354
self._getKeysForAddress(myAddress)
356-
except (configparser.NoSectionError, configparser.NoOptionError) as err:
357-
self.logger.warning("Section or Option did not found: %s", err)
358-
except Exception as err:
355+
except ValueError:
356+
return
357+
except Exception: # pylint:disable=broad-exception-caught
359358
self.logger.error(
360359
'Error within sendOutOrStoreMyV3Pubkey. Could not read'
361360
' the keys from the keys.dat file for a requested'
362-
' address. %s\n', err
363-
)
361+
' address. %s\n', exc_info=True)
364362
return
365363

366364
payload += pubSigningKey + pubEncryptionKey
@@ -428,14 +426,13 @@ def sendOutOrStoreMyV4Pubkey(self, myAddress):
428426
# , privEncryptionKeyHex
429427
privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \
430428
self._getKeysForAddress(myAddress)
431-
except (configparser.NoSectionError, configparser.NoOptionError) as err:
432-
self.logger.warning("Section or Option did not found: %s", err)
433-
except Exception as err:
429+
except ValueError:
430+
return
431+
except Exception: # pylint:disable=broad-exception-caught
434432
self.logger.error(
435433
'Error within sendOutOrStoreMyV4Pubkey. Could not read'
436434
' the keys from the keys.dat file for a requested'
437-
' address. %s\n', err
438-
)
435+
' address. %s\n', exc_info=True)
439436
return
440437

441438
dataToEncrypt += pubSigningKey + pubEncryptionKey
@@ -1118,8 +1115,9 @@ def sendMsg(self):
11181115
' from the keys.dat file for our own address. %s\n',
11191116
err)
11201117
continue
1121-
privEncryptionKeyHex = hexlify(shared.decodeWalletImportFormat(
1122-
privEncryptionKeyBase58))
1118+
privEncryptionKeyHex = hexlify(
1119+
highlevelcrypto.decodeWalletImportFormat(
1120+
privEncryptionKeyBase58))
11231121
pubEncryptionKeyBase256 = unhexlify(highlevelcrypto.privToPub(
11241122
privEncryptionKeyHex))[1:]
11251123
requiredAverageProofOfWorkNonceTrialsPerByte = \

src/highlevelcrypto.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,46 @@
77
`More discussion. <https://github.com/yann2192/pyelliptic/issues/32>`_
88
"""
99

10+
import hashlib
1011
from binascii import hexlify
1112

1213
import pyelliptic
1314
from pyelliptic import OpenSSL
1415
from pyelliptic import arithmetic as a
1516

1617

17-
__all__ = ['encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'sign', 'verify']
18+
__all__ = [
19+
'decodeWalletImportFormat', 'encodeWalletImportFormat',
20+
'encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'sign', 'verify']
21+
22+
23+
# WIF (uses arithmetic ):
24+
def decodeWalletImportFormat(WIFstring):
25+
"""
26+
Convert private key from base58 that's used in the config file to
27+
8-bit binary string.
28+
"""
29+
fullString = a.changebase(WIFstring, 58, 256)
30+
privkey = fullString[:-4]
31+
if fullString[-4:] != \
32+
hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]:
33+
raise ValueError('Checksum failed')
34+
elif privkey[0:1] == b'\x80': # checksum passed
35+
return privkey[1:]
36+
37+
raise ValueError('No hex 80 prefix')
38+
39+
40+
# An excellent way for us to store our keys
41+
# is in Wallet Import Format. Let us convert now.
42+
# https://en.bitcoin.it/wiki/Wallet_import_format
43+
def encodeWalletImportFormat(privKey):
44+
"""
45+
Convert private key from binary 8-bit string into base58check WIF string.
46+
"""
47+
privKey = b'\x80' + privKey
48+
checksum = hashlib.sha256(hashlib.sha256(privKey).digest()).digest()[0:4]
49+
return a.changebase(privKey + checksum, 256, 58)
1850

1951

2052
def makeCryptor(privkey, curve='secp256k1'):

src/shared.py

Lines changed: 33 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
from debug import logger
2424
from helper_sql import sqlQuery
2525

26-
from pyelliptic import arithmetic
27-
2826

2927
myECCryptorObjects = {}
3028
MyECSubscriptionCryptorObjects = {}
@@ -76,35 +74,6 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address):
7674
return False
7775

7876

79-
def decodeWalletImportFormat(WIFstring):
80-
# pylint: disable=inconsistent-return-statements
81-
"""
82-
Convert private key from base58 that's used in the config file to
83-
8-bit binary string
84-
"""
85-
fullString = arithmetic.changebase(WIFstring, 58, 256)
86-
privkey = fullString[:-4]
87-
if fullString[-4:] != \
88-
hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]:
89-
logger.critical(
90-
'Major problem! When trying to decode one of your'
91-
' private keys, the checksum failed. Here are the first'
92-
' 6 characters of the PRIVATE key: %s',
93-
str(WIFstring)[:6]
94-
)
95-
os._exit(0) # pylint: disable=protected-access
96-
# return ""
97-
elif privkey[0] == '\x80': # checksum passed
98-
return privkey[1:]
99-
100-
logger.critical(
101-
'Major problem! When trying to decode one of your private keys,'
102-
' the checksum passed but the key doesn\'t begin with hex 80.'
103-
' Here is the PRIVATE key: %s', WIFstring
104-
)
105-
os._exit(0) # pylint: disable=protected-access
106-
107-
10877
def reloadMyAddressHashes():
10978
"""Reload keys for user's addresses from the config file"""
11079
logger.debug('reloading keys from keys.dat file')
@@ -118,29 +87,39 @@ def reloadMyAddressHashes():
11887
hasEnabledKeys = False
11988
for addressInKeysFile in config.addresses():
12089
isEnabled = config.getboolean(addressInKeysFile, 'enabled')
121-
if isEnabled:
122-
hasEnabledKeys = True
123-
# status
124-
addressVersionNumber, streamNumber, hashobj = decodeAddress(addressInKeysFile)[1:]
125-
if addressVersionNumber in (2, 3, 4):
126-
# Returns a simple 32 bytes of information encoded
127-
# in 64 Hex characters, or null if there was an error.
128-
privEncryptionKey = hexlify(decodeWalletImportFormat(
129-
config.get(addressInKeysFile, 'privencryptionkey')))
130-
# It is 32 bytes encoded as 64 hex characters
131-
if len(privEncryptionKey) == 64:
132-
myECCryptorObjects[hashobj] = \
133-
highlevelcrypto.makeCryptor(privEncryptionKey)
134-
myAddressesByHash[hashobj] = addressInKeysFile
135-
tag = hashlib.sha512(hashlib.sha512(
136-
encodeVarint(addressVersionNumber)
137-
+ encodeVarint(streamNumber) + hashobj).digest()).digest()[32:]
138-
myAddressesByTag[tag] = addressInKeysFile
139-
else:
140-
logger.error(
141-
'Error in reloadMyAddressHashes: Can\'t handle'
142-
' address versions other than 2, 3, or 4.'
143-
)
90+
if not isEnabled:
91+
continue
92+
93+
hasEnabledKeys = True
94+
95+
addressVersionNumber, streamNumber, hashobj = decodeAddress(
96+
addressInKeysFile)[1:]
97+
if addressVersionNumber not in (2, 3, 4):
98+
logger.error(
99+
'Error in reloadMyAddressHashes: Can\'t handle'
100+
' address versions other than 2, 3, or 4.')
101+
continue
102+
103+
# Returns a simple 32 bytes of information encoded in 64 Hex characters
104+
try:
105+
privEncryptionKey = hexlify(
106+
highlevelcrypto.decodeWalletImportFormat(
107+
config.get(addressInKeysFile, 'privencryptionkey')
108+
))
109+
except ValueError:
110+
logger.error(
111+
'Error in reloadMyAddressHashes: failed to decode'
112+
' one of the private keys for address %s', addressInKeysFile)
113+
continue
114+
# It is 32 bytes encoded as 64 hex characters
115+
if len(privEncryptionKey) == 64:
116+
myECCryptorObjects[hashobj] = \
117+
highlevelcrypto.makeCryptor(privEncryptionKey)
118+
myAddressesByHash[hashobj] = addressInKeysFile
119+
tag = hashlib.sha512(hashlib.sha512(
120+
encodeVarint(addressVersionNumber)
121+
+ encodeVarint(streamNumber) + hashobj).digest()).digest()[32:]
122+
myAddressesByTag[tag] = addressInKeysFile
144123

145124
if not keyfileSecure:
146125
fixSensitiveFilePermissions(os.path.join(

0 commit comments

Comments
 (0)