Skip to content

Refactor using of crypto functions #1796

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 8 additions & 23 deletions src/addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@
Operations with addresses
"""
# pylint: disable=inconsistent-return-statements
import hashlib

import logging
from binascii import hexlify, unhexlify
from struct import pack, unpack

try:
from highlevelcrypto import double_sha512
except ImportError:
from .highlevelcrypto import double_sha512


logger = logging.getLogger('default')

Expand Down Expand Up @@ -134,15 +139,6 @@ def decodeVarint(data):
return (encodedValue, 9)


def calculateInventoryHash(data):
"""Calculate inventory hash from object data"""
sha = hashlib.new('sha512')
sha2 = hashlib.new('sha512')
sha.update(data)
sha2.update(sha.digest())
return sha2.digest()[0:32]


def encodeAddress(version, stream, ripe):
"""Convert ripe to address"""
if version >= 2 and version < 4:
Expand All @@ -166,12 +162,7 @@ def encodeAddress(version, stream, ripe):
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe

# Generate the checksum
sha = hashlib.new('sha512')
sha.update(storedBinaryData)
currentHash = sha.digest()
sha = hashlib.new('sha512')
sha.update(currentHash)
checksum = sha.digest()[0:4]
checksum = double_sha512(storedBinaryData)[0:4]

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

sha = hashlib.new('sha512')
sha.update(data[:-4])
currentHash = sha.digest()
sha = hashlib.new('sha512')
sha.update(currentHash)

if checksum != sha.digest()[0:4]:
if checksum != double_sha512(data[:-4])[0:4]:
status = 'checksumfailed'
return status, 0, 0, ''

Expand Down
8 changes: 5 additions & 3 deletions src/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
from struct import pack

from six.moves import queue

import defaults
import helper_inbox
import helper_sent
Expand All @@ -82,17 +84,17 @@
import state
from addresses import (
addBMIfNotPresent,
calculateInventoryHash,
decodeAddress,
decodeVarint,
varintDecodeError
)
from bmconfigparser import BMConfigParser
from debug import logger
from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery, sqlStoredProcedure, sql_ready
from helper_sql import (
SqlBulkExecute, sqlExecute, sqlQuery, sql_ready, sqlStoredProcedure)
from highlevelcrypto import calculateInventoryHash
from inventory import Inventory
from network.threads import StoppableThread
from six.moves import queue
from version import softwareVersion

try: # TODO: write tests for XML vulnerabilities
Expand Down
78 changes: 25 additions & 53 deletions src/class_addressGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
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


Expand Down Expand Up @@ -129,17 +127,13 @@ def run(self):
# the \x00 or \x00\x00 bytes thus making the address shorter.
startTime = time.time()
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
potentialPrivSigningKey = OpenSSL.rand(32)
potentialPubSigningKey = highlevelcrypto.pointMult(
potentialPrivSigningKey)
privSigningKey, pubSigningKey = highlevelcrypto.random_keys()
while True:
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
potentialPrivEncryptionKey = OpenSSL.rand(32)
potentialPubEncryptionKey = highlevelcrypto.pointMult(
potentialPrivEncryptionKey)
potentialPrivEncryptionKey, potentialPubEncryptionKey = \
highlevelcrypto.random_keys()
sha = hashlib.new('sha512')
sha.update(
potentialPubSigningKey + potentialPubEncryptionKey)
sha.update(pubSigningKey + potentialPubEncryptionKey)
ripe = RIPEMD160Hash(sha.digest()).digest()
if (
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
Expand All @@ -163,20 +157,10 @@ def run(self):
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(
privSigningKey)
privEncryptionKeyWIF = highlevelcrypto.encodeWalletImportFormat(
potentialPrivEncryptionKey)

BMConfigParser().add_section(address)
BMConfigParser().set(address, 'label', label)
Expand Down Expand Up @@ -246,18 +230,15 @@ def run(self):
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
while True:
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
potentialPrivSigningKey = hashlib.sha512(
deterministicPassphrase
+ encodeVarint(signingKeyNonce)
).digest()[:32]
potentialPrivEncryptionKey = hashlib.sha512(
deterministicPassphrase
+ encodeVarint(encryptionKeyNonce)
).digest()[:32]
potentialPubSigningKey = highlevelcrypto.pointMult(
potentialPrivSigningKey)
potentialPubEncryptionKey = highlevelcrypto.pointMult(
potentialPrivEncryptionKey)
potentialPrivSigningKey, potentialPubSigningKey = \
highlevelcrypto.deterministic_keys(
deterministicPassphrase,
encodeVarint(signingKeyNonce))
potentialPrivEncryptionKey, potentialPubEncryptionKey = \
highlevelcrypto.deterministic_keys(
deterministicPassphrase,
encodeVarint(encryptionKeyNonce))

signingKeyNonce += 2
encryptionKeyNonce += 2
sha = hashlib.new('sha512')
Expand Down Expand Up @@ -300,21 +281,12 @@ def run(self):
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)
Expand Down Expand Up @@ -367,10 +339,10 @@ def run(self):
highlevelcrypto.makeCryptor(
hexlify(potentialPrivEncryptionKey))
shared.myAddressesByHash[ripe] = address
tag = hashlib.sha512(hashlib.sha512(
tag = highlevelcrypto.double_sha512(
encodeVarint(addressVersionNumber)
+ encodeVarint(streamNumber) + ripe
).digest()).digest()[32:]
)[32:]
shared.myAddressesByTag[tag] = address
if addressVersionNumber == 3:
# If this is a chan address,
Expand Down
20 changes: 9 additions & 11 deletions src/class_objectProcessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import shared
import state
from addresses import (
calculateInventoryHash, decodeAddress, decodeVarint,
decodeAddress, decodeVarint,
encodeAddress, encodeVarint, varintDecodeError
)
from bmconfigparser import BMConfigParser
Expand Down Expand Up @@ -450,7 +450,7 @@ def processmsg(self, data):
streamNumberAsClaimedByMsg, streamNumberAsClaimedByMsgLength = \
decodeVarint(data[readPosition:readPosition + 9])
readPosition += streamNumberAsClaimedByMsgLength
inventoryHash = calculateInventoryHash(data)
inventoryHash = highlevelcrypto.calculateInventoryHash(data)
initialDecryptionSuccessful = False

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

# calculate the fromRipe.
sha = hashlib.new('sha512')
Expand Down Expand Up @@ -751,7 +750,7 @@ def processbroadcast(self, data):
state.numberOfBroadcastsProcessed += 1
queues.UISignalQueue.put((
'updateNumberOfBroadcastsProcessed', 'no data'))
inventoryHash = calculateInventoryHash(data)
inventoryHash = highlevelcrypto.calculateInventoryHash(data)
readPosition = 20 # bypass the nonce, time, and object type
broadcastVersion, broadcastVersionLength = decodeVarint(
data[readPosition:readPosition + 9])
Expand Down Expand Up @@ -885,10 +884,10 @@ def processbroadcast(self, data):
' itself. Ignoring message.'
)
elif broadcastVersion == 5:
calculatedTag = hashlib.sha512(hashlib.sha512(
calculatedTag = highlevelcrypto.double_sha512(
encodeVarint(sendersAddressVersion)
+ encodeVarint(sendersStream) + calculatedRipe
).digest()).digest()[32:]
)[32:]
if calculatedTag != embeddedTag:
return logger.debug(
'The tag and encryption key used to encrypt this'
Expand Down Expand Up @@ -918,8 +917,7 @@ def processbroadcast(self, data):
return
logger.debug('ECDSA verify passed')
# Used to detect and ignore duplicate messages in our inbox
sigHash = hashlib.sha512(
hashlib.sha512(signature).digest()).digest()[32:]
sigHash = highlevelcrypto.double_sha512(signature)[32:]

fromAddress = encodeAddress(
sendersAddressVersion, sendersStream, calculatedRipe)
Expand Down Expand Up @@ -993,10 +991,10 @@ def possibleNewPubkey(self, address):
# Let us create the tag from the address and see if we were waiting
# for it.
elif addressVersion >= 4:
tag = hashlib.sha512(hashlib.sha512(
tag = highlevelcrypto.double_sha512(
encodeVarint(addressVersion) + encodeVarint(streamNumber)
+ ripe
).digest()).digest()[32:]
)[32:]
if tag in state.neededPubkeys:
del state.neededPubkeys[tag]
self.sendMessages(address)
Expand Down
Loading