Move RIPEMD160 hash to highlevelcrypto and export to_ripe() (closes: #1796)
This commit is contained in:
parent
41fd17b637
commit
3a04e351cc
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
A thread for creating addresses
|
A thread for creating addresses
|
||||||
"""
|
"""
|
||||||
import hashlib
|
|
||||||
import time
|
import time
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ import shared
|
||||||
import state
|
import state
|
||||||
from addresses import decodeAddress, encodeAddress, encodeVarint
|
from addresses import decodeAddress, encodeAddress, encodeVarint
|
||||||
from bmconfigparser import config
|
from bmconfigparser import config
|
||||||
from fallback import RIPEMD160Hash
|
|
||||||
from network import StoppableThread
|
from network import StoppableThread
|
||||||
from tr import _translate
|
from tr import _translate
|
||||||
|
|
||||||
|
@ -133,9 +132,8 @@ class addressGenerator(StoppableThread):
|
||||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
|
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
|
||||||
potentialPrivEncryptionKey, potentialPubEncryptionKey = \
|
potentialPrivEncryptionKey, potentialPubEncryptionKey = \
|
||||||
highlevelcrypto.random_keys()
|
highlevelcrypto.random_keys()
|
||||||
sha = hashlib.new('sha512')
|
ripe = highlevelcrypto.to_ripe(
|
||||||
sha.update(pubSigningKey + potentialPubEncryptionKey)
|
pubSigningKey, potentialPubEncryptionKey)
|
||||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
|
||||||
if (
|
if (
|
||||||
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
|
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
|
||||||
== b'\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
|
== b'\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
|
||||||
|
@ -244,10 +242,8 @@ class addressGenerator(StoppableThread):
|
||||||
|
|
||||||
signingKeyNonce += 2
|
signingKeyNonce += 2
|
||||||
encryptionKeyNonce += 2
|
encryptionKeyNonce += 2
|
||||||
sha = hashlib.new('sha512')
|
ripe = highlevelcrypto.to_ripe(
|
||||||
sha.update(
|
potentialPubSigningKey, potentialPubEncryptionKey)
|
||||||
potentialPubSigningKey + potentialPubEncryptionKey)
|
|
||||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
|
||||||
if (
|
if (
|
||||||
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
|
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
|
||||||
== b'\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
|
== b'\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
|
||||||
|
|
|
@ -28,7 +28,6 @@ from addresses import (
|
||||||
encodeAddress, encodeVarint, varintDecodeError
|
encodeAddress, encodeVarint, varintDecodeError
|
||||||
)
|
)
|
||||||
from bmconfigparser import config
|
from bmconfigparser import config
|
||||||
from fallback import RIPEMD160Hash
|
|
||||||
from helper_sql import (
|
from helper_sql import (
|
||||||
sql_ready, sql_timeout, SqlBulkExecute, sqlExecute, sqlQuery)
|
sql_ready, sql_timeout, SqlBulkExecute, sqlExecute, sqlQuery)
|
||||||
from network import knownnodes
|
from network import knownnodes
|
||||||
|
@ -300,23 +299,20 @@ class objectProcessor(threading.Thread):
|
||||||
'(within processpubkey) payloadLength less than 146.'
|
'(within processpubkey) payloadLength less than 146.'
|
||||||
' Sanity check failed.')
|
' Sanity check failed.')
|
||||||
readPosition += 4
|
readPosition += 4
|
||||||
publicSigningKey = data[readPosition:readPosition + 64]
|
pubSigningKey = '\x04' + data[readPosition:readPosition + 64]
|
||||||
# Is it possible for a public key to be invalid such that trying to
|
# Is it possible for a public key to be invalid such that trying to
|
||||||
# encrypt or sign with it will cause an error? If it is, it would
|
# encrypt or sign with it will cause an error? If it is, it would
|
||||||
# be easiest to test them here.
|
# be easiest to test them here.
|
||||||
readPosition += 64
|
readPosition += 64
|
||||||
publicEncryptionKey = data[readPosition:readPosition + 64]
|
pubEncryptionKey = '\x04' + data[readPosition:readPosition + 64]
|
||||||
if len(publicEncryptionKey) < 64:
|
if len(pubEncryptionKey) < 65:
|
||||||
return logger.debug(
|
return logger.debug(
|
||||||
'publicEncryptionKey length less than 64. Sanity check'
|
'publicEncryptionKey length less than 64. Sanity check'
|
||||||
' failed.')
|
' failed.')
|
||||||
readPosition += 64
|
readPosition += 64
|
||||||
# The data we'll store in the pubkeys table.
|
# The data we'll store in the pubkeys table.
|
||||||
dataToStore = data[20:readPosition]
|
dataToStore = data[20:readPosition]
|
||||||
sha = hashlib.new('sha512')
|
ripe = highlevelcrypto.to_ripe(pubSigningKey, pubEncryptionKey)
|
||||||
sha.update(
|
|
||||||
'\x04' + publicSigningKey + '\x04' + publicEncryptionKey)
|
|
||||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
|
||||||
|
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -324,7 +320,7 @@ class objectProcessor(threading.Thread):
|
||||||
'\nripe %s\npublicSigningKey in hex: %s'
|
'\nripe %s\npublicSigningKey in hex: %s'
|
||||||
'\npublicEncryptionKey in hex: %s',
|
'\npublicEncryptionKey in hex: %s',
|
||||||
addressVersion, streamNumber, hexlify(ripe),
|
addressVersion, streamNumber, hexlify(ripe),
|
||||||
hexlify(publicSigningKey), hexlify(publicEncryptionKey)
|
hexlify(pubSigningKey), hexlify(pubEncryptionKey)
|
||||||
)
|
)
|
||||||
|
|
||||||
address = encodeAddress(addressVersion, streamNumber, ripe)
|
address = encodeAddress(addressVersion, streamNumber, ripe)
|
||||||
|
@ -354,9 +350,9 @@ class objectProcessor(threading.Thread):
|
||||||
' Sanity check failed.')
|
' Sanity check failed.')
|
||||||
return
|
return
|
||||||
readPosition += 4
|
readPosition += 4
|
||||||
publicSigningKey = '\x04' + data[readPosition:readPosition + 64]
|
pubSigningKey = '\x04' + data[readPosition:readPosition + 64]
|
||||||
readPosition += 64
|
readPosition += 64
|
||||||
publicEncryptionKey = '\x04' + data[readPosition:readPosition + 64]
|
pubEncryptionKey = '\x04' + data[readPosition:readPosition + 64]
|
||||||
readPosition += 64
|
readPosition += 64
|
||||||
specifiedNonceTrialsPerByteLength = decodeVarint(
|
specifiedNonceTrialsPerByteLength = decodeVarint(
|
||||||
data[readPosition:readPosition + 10])[1]
|
data[readPosition:readPosition + 10])[1]
|
||||||
|
@ -373,15 +369,13 @@ class objectProcessor(threading.Thread):
|
||||||
signature = data[readPosition:readPosition + signatureLength]
|
signature = data[readPosition:readPosition + signatureLength]
|
||||||
if highlevelcrypto.verify(
|
if highlevelcrypto.verify(
|
||||||
data[8:endOfSignedDataPosition],
|
data[8:endOfSignedDataPosition],
|
||||||
signature, hexlify(publicSigningKey)):
|
signature, hexlify(pubSigningKey)):
|
||||||
logger.debug('ECDSA verify passed (within processpubkey)')
|
logger.debug('ECDSA verify passed (within processpubkey)')
|
||||||
else:
|
else:
|
||||||
logger.warning('ECDSA verify failed (within processpubkey)')
|
logger.warning('ECDSA verify failed (within processpubkey)')
|
||||||
return
|
return
|
||||||
|
|
||||||
sha = hashlib.new('sha512')
|
ripe = highlevelcrypto.to_ripe(pubSigningKey, pubEncryptionKey)
|
||||||
sha.update(publicSigningKey + publicEncryptionKey)
|
|
||||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
|
||||||
|
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -389,7 +383,7 @@ class objectProcessor(threading.Thread):
|
||||||
'\nripe %s\npublicSigningKey in hex: %s'
|
'\nripe %s\npublicSigningKey in hex: %s'
|
||||||
'\npublicEncryptionKey in hex: %s',
|
'\npublicEncryptionKey in hex: %s',
|
||||||
addressVersion, streamNumber, hexlify(ripe),
|
addressVersion, streamNumber, hexlify(ripe),
|
||||||
hexlify(publicSigningKey), hexlify(publicEncryptionKey)
|
hexlify(pubSigningKey), hexlify(pubEncryptionKey)
|
||||||
)
|
)
|
||||||
|
|
||||||
address = encodeAddress(addressVersion, streamNumber, ripe)
|
address = encodeAddress(addressVersion, streamNumber, ripe)
|
||||||
|
@ -588,9 +582,7 @@ class objectProcessor(threading.Thread):
|
||||||
sigHash = highlevelcrypto.double_sha512(signature)[32:]
|
sigHash = highlevelcrypto.double_sha512(signature)[32:]
|
||||||
|
|
||||||
# calculate the fromRipe.
|
# calculate the fromRipe.
|
||||||
sha = hashlib.new('sha512')
|
ripe = highlevelcrypto.to_ripe(pubSigningKey, pubEncryptionKey)
|
||||||
sha.update(pubSigningKey + pubEncryptionKey)
|
|
||||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
|
||||||
fromAddress = encodeAddress(
|
fromAddress = encodeAddress(
|
||||||
sendersAddressVersionNumber, sendersStreamNumber, ripe)
|
sendersAddressVersionNumber, sendersStreamNumber, ripe)
|
||||||
|
|
||||||
|
@ -883,9 +875,8 @@ class objectProcessor(threading.Thread):
|
||||||
requiredPayloadLengthExtraBytes)
|
requiredPayloadLengthExtraBytes)
|
||||||
endOfPubkeyPosition = readPosition
|
endOfPubkeyPosition = readPosition
|
||||||
|
|
||||||
sha = hashlib.new('sha512')
|
calculatedRipe = highlevelcrypto.to_ripe(
|
||||||
sha.update(sendersPubSigningKey + sendersPubEncryptionKey)
|
sendersPubSigningKey, sendersPubEncryptionKey)
|
||||||
calculatedRipe = RIPEMD160Hash(sha.digest()).digest()
|
|
||||||
|
|
||||||
if broadcastVersion == 4:
|
if broadcastVersion == 4:
|
||||||
if toRipe != calculatedRipe:
|
if toRipe != calculatedRipe:
|
||||||
|
|
|
@ -15,12 +15,13 @@ import pyelliptic
|
||||||
from pyelliptic import OpenSSL
|
from pyelliptic import OpenSSL
|
||||||
from pyelliptic import arithmetic as a
|
from pyelliptic import arithmetic as a
|
||||||
|
|
||||||
|
from fallback import RIPEMD160Hash
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'decodeWalletImportFormat', 'deterministic_keys',
|
'decodeWalletImportFormat', 'deterministic_keys',
|
||||||
'double_sha512', 'calculateInventoryHash', 'encodeWalletImportFormat',
|
'double_sha512', 'calculateInventoryHash', 'encodeWalletImportFormat',
|
||||||
'encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'randomBytes',
|
'encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'randomBytes',
|
||||||
'random_keys', 'sign', 'verify']
|
'random_keys', 'sign', 'to_ripe', 'verify']
|
||||||
|
|
||||||
|
|
||||||
# WIF (uses arithmetic ):
|
# WIF (uses arithmetic ):
|
||||||
|
@ -64,6 +65,16 @@ def randomBytes(n):
|
||||||
|
|
||||||
# Hashes
|
# Hashes
|
||||||
|
|
||||||
|
def _bm160(data):
|
||||||
|
"""RIPEME160(SHA512(data)) -> bytes"""
|
||||||
|
return RIPEMD160Hash(hashlib.sha512(data).digest()).digest()
|
||||||
|
|
||||||
|
|
||||||
|
def to_ripe(signing_key, encryption_key):
|
||||||
|
"""Convert two public keys to a ripe hash"""
|
||||||
|
return _bm160(signing_key + encryption_key)
|
||||||
|
|
||||||
|
|
||||||
def double_sha512(data):
|
def double_sha512(data):
|
||||||
"""Binary double SHA512 digest"""
|
"""Binary double SHA512 digest"""
|
||||||
return hashlib.sha512(hashlib.sha512(data).digest()).digest()
|
return hashlib.sha512(hashlib.sha512(data).digest()).digest()
|
||||||
|
|
|
@ -20,7 +20,6 @@ from addresses import (
|
||||||
encodeVarint, decodeVarint, decodeAddress, varintDecodeError)
|
encodeVarint, decodeVarint, decodeAddress, varintDecodeError)
|
||||||
from bmconfigparser import config
|
from bmconfigparser import config
|
||||||
from debug import logger
|
from debug import logger
|
||||||
from fallback import RIPEMD160Hash
|
|
||||||
from helper_sql import sqlExecute
|
from helper_sql import sqlExecute
|
||||||
from network.node import Peer
|
from network.node import Peer
|
||||||
from version import softwareVersion
|
from version import softwareVersion
|
||||||
|
@ -512,9 +511,9 @@ def decryptAndCheckPubkeyPayload(data, address):
|
||||||
readPosition = 0
|
readPosition = 0
|
||||||
# bitfieldBehaviors = decryptedData[readPosition:readPosition + 4]
|
# bitfieldBehaviors = decryptedData[readPosition:readPosition + 4]
|
||||||
readPosition += 4
|
readPosition += 4
|
||||||
publicSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
|
pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
|
||||||
readPosition += 64
|
readPosition += 64
|
||||||
publicEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
|
pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
|
||||||
readPosition += 64
|
readPosition += 64
|
||||||
specifiedNonceTrialsPerByteLength = decodeVarint(
|
specifiedNonceTrialsPerByteLength = decodeVarint(
|
||||||
decryptedData[readPosition:readPosition + 10])[1]
|
decryptedData[readPosition:readPosition + 10])[1]
|
||||||
|
@ -530,7 +529,7 @@ def decryptAndCheckPubkeyPayload(data, address):
|
||||||
signature = decryptedData[readPosition:readPosition + signatureLength]
|
signature = decryptedData[readPosition:readPosition + signatureLength]
|
||||||
|
|
||||||
if not highlevelcrypto.verify(
|
if not highlevelcrypto.verify(
|
||||||
signedData, signature, hexlify(publicSigningKey)):
|
signedData, signature, hexlify(pubSigningKey)):
|
||||||
logger.info(
|
logger.info(
|
||||||
'ECDSA verify failed (within decryptAndCheckPubkeyPayload)')
|
'ECDSA verify failed (within decryptAndCheckPubkeyPayload)')
|
||||||
return 'failed'
|
return 'failed'
|
||||||
|
@ -538,9 +537,7 @@ def decryptAndCheckPubkeyPayload(data, address):
|
||||||
logger.info(
|
logger.info(
|
||||||
'ECDSA verify passed (within decryptAndCheckPubkeyPayload)')
|
'ECDSA verify passed (within decryptAndCheckPubkeyPayload)')
|
||||||
|
|
||||||
sha = hashlib.new('sha512')
|
embeddedRipe = highlevelcrypto.to_ripe(pubSigningKey, pubEncryptionKey)
|
||||||
sha.update(publicSigningKey + publicEncryptionKey)
|
|
||||||
embeddedRipe = RIPEMD160Hash(sha.digest()).digest()
|
|
||||||
|
|
||||||
if embeddedRipe != ripe:
|
if embeddedRipe != ripe:
|
||||||
# Although this pubkey object had the tag were were looking for
|
# Although this pubkey object had the tag were were looking for
|
||||||
|
@ -558,7 +555,7 @@ def decryptAndCheckPubkeyPayload(data, address):
|
||||||
'addressVersion: %s, streamNumber: %s\nripe %s\n'
|
'addressVersion: %s, streamNumber: %s\nripe %s\n'
|
||||||
'publicSigningKey in hex: %s\npublicEncryptionKey in hex: %s',
|
'publicSigningKey in hex: %s\npublicEncryptionKey in hex: %s',
|
||||||
addressVersion, streamNumber, hexlify(ripe),
|
addressVersion, streamNumber, hexlify(ripe),
|
||||||
hexlify(publicSigningKey), hexlify(publicEncryptionKey)
|
hexlify(pubSigningKey), hexlify(pubEncryptionKey)
|
||||||
)
|
)
|
||||||
|
|
||||||
t = (address, addressVersion, storedData, int(time.time()), 'yes')
|
t = (address, addressVersion, storedData, int(time.time()), 'yes')
|
||||||
|
|
|
@ -8,6 +8,7 @@ sample_double_sha512 = unhexlify(
|
||||||
'0592a10584ffabf96539f3d780d776828c67da1ab5b169e9e8aed838aaecc9ed36d49ff14'
|
'0592a10584ffabf96539f3d780d776828c67da1ab5b169e9e8aed838aaecc9ed36d49ff14'
|
||||||
'23c55f019e050c66c6324f53588be88894fef4dcffdb74b98e2b200')
|
'23c55f019e050c66c6324f53588be88894fef4dcffdb74b98e2b200')
|
||||||
|
|
||||||
|
sample_bm160 = unhexlify('79a324faeebcbf9849f310545ed531556882487e')
|
||||||
|
|
||||||
# 500 identical peers:
|
# 500 identical peers:
|
||||||
# 1626611891, 1, 1, 127.0.0.1, 8444
|
# 1626611891, 1, 1, 127.0.0.1, 8444
|
||||||
|
|
|
@ -8,7 +8,7 @@ import unittest
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
|
|
||||||
from pybitmessage import highlevelcrypto, fallback
|
from pybitmessage import highlevelcrypto
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -17,10 +17,10 @@ except ImportError:
|
||||||
RIPEMD160 = None
|
RIPEMD160 = None
|
||||||
|
|
||||||
from .samples import (
|
from .samples import (
|
||||||
sample_deterministic_ripe, sample_double_sha512, sample_hash_data,
|
sample_bm160, sample_deterministic_ripe, sample_double_sha512,
|
||||||
sample_msg, sample_pubsigningkey, sample_pubencryptionkey,
|
sample_hash_data, sample_msg, sample_pubsigningkey,
|
||||||
sample_privsigningkey, sample_privencryptionkey, sample_ripe,
|
sample_pubencryptionkey, sample_privsigningkey, sample_privencryptionkey,
|
||||||
sample_seed, sample_sig, sample_sig_sha1
|
sample_ripe, sample_seed, sample_sig, sample_sig_sha1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +73,19 @@ class TestHighlevelcrypto(unittest.TestCase):
|
||||||
highlevelcrypto.double_sha512(sample_hash_data),
|
highlevelcrypto.double_sha512(sample_hash_data),
|
||||||
sample_double_sha512)
|
sample_double_sha512)
|
||||||
|
|
||||||
|
def test_bm160(self):
|
||||||
|
"""Formally check highlevelcrypto._bm160()"""
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
self.assertEqual(
|
||||||
|
highlevelcrypto._bm160(sample_hash_data), sample_bm160)
|
||||||
|
|
||||||
|
def test_to_ripe(self):
|
||||||
|
"""Formally check highlevelcrypto.to_ripe()"""
|
||||||
|
self.assertEqual(
|
||||||
|
hexlify(highlevelcrypto.to_ripe(
|
||||||
|
sample_pubsigningkey, sample_pubencryptionkey)),
|
||||||
|
sample_ripe)
|
||||||
|
|
||||||
def test_randomBytes(self):
|
def test_randomBytes(self):
|
||||||
"""Dummy checks for random bytes"""
|
"""Dummy checks for random bytes"""
|
||||||
for n in (8, 32, 64):
|
for n in (8, 32, 64):
|
||||||
|
@ -94,8 +107,7 @@ class TestHighlevelcrypto(unittest.TestCase):
|
||||||
enkey = highlevelcrypto.deterministic_keys(sample_seed, b'+')[1]
|
enkey = highlevelcrypto.deterministic_keys(sample_seed, b'+')[1]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
sample_deterministic_ripe,
|
sample_deterministic_ripe,
|
||||||
hexlify(fallback.RIPEMD160Hash(
|
hexlify(highlevelcrypto.to_ripe(sigkey, enkey)))
|
||||||
hashlib.sha512(sigkey + enkey).digest()).digest()))
|
|
||||||
|
|
||||||
def test_signatures(self):
|
def test_signatures(self):
|
||||||
"""Verify sample signatures and newly generated ones"""
|
"""Verify sample signatures and newly generated ones"""
|
||||||
|
|
Reference in New Issue
Block a user