Skip to content

Commit cf8c3ac

Browse files
committed
Start adding hashes with double SHA512
1 parent f9c8649 commit cf8c3ac

File tree

10 files changed

+102
-108
lines changed

10 files changed

+102
-108
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

@@ -132,15 +137,6 @@ def decodeVarint(data):
132137
return (encodedValue, 9)
133138

134139

135-
def calculateInventoryHash(data):
136-
"""Calculate inventory hash from object data"""
137-
sha = hashlib.new('sha512')
138-
sha2 = hashlib.new('sha512')
139-
sha.update(data)
140-
sha2.update(sha.digest())
141-
return sha2.digest()[0:32]
142-
143-
144140
def encodeAddress(version, stream, ripe):
145141
"""Convert ripe to address"""
146142
if version >= 2 and version < 4:
@@ -164,12 +160,7 @@ def encodeAddress(version, stream, ripe):
164160
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe
165161

166162
# Generate the checksum
167-
sha = hashlib.new('sha512')
168-
sha.update(storedBinaryData)
169-
currentHash = sha.digest()
170-
sha = hashlib.new('sha512')
171-
sha.update(currentHash)
172-
checksum = sha.digest()[0:4]
163+
checksum = double_sha512(storedBinaryData)[0:4]
173164

174165
# FIXME: encodeBase58 should take binary data, to reduce conversions
175166
# encodeBase58(storedBinaryData + checksum)
@@ -205,13 +196,7 @@ def decodeAddress(address):
205196
data = unhexlify(hexdata)
206197
checksum = data[-4:]
207198

208-
sha = hashlib.new('sha512')
209-
sha.update(data[:-4])
210-
currentHash = sha.digest()
211-
sha = hashlib.new('sha512')
212-
sha.update(currentHash)
213-
214-
if checksum != sha.digest()[0:4]:
199+
if checksum != double_sha512(data[:-4])[0:4]:
215200
status = 'checksumfailed'
216201
return status, 0, 0, ''
217202

src/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,14 @@
8282
import state
8383
from addresses import (
8484
addBMIfNotPresent,
85-
calculateInventoryHash,
8685
decodeAddress,
8786
decodeVarint,
8887
varintDecodeError
8988
)
9089
from bmconfigparser import BMConfigParser
9190
from debug import logger
9291
from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery, sqlStoredProcedure
92+
from highlevelcrypto import calculateInventoryHash
9393
from inventory import Inventory
9494
from network.threads import StoppableThread
9595
from version import softwareVersion

src/class_addressGenerator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,10 @@ def run(self):
367367
highlevelcrypto.makeCryptor(
368368
hexlify(potentialPrivEncryptionKey))
369369
shared.myAddressesByHash[ripe] = address
370-
tag = hashlib.sha512(hashlib.sha512(
370+
tag = highlevelcrypto.double_sha512(
371371
encodeVarint(addressVersionNumber)
372372
+ encodeVarint(streamNumber) + ripe
373-
).digest()).digest()[32:]
373+
)[32:]
374374
shared.myAddressesByTag[tag] = address
375375
if addressVersionNumber == 3:
376376
# If this is a chan address,

src/class_objectProcessor.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import shared
2424
import state
2525
from addresses import (
26-
calculateInventoryHash, decodeAddress, decodeVarint,
26+
decodeAddress, decodeVarint,
2727
encodeAddress, encodeVarint, varintDecodeError
2828
)
2929
from bmconfigparser import BMConfigParser
@@ -450,7 +450,7 @@ def processmsg(self, data):
450450
streamNumberAsClaimedByMsg, streamNumberAsClaimedByMsgLength = \
451451
decodeVarint(data[readPosition:readPosition + 9])
452452
readPosition += streamNumberAsClaimedByMsgLength
453-
inventoryHash = calculateInventoryHash(data)
453+
inventoryHash = highlevelcrypto.calculateInventoryHash(data)
454454
initialDecryptionSuccessful = False
455455

456456
# This is not an acknowledgement bound for me. See if it is a message
@@ -580,8 +580,7 @@ def processmsg(self, data):
580580
helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey)
581581
)
582582
# Used to detect and ignore duplicate messages in our inbox
583-
sigHash = hashlib.sha512(
584-
hashlib.sha512(signature).digest()).digest()[32:]
583+
sigHash = highlevelcrypto.double_sha512(signature)[32:]
585584

586585
# calculate the fromRipe.
587586
sha = hashlib.new('sha512')
@@ -751,7 +750,7 @@ def processbroadcast(self, data):
751750
state.numberOfBroadcastsProcessed += 1
752751
queues.UISignalQueue.put((
753752
'updateNumberOfBroadcastsProcessed', 'no data'))
754-
inventoryHash = calculateInventoryHash(data)
753+
inventoryHash = highlevelcrypto.calculateInventoryHash(data)
755754
readPosition = 20 # bypass the nonce, time, and object type
756755
broadcastVersion, broadcastVersionLength = decodeVarint(
757756
data[readPosition:readPosition + 9])
@@ -885,10 +884,10 @@ def processbroadcast(self, data):
885884
' itself. Ignoring message.'
886885
)
887886
elif broadcastVersion == 5:
888-
calculatedTag = hashlib.sha512(hashlib.sha512(
887+
calculatedTag = highlevelcrypto.double_sha512(
889888
encodeVarint(sendersAddressVersion)
890889
+ encodeVarint(sendersStream) + calculatedRipe
891-
).digest()).digest()[32:]
890+
)[32:]
892891
if calculatedTag != embeddedTag:
893892
return logger.debug(
894893
'The tag and encryption key used to encrypt this'
@@ -918,8 +917,7 @@ def processbroadcast(self, data):
918917
return
919918
logger.debug('ECDSA verify passed')
920919
# Used to detect and ignore duplicate messages in our inbox
921-
sigHash = hashlib.sha512(
922-
hashlib.sha512(signature).digest()).digest()[32:]
920+
sigHash = highlevelcrypto.double_sha512(signature)[32:]
923921

924922
fromAddress = encodeAddress(
925923
sendersAddressVersion, sendersStream, calculatedRipe)
@@ -993,10 +991,10 @@ def possibleNewPubkey(self, address):
993991
# Let us create the tag from the address and see if we were waiting
994992
# for it.
995993
elif addressVersion >= 4:
996-
tag = hashlib.sha512(hashlib.sha512(
994+
tag = highlevelcrypto.double_sha512(
997995
encodeVarint(addressVersion) + encodeVarint(streamNumber)
998996
+ ripe
999-
).digest()).digest()[32:]
997+
)[32:]
1000998
if tag in state.neededPubkeys:
1001999
del state.neededPubkeys[tag]
10021000
self.sendMessages(address)

src/class_singleWorker.py

Lines changed: 40 additions & 48 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 BMConfigParser
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(
87-
encodeVarint(toAddressVersionNumber) +
88-
encodeVarint(toStreamNumber) + toRipe
89-
).digest()).digest()
82+
doubleHashOfAddressData = highlevelcrypto.double_sha512(
83+
encodeVarint(toAddressVersionNumber)
84+
+ encodeVarint(toStreamNumber) + toRipe
85+
)
9086
# Note that this is the first half of the sha512 hash.
9187
privEncryptionKey = doubleHashOfAddressData[:32]
9288
tag = doubleHashOfAddressData[32:]
@@ -290,7 +286,7 @@ def doPOWForMyV2Pubkey(self, adressHash):
290286
payload = self._doPOWDefaults(
291287
payload, TTL, log_prefix='(For pubkey message)')
292288

293-
inventoryHash = calculateInventoryHash(payload)
289+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
294290
objectType = 1
295291
Inventory()[inventoryHash] = (
296292
objectType, streamNumber, payload, embeddedTime, '')
@@ -379,7 +375,7 @@ def sendOutOrStoreMyV3Pubkey(self, adressHash):
379375
payload = self._doPOWDefaults(
380376
payload, TTL, log_prefix='(For pubkey message)')
381377

382-
inventoryHash = calculateInventoryHash(payload)
378+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
383379
objectType = 1
384380
Inventory()[inventoryHash] = (
385381
objectType, streamNumber, payload, embeddedTime, '')
@@ -452,10 +448,10 @@ def sendOutOrStoreMyV4Pubkey(self, myAddress):
452448
# unencrypted, the pubkey with part of the hash so that nodes
453449
# know which pubkey object to try to decrypt
454450
# when they want to send a message.
455-
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(
456-
encodeVarint(addressVersionNumber) +
457-
encodeVarint(streamNumber) + addressHash
458-
).digest()).digest()
451+
doubleHashOfAddressData = highlevelcrypto.double_sha512(
452+
encodeVarint(addressVersionNumber)
453+
+ encodeVarint(streamNumber) + addressHash
454+
)
459455
payload += doubleHashOfAddressData[32:] # the tag
460456
signature = highlevelcrypto.sign(
461457
payload + dataToEncrypt, privSigningKeyHex, self.digestAlg)
@@ -471,7 +467,7 @@ def sendOutOrStoreMyV4Pubkey(self, myAddress):
471467
payload = self._doPOWDefaults(
472468
payload, TTL, log_prefix='(For pubkey message)')
473469

474-
inventoryHash = calculateInventoryHash(payload)
470+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
475471
objectType = 1
476472
Inventory()[inventoryHash] = (
477473
objectType, streamNumber, payload, embeddedTime,
@@ -507,7 +503,7 @@ def sendOnionPeerObj(self, peer=None):
507503
objectType = protocol.OBJECT_ONIONPEER
508504
# FIXME: ideally the objectPayload should be signed
509505
objectPayload = encodeVarint(peer.port) + protocol.encodeHost(peer.host)
510-
tag = calculateInventoryHash(objectPayload)
506+
tag = highlevelcrypto.calculateInventoryHash(objectPayload)
511507

512508
if Inventory().by_type_and_tag(objectType, tag):
513509
return # not expired
@@ -521,7 +517,7 @@ def sendOnionPeerObj(self, peer=None):
521517
payload = self._doPOWDefaults(
522518
payload, TTL, log_prefix='(For onionpeer object)')
523519

524-
inventoryHash = calculateInventoryHash(payload)
520+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
525521
Inventory()[inventoryHash] = (
526522
objectType, streamNumber, buffer(payload),
527523
embeddedTime, buffer(tag)
@@ -615,10 +611,10 @@ def sendBroadcast(self):
615611

616612
payload += encodeVarint(streamNumber)
617613
if addressVersionNumber >= 4:
618-
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(
619-
encodeVarint(addressVersionNumber) +
620-
encodeVarint(streamNumber) + ripe
621-
).digest()).digest()
614+
doubleHashOfAddressData = highlevelcrypto.double_sha512(
615+
encodeVarint(addressVersionNumber)
616+
+ encodeVarint(streamNumber) + ripe
617+
)
622618
tag = doubleHashOfAddressData[32:]
623619
payload += tag
624620
else:
@@ -688,7 +684,7 @@ def sendBroadcast(self):
688684
)
689685
continue
690686

691-
inventoryHash = calculateInventoryHash(payload)
687+
inventoryHash = highlevelcrypto.calculateInventoryHash(payload)
692688
objectType = 3
693689
Inventory()[inventoryHash] = (
694690
objectType, streamNumber, payload, embeddedTime, tag)
@@ -797,10 +793,10 @@ def sendMsg(self):
797793
if toAddressVersionNumber <= 3:
798794
toTag = ''
799795
else:
800-
toTag = hashlib.sha512(hashlib.sha512(
801-
encodeVarint(toAddressVersionNumber) +
802-
encodeVarint(toStreamNumber) + toRipe
803-
).digest()).digest()[32:]
796+
toTag = highlevelcrypto.double_sha512(
797+
encodeVarint(toAddressVersionNumber)
798+
+ encodeVarint(toStreamNumber) + toRipe
799+
)[32:]
804800
if toaddress in state.neededPubkeys or \
805801
toTag in state.neededPubkeys:
806802
# We already sent a request for the pubkey
@@ -834,11 +830,11 @@ def sendMsg(self):
834830
# already contains the toAddress and cryptor
835831
# object associated with the tag for this toAddress.
836832
if toAddressVersionNumber >= 4:
837-
doubleHashOfToAddressData = hashlib.sha512(
838-
hashlib.sha512(
839-
encodeVarint(toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe
840-
).digest()
841-
).digest()
833+
doubleHashOfToAddressData = \
834+
highlevelcrypto.double_sha512(
835+
encodeVarint(toAddressVersionNumber)
836+
+ encodeVarint(toStreamNumber) + toRipe
837+
)
842838
# The first half of the sha512 hash.
843839
privEncryptionKey = doubleHashOfToAddressData[:32]
844840
# The second half of the sha512 hash.
@@ -1304,7 +1300,7 @@ def sendMsg(self):
13041300
)
13051301
continue
13061302

1307-
inventoryHash = calculateInventoryHash(encryptedPayload)
1303+
inventoryHash = highlevelcrypto.calculateInventoryHash(encryptedPayload)
13081304
objectType = 2
13091305
Inventory()[inventoryHash] = (
13101306
objectType, toStreamNumber, encryptedPayload, embeddedTime, '')
@@ -1354,8 +1350,7 @@ def sendMsg(self):
13541350
# the message in our own inbox.
13551351
if BMConfigParser().has_section(toaddress):
13561352
# Used to detect and ignore duplicate messages in our inbox
1357-
sigHash = hashlib.sha512(hashlib.sha512(
1358-
signature).digest()).digest()[32:]
1353+
sigHash = highlevelcrypto.double_sha512(signature)[32:]
13591354
t = (inventoryHash, toaddress, fromaddress, subject, int(
13601355
time.time()), message, 'inbox', encoding, 0, sigHash)
13611356
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(
1415-
encodeVarint(addressVersionNumber) +
1416-
encodeVarint(streamNumber) + ripe
1417-
).digest()).digest()[:32]
1408+
doubleHashOfAddressData = highlevelcrypto.double_sha512(
1409+
encodeVarint(addressVersionNumber)
1410+
+ encodeVarint(streamNumber) + ripe
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
@@ -7,6 +7,7 @@
77
`More discussion. <https://github.com/yann2192/pyelliptic/issues/32>`_
88
"""
99

10+
import hashlib
1011
from binascii import hexlify
1112

1213
import pyelliptic
@@ -17,6 +18,18 @@
1718
__all__ = ['encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'sign', 'verify']
1819

1920

21+
# Hashes
22+
23+
def double_sha512(data):
24+
"""Binary double SHA512 digest"""
25+
return hashlib.sha512(hashlib.sha512(data).digest()).digest()
26+
27+
28+
def calculateInventoryHash(data):
29+
"""Calculate inventory hash from object data"""
30+
return double_sha512(data)[:32]
31+
32+
2033
def makeCryptor(privkey):
2134
"""Return a private `.pyelliptic.ECC` instance"""
2235
private_key = a.changebase(privkey, 16, 256, minlen=32)

0 commit comments

Comments
 (0)