Skip to content

Commit 3ed84a5

Browse files
g1itchLee Miller
authored andcommitted
Start adding hashes with double SHA512
1 parent 1b9773f commit 3ed84a5

File tree

12 files changed

+94
-104
lines changed

12 files changed

+94
-104
lines changed

src/addresses.py

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
Operations with addresses
33
"""
44
# pylint: disable=inconsistent-return-statements
5-
import hashlib
5+
66
import logging
77
from binascii import hexlify, unhexlify
88
from struct import pack, unpack
99

10+
try:
11+
from highlevelcrypto import double_sha512
12+
except ImportError:
13+
from .highlevelcrypto import double_sha512
14+
1015

1116
logger = logging.getLogger('default')
1217

@@ -134,15 +139,6 @@ def decodeVarint(data):
134139
return (encodedValue, 9)
135140

136141

137-
def calculateInventoryHash(data):
138-
"""Calculate inventory hash from object data"""
139-
sha = hashlib.new('sha512')
140-
sha2 = hashlib.new('sha512')
141-
sha.update(data)
142-
sha2.update(sha.digest())
143-
return sha2.digest()[0:32]
144-
145-
146142
def encodeAddress(version, stream, ripe):
147143
"""Convert ripe to address"""
148144
if version >= 2 and version < 4:
@@ -166,12 +162,7 @@ def encodeAddress(version, stream, ripe):
166162
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe
167163

168164
# Generate the checksum
169-
sha = hashlib.new('sha512')
170-
sha.update(storedBinaryData)
171-
currentHash = sha.digest()
172-
sha = hashlib.new('sha512')
173-
sha.update(currentHash)
174-
checksum = sha.digest()[0:4]
165+
checksum = double_sha512(storedBinaryData)[0:4]
175166

176167
# FIXME: encodeBase58 should take binary data, to reduce conversions
177168
# encodeBase58(storedBinaryData + checksum)
@@ -207,13 +198,7 @@ def decodeAddress(address):
207198
data = unhexlify(hexdata)
208199
checksum = data[-4:]
209200

210-
sha = hashlib.new('sha512')
211-
sha.update(data[:-4])
212-
currentHash = sha.digest()
213-
sha = hashlib.new('sha512')
214-
sha.update(currentHash)
215-
216-
if checksum != sha.digest()[0:4]:
201+
if checksum != double_sha512(data[:-4])[0:4]:
217202
status = 'checksumfailed'
218203
return status, 0, 0, ''
219204

src/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@
8383
import state
8484
from addresses import (
8585
addBMIfNotPresent,
86-
calculateInventoryHash,
8786
decodeAddress,
8887
decodeVarint,
8988
varintDecodeError
@@ -92,6 +91,7 @@
9291
from debug import logger
9392
from helper_sql import (
9493
SqlBulkExecute, sqlExecute, sqlQuery, sqlStoredProcedure, sql_ready)
94+
from highlevelcrypto import calculateInventoryHash
9595
from inventory import Inventory
9696

9797
try:

src/class_addressGenerator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,10 @@ def run(self):
349349
highlevelcrypto.makeCryptor(
350350
hexlify(potentialPrivEncryptionKey))
351351
shared.myAddressesByHash[ripe] = address
352-
tag = hashlib.sha512(hashlib.sha512(
352+
tag = highlevelcrypto.double_sha512(
353353
encodeVarint(addressVersionNumber)
354354
+ encodeVarint(streamNumber) + ripe
355-
).digest()).digest()[32:]
355+
)[32:]
356356
shared.myAddressesByTag[tag] = address
357357
if addressVersionNumber == 3:
358358
# If this is a chan address,

src/class_objectProcessor.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import shared
2525
import state
2626
from addresses import (
27-
calculateInventoryHash, decodeAddress, decodeVarint,
27+
decodeAddress, decodeVarint,
2828
encodeAddress, encodeVarint, varintDecodeError
2929
)
3030
from bmconfigparser import config
@@ -456,7 +456,7 @@ def processmsg(self, data):
456456
streamNumberAsClaimedByMsg, streamNumberAsClaimedByMsgLength = \
457457
decodeVarint(data[readPosition:readPosition + 9])
458458
readPosition += streamNumberAsClaimedByMsgLength
459-
inventoryHash = calculateInventoryHash(data)
459+
inventoryHash = highlevelcrypto.calculateInventoryHash(data)
460460
initialDecryptionSuccessful = False
461461

462462
# This is not an acknowledgement bound for me. See if it is a message
@@ -586,8 +586,7 @@ def processmsg(self, data):
586586
helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey)
587587
)
588588
# Used to detect and ignore duplicate messages in our inbox
589-
sigHash = hashlib.sha512(
590-
hashlib.sha512(signature).digest()).digest()[32:]
589+
sigHash = highlevelcrypto.double_sha512(signature)[32:]
591590

592591
# calculate the fromRipe.
593592
sha = hashlib.new('sha512')
@@ -736,7 +735,7 @@ def processmsg(self, data):
736735
ackPayload = ackData[24:]
737736
objectType, toStreamNumber, expiresTime = \
738737
protocol.decodeObjectParameters(ackPayload)
739-
inventoryHash = calculateInventoryHash(ackPayload)
738+
inventoryHash = highlevelcrypto.calculateInventoryHash(ackPayload)
740739
Inventory()[inventoryHash] = (
741740
objectType, toStreamNumber, ackPayload, expiresTime, b'')
742741
queues.invQueue.put((toStreamNumber, inventoryHash))
@@ -763,7 +762,7 @@ def processbroadcast(self, data):
763762
state.numberOfBroadcastsProcessed += 1
764763
queues.UISignalQueue.put((
765764
'updateNumberOfBroadcastsProcessed', 'no data'))
766-
inventoryHash = calculateInventoryHash(data)
765+
inventoryHash = highlevelcrypto.calculateInventoryHash(data)
767766
readPosition = 20 # bypass the nonce, time, and object type
768767
broadcastVersion, broadcastVersionLength = decodeVarint(
769768
data[readPosition:readPosition + 9])
@@ -897,10 +896,10 @@ def processbroadcast(self, data):
897896
' itself. Ignoring message.'
898897
)
899898
elif broadcastVersion == 5:
900-
calculatedTag = hashlib.sha512(hashlib.sha512(
899+
calculatedTag = highlevelcrypto.double_sha512(
901900
encodeVarint(sendersAddressVersion)
902901
+ encodeVarint(sendersStream) + calculatedRipe
903-
).digest()).digest()[32:]
902+
)[32:]
904903
if calculatedTag != embeddedTag:
905904
return logger.debug(
906905
'The tag and encryption key used to encrypt this'
@@ -930,8 +929,7 @@ def processbroadcast(self, data):
930929
return
931930
logger.debug('ECDSA verify passed')
932931
# Used to detect and ignore duplicate messages in our inbox
933-
sigHash = hashlib.sha512(
934-
hashlib.sha512(signature).digest()).digest()[32:]
932+
sigHash = highlevelcrypto.double_sha512(signature)[32:]
935933

936934
fromAddress = encodeAddress(
937935
sendersAddressVersion, sendersStream, calculatedRipe)
@@ -1005,10 +1003,10 @@ def possibleNewPubkey(self, address):
10051003
# Let us create the tag from the address and see if we were waiting
10061004
# for it.
10071005
elif addressVersion >= 4:
1008-
tag = hashlib.sha512(hashlib.sha512(
1006+
tag = highlevelcrypto.double_sha512(
10091007
encodeVarint(addressVersion) + encodeVarint(streamNumber)
10101008
+ ripe
1011-
).digest()).digest()[32:]
1009+
)[32:]
10121010
if tag in state.neededPubkeys:
10131011
del state.neededPubkeys[tag]
10141012
self.sendMessages(address)

src/class_singleWorker.py

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525
import shared
2626
import state
2727
import tr
28-
from addresses import (
29-
calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint
30-
)
28+
from addresses import decodeAddress, decodeVarint, encodeVarint
3129
from bmconfigparser import config
3230
from helper_sql import sqlExecute, sqlQuery
3331
from inventory import Inventory
@@ -75,18 +73,16 @@ def run(self):
7573
queryreturn = sqlQuery(
7674
'''SELECT DISTINCT toaddress FROM sent'''
7775
''' WHERE (status='awaitingpubkey' AND folder='sent')''')
78-
for row in queryreturn:
79-
toAddress, = row
80-
# toStatus
81-
_, toAddressVersionNumber, toStreamNumber, toRipe = \
82-
decodeAddress(toAddress)
76+
for toAddress, in queryreturn:
77+
toAddressVersionNumber, toStreamNumber, toRipe = \
78+
decodeAddress(toAddress)[1:]
8379
if toAddressVersionNumber <= 3:
8480
state.neededPubkeys[toAddress] = 0
8581
elif toAddressVersionNumber >= 4:
86-
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(
82+
doubleHashOfAddressData = highlevelcrypto.double_sha512(
8783
encodeVarint(toAddressVersionNumber)
8884
+ encodeVarint(toStreamNumber) + toRipe
89-
).digest()).digest()
85+
)
9086
# Note that this is the first half of the sha512 hash.
9187
privEncryptionKey = doubleHashOfAddressData[:32]
9288
tag = doubleHashOfAddressData[32:]
@@ -289,7 +285,7 @@ def doPOWForMyV2Pubkey(self, adressHash):
289285
payload = self._doPOWDefaults(
290286
payload, TTL, log_prefix='(For pubkey message)')
291287

292-
inventoryHash = calculateInventoryHash(payload)
288+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
293289
objectType = 1
294290
Inventory()[inventoryHash] = (
295291
objectType, streamNumber, payload, embeddedTime, '')
@@ -377,7 +373,7 @@ def sendOutOrStoreMyV3Pubkey(self, adressHash):
377373
payload = self._doPOWDefaults(
378374
payload, TTL, log_prefix='(For pubkey message)')
379375

380-
inventoryHash = calculateInventoryHash(payload)
376+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
381377
objectType = 1
382378
Inventory()[inventoryHash] = (
383379
objectType, streamNumber, payload, embeddedTime, '')
@@ -449,10 +445,10 @@ def sendOutOrStoreMyV4Pubkey(self, myAddress):
449445
# unencrypted, the pubkey with part of the hash so that nodes
450446
# know which pubkey object to try to decrypt
451447
# when they want to send a message.
452-
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(
448+
doubleHashOfAddressData = highlevelcrypto.double_sha512(
453449
encodeVarint(addressVersionNumber)
454450
+ encodeVarint(streamNumber) + addressHash
455-
).digest()).digest()
451+
)
456452
payload += doubleHashOfAddressData[32:] # the tag
457453
signature = highlevelcrypto.sign(
458454
payload + dataToEncrypt, privSigningKeyHex, self.digestAlg)
@@ -468,7 +464,7 @@ def sendOutOrStoreMyV4Pubkey(self, myAddress):
468464
payload = self._doPOWDefaults(
469465
payload, TTL, log_prefix='(For pubkey message)')
470466

471-
inventoryHash = calculateInventoryHash(payload)
467+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
472468
objectType = 1
473469
Inventory()[inventoryHash] = (
474470
objectType, streamNumber, payload, embeddedTime,
@@ -504,7 +500,7 @@ def sendOnionPeerObj(self, peer=None):
504500
objectType = protocol.OBJECT_ONIONPEER
505501
# FIXME: ideally the objectPayload should be signed
506502
objectPayload = encodeVarint(peer.port) + protocol.encodeHost(peer.host)
507-
tag = calculateInventoryHash(objectPayload)
503+
tag = highlevelcrypto.calculateInventoryHash(objectPayload)
508504

509505
if Inventory().by_type_and_tag(objectType, tag):
510506
return # not expired
@@ -518,7 +514,7 @@ def sendOnionPeerObj(self, peer=None):
518514
payload = self._doPOWDefaults(
519515
payload, TTL, log_prefix='(For onionpeer object)')
520516

521-
inventoryHash = calculateInventoryHash(payload)
517+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
522518
Inventory()[inventoryHash] = (
523519
objectType, streamNumber, buffer(payload), # noqa: F821
524520
embeddedTime, buffer(tag) # noqa: F821
@@ -612,10 +608,10 @@ def sendBroadcast(self):
612608

613609
payload += encodeVarint(streamNumber)
614610
if addressVersionNumber >= 4:
615-
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(
611+
doubleHashOfAddressData = highlevelcrypto.double_sha512(
616612
encodeVarint(addressVersionNumber)
617613
+ encodeVarint(streamNumber) + ripe
618-
).digest()).digest()
614+
)
619615
tag = doubleHashOfAddressData[32:]
620616
payload += tag
621617
else:
@@ -685,7 +681,7 @@ def sendBroadcast(self):
685681
)
686682
continue
687683

688-
inventoryHash = calculateInventoryHash(payload)
684+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
689685
objectType = 3
690686
Inventory()[inventoryHash] = (
691687
objectType, streamNumber, payload, embeddedTime, tag)
@@ -794,10 +790,10 @@ def sendMsg(self):
794790
if toAddressVersionNumber <= 3:
795791
toTag = ''
796792
else:
797-
toTag = hashlib.sha512(hashlib.sha512(
793+
toTag = highlevelcrypto.double_sha512(
798794
encodeVarint(toAddressVersionNumber)
799795
+ encodeVarint(toStreamNumber) + toRipe
800-
).digest()).digest()[32:]
796+
)[32:]
801797
if toaddress in state.neededPubkeys or \
802798
toTag in state.neededPubkeys:
803799
# We already sent a request for the pubkey
@@ -831,11 +827,11 @@ def sendMsg(self):
831827
# already contains the toAddress and cryptor
832828
# object associated with the tag for this toAddress.
833829
if toAddressVersionNumber >= 4:
834-
doubleHashOfToAddressData = hashlib.sha512(
835-
hashlib.sha512(
836-
encodeVarint(toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe
837-
).digest()
838-
).digest()
830+
doubleHashOfToAddressData = \
831+
highlevelcrypto.double_sha512(
832+
encodeVarint(toAddressVersionNumber)
833+
+ encodeVarint(toStreamNumber) + toRipe
834+
)
839835
# The first half of the sha512 hash.
840836
privEncryptionKey = doubleHashOfToAddressData[:32]
841837
# The second half of the sha512 hash.
@@ -1302,7 +1298,7 @@ def sendMsg(self):
13021298
)
13031299
continue
13041300

1305-
inventoryHash = calculateInventoryHash(encryptedPayload)
1301+
inventoryHash = highlevelcrypto.calculateInventoryHash(encryptedPayload)
13061302
objectType = 2
13071303
Inventory()[inventoryHash] = (
13081304
objectType, toStreamNumber, encryptedPayload, embeddedTime, '')
@@ -1352,8 +1348,7 @@ def sendMsg(self):
13521348
# the message in our own inbox.
13531349
if config.has_section(toaddress):
13541350
# Used to detect and ignore duplicate messages in our inbox
1355-
sigHash = hashlib.sha512(hashlib.sha512(
1356-
signature).digest()).digest()[32:]
1351+
sigHash = highlevelcrypto.double_sha512(signature)[32:]
13571352
t = (inventoryHash, toaddress, fromaddress, subject, int(
13581353
time.time()), message, 'inbox', encoding, 0, sigHash)
13591354
helper_inbox.insert(t)
@@ -1410,16 +1405,13 @@ def requestPubKey(self, toAddress):
14101405
# neededPubkeys dictionary. But if we are recovering
14111406
# from a restart of the client then we have to put it in now.
14121407

1413-
# Note that this is the first half of the sha512 hash.
1414-
privEncryptionKey = hashlib.sha512(hashlib.sha512(
1408+
doubleHashOfAddressData = highlevelcrypto.double_sha512(
14151409
encodeVarint(addressVersionNumber)
14161410
+ encodeVarint(streamNumber) + ripe
1417-
).digest()).digest()[:32]
1411+
)
1412+
privEncryptionKey = doubleHashOfAddressData[:32]
14181413
# Note that this is the second half of the sha512 hash.
1419-
tag = hashlib.sha512(hashlib.sha512(
1420-
encodeVarint(addressVersionNumber)
1421-
+ encodeVarint(streamNumber) + ripe
1422-
).digest()).digest()[32:]
1414+
tag = doubleHashOfAddressData[32:]
14231415
if tag not in state.neededPubkeys:
14241416
# We'll need this for when we receive a pubkey reply:
14251417
# it will be encrypted and we'll need to decrypt it.
@@ -1462,7 +1454,7 @@ def requestPubKey(self, toAddress):
14621454

14631455
payload = self._doPOWDefaults(payload, TTL)
14641456

1465-
inventoryHash = calculateInventoryHash(payload)
1457+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
14661458
objectType = 1
14671459
Inventory()[inventoryHash] = (
14681460
objectType, streamNumber, payload, embeddedTime, '')

src/highlevelcrypto.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
__all__ = [
2020
'decodeWalletImportFormat', 'encodeWalletImportFormat',
21+
'double_sha512', 'calculateInventoryHash',
2122
'encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'randomBytes',
2223
'sign', 'verify']
2324

@@ -61,6 +62,18 @@ def randomBytes(n):
6162
return OpenSSL.rand(n)
6263

6364

65+
# Hashes
66+
67+
def double_sha512(data):
68+
"""Binary double SHA512 digest"""
69+
return hashlib.sha512(hashlib.sha512(data).digest()).digest()
70+
71+
72+
def calculateInventoryHash(data):
73+
"""Calculate inventory hash from object data"""
74+
return double_sha512(data)[:32]
75+
76+
6477
def makeCryptor(privkey, curve='secp256k1'):
6578
"""Return a private `.pyelliptic.ECC` instance"""
6679
private_key = a.changebase(privkey, 16, 256, minlen=32)

0 commit comments

Comments
 (0)