Added pycrypto fallback for RIPEMD160 hash function
This commit is contained in:
parent
4eec124225
commit
e163137893
|
@ -1,2 +1,3 @@
|
|||
python_prctl
|
||||
psutil
|
||||
pycrypto
|
||||
|
|
|
@ -15,6 +15,7 @@ import highlevelcrypto
|
|||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from addresses import decodeAddress, encodeAddress, encodeVarint
|
||||
from fallback import RIPEMD160Hash
|
||||
from helper_threading import StoppableThread
|
||||
|
||||
|
||||
|
@ -133,16 +134,17 @@ class addressGenerator(threading.Thread, StoppableThread):
|
|||
potentialPrivEncryptionKey = OpenSSL.rand(32)
|
||||
potentialPubEncryptionKey = highlevelcrypto.pointMult(
|
||||
potentialPrivEncryptionKey)
|
||||
ripe = hashlib.new('ripemd160')
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(
|
||||
potentialPubSigningKey + potentialPubEncryptionKey)
|
||||
ripe.update(sha.digest())
|
||||
if ripe.digest()[:numberOfNullBytesDemandedOnFrontOfRipeHash] == '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash:
|
||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
||||
if (
|
||||
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash] ==
|
||||
'\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
|
||||
):
|
||||
break
|
||||
logger.info(
|
||||
'Generated address with ripe digest: %s',
|
||||
hexlify(ripe.digest()))
|
||||
'Generated address with ripe digest: %s', hexlify(ripe))
|
||||
try:
|
||||
logger.info(
|
||||
'Address generator calculated %s addresses at %s'
|
||||
|
@ -156,7 +158,7 @@ class addressGenerator(threading.Thread, StoppableThread):
|
|||
# time.time() - startTime equaled zero.
|
||||
pass
|
||||
address = encodeAddress(
|
||||
addressVersionNumber, streamNumber, ripe.digest())
|
||||
addressVersionNumber, streamNumber, ripe)
|
||||
|
||||
# An excellent way for us to store our keys
|
||||
# is in Wallet Import Format. Let us convert now.
|
||||
|
@ -203,7 +205,7 @@ class addressGenerator(threading.Thread, StoppableThread):
|
|||
shared.reloadMyAddressHashes()
|
||||
if addressVersionNumber == 3:
|
||||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV3Pubkey', ripe.digest()))
|
||||
'sendOutOrStoreMyV3Pubkey', ripe))
|
||||
elif addressVersionNumber == 4:
|
||||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV4Pubkey', address))
|
||||
|
@ -255,17 +257,18 @@ class addressGenerator(threading.Thread, StoppableThread):
|
|||
potentialPrivEncryptionKey)
|
||||
signingKeyNonce += 2
|
||||
encryptionKeyNonce += 2
|
||||
ripe = hashlib.new('ripemd160')
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(
|
||||
potentialPubSigningKey + potentialPubEncryptionKey)
|
||||
ripe.update(sha.digest())
|
||||
if ripe.digest()[:numberOfNullBytesDemandedOnFrontOfRipeHash] == '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash:
|
||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
||||
if (
|
||||
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash] ==
|
||||
'\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
|
||||
):
|
||||
break
|
||||
|
||||
logger.info(
|
||||
'Generated address with ripe digest: %s',
|
||||
hexlify(ripe.digest()))
|
||||
'Generated address with ripe digest: %s', hexlify(ripe))
|
||||
try:
|
||||
logger.info(
|
||||
'Address generator calculated %s addresses'
|
||||
|
@ -280,7 +283,7 @@ class addressGenerator(threading.Thread, StoppableThread):
|
|||
# time.time() - startTime equaled zero.
|
||||
pass
|
||||
address = encodeAddress(
|
||||
addressVersionNumber, streamNumber, ripe.digest())
|
||||
addressVersionNumber, streamNumber, ripe)
|
||||
|
||||
saveAddressToDisk = True
|
||||
# If we are joining an existing chan, let us check
|
||||
|
@ -357,13 +360,13 @@ class addressGenerator(threading.Thread, StoppableThread):
|
|||
))
|
||||
listOfNewAddressesToSendOutThroughTheAPI.append(
|
||||
address)
|
||||
shared.myECCryptorObjects[ripe.digest()] = \
|
||||
shared.myECCryptorObjects[ripe] = \
|
||||
highlevelcrypto.makeCryptor(
|
||||
hexlify(potentialPrivEncryptionKey))
|
||||
shared.myAddressesByHash[ripe.digest()] = address
|
||||
shared.myAddressesByHash[ripe] = address
|
||||
tag = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(addressVersionNumber) +
|
||||
encodeVarint(streamNumber) + ripe.digest()
|
||||
encodeVarint(streamNumber) + ripe
|
||||
).digest()).digest()[32:]
|
||||
shared.myAddressesByTag[tag] = address
|
||||
if addressVersionNumber == 3:
|
||||
|
@ -371,7 +374,7 @@ class addressGenerator(threading.Thread, StoppableThread):
|
|||
# the worker thread won't send out
|
||||
# the pubkey over the network.
|
||||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV3Pubkey', ripe.digest()))
|
||||
'sendOutOrStoreMyV3Pubkey', ripe))
|
||||
elif addressVersionNumber == 4:
|
||||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV4Pubkey', address))
|
||||
|
|
|
@ -24,6 +24,7 @@ import queues
|
|||
import state
|
||||
import tr
|
||||
from debug import logger
|
||||
from fallback import RIPEMD160Hash
|
||||
import l10n
|
||||
|
||||
|
||||
|
@ -288,9 +289,7 @@ class objectProcessor(threading.Thread):
|
|||
sha = hashlib.new('sha512')
|
||||
sha.update(
|
||||
'\x04' + publicSigningKey + '\x04' + publicEncryptionKey)
|
||||
ripeHasher = hashlib.new('ripemd160')
|
||||
ripeHasher.update(sha.digest())
|
||||
ripe = ripeHasher.digest()
|
||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
||||
|
||||
logger.debug(
|
||||
'within recpubkey, addressVersion: %s, streamNumber: %s'
|
||||
|
@ -354,9 +353,7 @@ class objectProcessor(threading.Thread):
|
|||
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(publicSigningKey + publicEncryptionKey)
|
||||
ripeHasher = hashlib.new('ripemd160')
|
||||
ripeHasher.update(sha.digest())
|
||||
ripe = ripeHasher.digest()
|
||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
||||
|
||||
logger.debug(
|
||||
'within recpubkey, addressVersion: %s, streamNumber: %s'
|
||||
|
@ -575,10 +572,9 @@ class objectProcessor(threading.Thread):
|
|||
# calculate the fromRipe.
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(pubSigningKey + pubEncryptionKey)
|
||||
ripe = hashlib.new('ripemd160')
|
||||
ripe.update(sha.digest())
|
||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
||||
fromAddress = encodeAddress(
|
||||
sendersAddressVersionNumber, sendersStreamNumber, ripe.digest())
|
||||
sendersAddressVersionNumber, sendersStreamNumber, ripe)
|
||||
|
||||
# Let's store the public key in case we want to reply to this
|
||||
# person.
|
||||
|
@ -897,9 +893,7 @@ class objectProcessor(threading.Thread):
|
|||
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(sendersPubSigningKey + sendersPubEncryptionKey)
|
||||
ripeHasher = hashlib.new('ripemd160')
|
||||
ripeHasher.update(sha.digest())
|
||||
calculatedRipe = ripeHasher.digest()
|
||||
calculatedRipe = RIPEMD160Hash(sha.digest()).digest()
|
||||
|
||||
if broadcastVersion == 4:
|
||||
if toRipe != calculatedRipe:
|
||||
|
|
|
@ -162,37 +162,13 @@ def try_import(module, log_extra=False):
|
|||
return False
|
||||
|
||||
|
||||
# We need to check hashlib for RIPEMD-160, as it won't be available
|
||||
# if OpenSSL is not linked against or the linked OpenSSL has RIPEMD
|
||||
# disabled.
|
||||
def check_hashlib():
|
||||
"""Do hashlib check.
|
||||
|
||||
The hashlib module check with version as if it included or not
|
||||
in The Python Standard library, it's a module containing an
|
||||
interface to the most popular hashing algorithms. hashlib
|
||||
implements some of the algorithms, however if OpenSSL
|
||||
installed, hashlib is able to use this algorithms as well.
|
||||
"""
|
||||
if sys.hexversion < 0x020500F0:
|
||||
logger.error(
|
||||
'The hashlib module is not included in this version of Python.')
|
||||
return False
|
||||
import hashlib
|
||||
if '_hashlib' not in hashlib.__dict__:
|
||||
logger.error(
|
||||
'The RIPEMD-160 hash algorithm is not available.'
|
||||
' The hashlib module is not linked against OpenSSL.')
|
||||
return False
|
||||
def check_ripemd160():
|
||||
"""Check availability of the RIPEMD160 hash function"""
|
||||
try:
|
||||
hashlib.new('ripemd160')
|
||||
except ValueError:
|
||||
logger.error(
|
||||
'The RIPEMD-160 hash algorithm is not available.'
|
||||
' The hashlib module utilizes an OpenSSL library with'
|
||||
' RIPEMD disabled.')
|
||||
from fallback import RIPEMD160Hash
|
||||
except ImportError:
|
||||
return False
|
||||
return True
|
||||
return RIPEMD160Hash is not None
|
||||
|
||||
|
||||
def check_sqlite():
|
||||
|
@ -446,7 +422,7 @@ def check_dependencies(verbose=False, optional=False):
|
|||
' or greater is required.')
|
||||
has_all_dependencies = False
|
||||
|
||||
check_functions = [check_hashlib, check_sqlite, check_openssl]
|
||||
check_functions = [check_ripemd160, check_sqlite, check_openssl]
|
||||
if optional:
|
||||
check_functions.extend([check_msgpack, check_pyqt, check_curses])
|
||||
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
"""
|
||||
.. todo:: hello world
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
|
||||
# We need to check hashlib for RIPEMD-160, as it won't be available
|
||||
# if OpenSSL is not linked against or the linked OpenSSL has RIPEMD
|
||||
# disabled.
|
||||
|
||||
try:
|
||||
hashlib.new('ripemd160')
|
||||
except ValueError:
|
||||
try:
|
||||
from Crypto.Hash import RIPEMD
|
||||
except ImportError:
|
||||
RIPEMD160Hash = None
|
||||
else:
|
||||
RIPEMD160Hash = RIPEMD.RIPEMD160Hash
|
||||
else:
|
||||
def RIPEMD160Hash(data=None):
|
||||
"""hashlib based RIPEMD160Hash"""
|
||||
hasher = hashlib.new('ripemd160')
|
||||
if data:
|
||||
hasher.update(data)
|
||||
return hasher
|
||||
|
|
|
@ -25,6 +25,7 @@ from addresses import (
|
|||
encodeVarint, decodeVarint, decodeAddress, varintDecodeError)
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from fallback import RIPEMD160Hash
|
||||
from helper_sql import sqlExecute
|
||||
from version import softwareVersion
|
||||
|
||||
|
@ -411,9 +412,7 @@ def decryptAndCheckPubkeyPayload(data, address):
|
|||
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(publicSigningKey + publicEncryptionKey)
|
||||
ripeHasher = hashlib.new('ripemd160')
|
||||
ripeHasher.update(sha.digest())
|
||||
embeddedRipe = ripeHasher.digest()
|
||||
embeddedRipe = RIPEMD160Hash(sha.digest()).digest()
|
||||
|
||||
if embeddedRipe != ripe:
|
||||
# Although this pubkey object had the tag were were looking for
|
||||
|
|
60
src/tests/test_crypto.py
Normal file
60
src/tests/test_crypto.py
Normal file
|
@ -0,0 +1,60 @@
|
|||
"""
|
||||
Test the alternatives for crypto primitives
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import unittest
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
try:
|
||||
from Crypto.Hash import RIPEMD
|
||||
except ImportError:
|
||||
RIPEMD = None
|
||||
|
||||
|
||||
# These keys are from addresses test script
|
||||
sample_pubsigningkey = unhexlify(
|
||||
'044a367f049ec16cb6b6118eb734a9962d10b8db59c890cd08f210c43ff08bdf09d'
|
||||
'16f502ca26cd0713f38988a1237f1fc8fa07b15653c996dc4013af6d15505ce')
|
||||
sample_pubencryptionkey = unhexlify(
|
||||
'044597d59177fc1d89555d38915f581b5ff2286b39d022ca0283d2bdd5c36be5d3c'
|
||||
'e7b9b97792327851a562752e4b79475d1f51f5a71352482b241227f45ed36a9')
|
||||
|
||||
sample_ripe = '003cd097eb7f35c87b5dc8b4538c22cb55312a9f'
|
||||
|
||||
_sha = hashlib.new('sha512')
|
||||
_sha.update(sample_pubsigningkey + sample_pubencryptionkey)
|
||||
|
||||
pubkey_sha = _sha.digest()
|
||||
|
||||
|
||||
class RIPEMD160TestCase(object):
|
||||
"""Base class for RIPEMD160 test case"""
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@abstractmethod
|
||||
def _hashdigest(self, data):
|
||||
"""RIPEMD160 digest implementation"""
|
||||
pass
|
||||
|
||||
def test_hash_string(self):
|
||||
"""Check RIPEMD160 hash function on string"""
|
||||
self.assertEqual(hexlify(self._hashdigest(pubkey_sha)), sample_ripe)
|
||||
|
||||
|
||||
class TestHashlib(RIPEMD160TestCase, unittest.TestCase):
|
||||
"""RIPEMD160 test case for hashlib"""
|
||||
@staticmethod
|
||||
def _hashdigest(data):
|
||||
hasher = hashlib.new('ripemd160')
|
||||
hasher.update(data)
|
||||
return hasher.digest()
|
||||
|
||||
|
||||
@unittest.skipUnless(RIPEMD, 'pycrypto package not found')
|
||||
class TestCrypto(RIPEMD160TestCase, unittest.TestCase):
|
||||
"""RIPEMD160 test case for Crypto"""
|
||||
@staticmethod
|
||||
def _hashdigest(data):
|
||||
return RIPEMD.RIPEMD160Hash(data).digest()
|
Reference in New Issue
Block a user