diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py
index 929ac364..33da1371 100644
--- a/src/class_addressGenerator.py
+++ b/src/class_addressGenerator.py
@@ -1,7 +1,7 @@
 """
 A thread for creating addresses
 """
-import hashlib
+
 import time
 from binascii import hexlify
 
@@ -14,7 +14,6 @@ import shared
 import state
 from addresses import decodeAddress, encodeAddress, encodeVarint
 from bmconfigparser import config
-from fallback import RIPEMD160Hash
 from network import StoppableThread
 from tr import _translate
 
@@ -133,9 +132,8 @@ class addressGenerator(StoppableThread):
                     numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
                     potentialPrivEncryptionKey, potentialPubEncryptionKey = \
                         highlevelcrypto.random_keys()
-                    sha = hashlib.new('sha512')
-                    sha.update(pubSigningKey + potentialPubEncryptionKey)
-                    ripe = RIPEMD160Hash(sha.digest()).digest()
+                    ripe = highlevelcrypto.to_ripe(
+                        pubSigningKey, potentialPubEncryptionKey)
                     if (
                         ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
                         == b'\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
@@ -244,10 +242,8 @@ class addressGenerator(StoppableThread):
 
                         signingKeyNonce += 2
                         encryptionKeyNonce += 2
-                        sha = hashlib.new('sha512')
-                        sha.update(
-                            potentialPubSigningKey + potentialPubEncryptionKey)
-                        ripe = RIPEMD160Hash(sha.digest()).digest()
+                        ripe = highlevelcrypto.to_ripe(
+                            potentialPubSigningKey, potentialPubEncryptionKey)
                         if (
                             ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
                             == b'\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py
index 50c23e2c..469ccbfa 100644
--- a/src/class_objectProcessor.py
+++ b/src/class_objectProcessor.py
@@ -28,7 +28,6 @@ from addresses import (
     encodeAddress, encodeVarint, varintDecodeError
 )
 from bmconfigparser import config
-from fallback import RIPEMD160Hash
 from helper_sql import (
     sql_ready, sql_timeout, SqlBulkExecute, sqlExecute, sqlQuery)
 from network import knownnodes
@@ -300,23 +299,20 @@ class objectProcessor(threading.Thread):
                     '(within processpubkey) payloadLength less than 146.'
                     ' Sanity check failed.')
             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
             # encrypt or sign with it will cause an error? If it is, it would
             # be easiest to test them here.
             readPosition += 64
-            publicEncryptionKey = data[readPosition:readPosition + 64]
-            if len(publicEncryptionKey) < 64:
+            pubEncryptionKey = '\x04' + data[readPosition:readPosition + 64]
+            if len(pubEncryptionKey) < 65:
                 return logger.debug(
                     'publicEncryptionKey length less than 64. Sanity check'
                     ' failed.')
             readPosition += 64
             # The data we'll store in the pubkeys table.
             dataToStore = data[20:readPosition]
-            sha = hashlib.new('sha512')
-            sha.update(
-                '\x04' + publicSigningKey + '\x04' + publicEncryptionKey)
-            ripe = RIPEMD160Hash(sha.digest()).digest()
+            ripe = highlevelcrypto.to_ripe(pubSigningKey, pubEncryptionKey)
 
             if logger.isEnabledFor(logging.DEBUG):
                 logger.debug(
@@ -324,7 +320,7 @@ class objectProcessor(threading.Thread):
                     '\nripe %s\npublicSigningKey in hex: %s'
                     '\npublicEncryptionKey in hex: %s',
                     addressVersion, streamNumber, hexlify(ripe),
-                    hexlify(publicSigningKey), hexlify(publicEncryptionKey)
+                    hexlify(pubSigningKey), hexlify(pubEncryptionKey)
                 )
 
             address = encodeAddress(addressVersion, streamNumber, ripe)
@@ -354,9 +350,9 @@ class objectProcessor(threading.Thread):
                     ' Sanity check failed.')
                 return
             readPosition += 4
-            publicSigningKey = '\x04' + data[readPosition:readPosition + 64]
+            pubSigningKey = '\x04' + data[readPosition:readPosition + 64]
             readPosition += 64
-            publicEncryptionKey = '\x04' + data[readPosition:readPosition + 64]
+            pubEncryptionKey = '\x04' + data[readPosition:readPosition + 64]
             readPosition += 64
             specifiedNonceTrialsPerByteLength = decodeVarint(
                 data[readPosition:readPosition + 10])[1]
@@ -373,15 +369,13 @@ class objectProcessor(threading.Thread):
             signature = data[readPosition:readPosition + signatureLength]
             if highlevelcrypto.verify(
                     data[8:endOfSignedDataPosition],
-                    signature, hexlify(publicSigningKey)):
+                    signature, hexlify(pubSigningKey)):
                 logger.debug('ECDSA verify passed (within processpubkey)')
             else:
                 logger.warning('ECDSA verify failed (within processpubkey)')
                 return
 
-            sha = hashlib.new('sha512')
-            sha.update(publicSigningKey + publicEncryptionKey)
-            ripe = RIPEMD160Hash(sha.digest()).digest()
+            ripe = highlevelcrypto.to_ripe(pubSigningKey, pubEncryptionKey)
 
             if logger.isEnabledFor(logging.DEBUG):
                 logger.debug(
@@ -389,7 +383,7 @@ class objectProcessor(threading.Thread):
                     '\nripe %s\npublicSigningKey in hex: %s'
                     '\npublicEncryptionKey in hex: %s',
                     addressVersion, streamNumber, hexlify(ripe),
-                    hexlify(publicSigningKey), hexlify(publicEncryptionKey)
+                    hexlify(pubSigningKey), hexlify(pubEncryptionKey)
                 )
 
             address = encodeAddress(addressVersion, streamNumber, ripe)
@@ -588,9 +582,7 @@ class objectProcessor(threading.Thread):
         sigHash = highlevelcrypto.double_sha512(signature)[32:]
 
         # calculate the fromRipe.
-        sha = hashlib.new('sha512')
-        sha.update(pubSigningKey + pubEncryptionKey)
-        ripe = RIPEMD160Hash(sha.digest()).digest()
+        ripe = highlevelcrypto.to_ripe(pubSigningKey, pubEncryptionKey)
         fromAddress = encodeAddress(
             sendersAddressVersionNumber, sendersStreamNumber, ripe)
 
@@ -883,9 +875,8 @@ class objectProcessor(threading.Thread):
                 requiredPayloadLengthExtraBytes)
         endOfPubkeyPosition = readPosition
 
-        sha = hashlib.new('sha512')
-        sha.update(sendersPubSigningKey + sendersPubEncryptionKey)
-        calculatedRipe = RIPEMD160Hash(sha.digest()).digest()
+        calculatedRipe = highlevelcrypto.to_ripe(
+            sendersPubSigningKey, sendersPubEncryptionKey)
 
         if broadcastVersion == 4:
             if toRipe != calculatedRipe:
diff --git a/src/highlevelcrypto.py b/src/highlevelcrypto.py
index d7af85de..d59a721d 100644
--- a/src/highlevelcrypto.py
+++ b/src/highlevelcrypto.py
@@ -15,12 +15,13 @@ import pyelliptic
 from pyelliptic import OpenSSL
 from pyelliptic import arithmetic as a
 
+from fallback import RIPEMD160Hash
 
 __all__ = [
     'decodeWalletImportFormat', 'deterministic_keys',
     'double_sha512', 'calculateInventoryHash', 'encodeWalletImportFormat',
     'encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'randomBytes',
-    'random_keys', 'sign', 'verify']
+    'random_keys', 'sign', 'to_ripe', 'verify']
 
 
 # WIF (uses arithmetic ):
@@ -64,6 +65,16 @@ def randomBytes(n):
 
 # 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):
     """Binary double SHA512 digest"""
     return hashlib.sha512(hashlib.sha512(data).digest()).digest()
diff --git a/src/protocol.py b/src/protocol.py
index d1a5f865..7f9830e5 100644
--- a/src/protocol.py
+++ b/src/protocol.py
@@ -20,7 +20,6 @@ from addresses import (
     encodeVarint, decodeVarint, decodeAddress, varintDecodeError)
 from bmconfigparser import config
 from debug import logger
-from fallback import RIPEMD160Hash
 from helper_sql import sqlExecute
 from network.node import Peer
 from version import softwareVersion
@@ -512,9 +511,9 @@ def decryptAndCheckPubkeyPayload(data, address):
         readPosition = 0
         # bitfieldBehaviors = decryptedData[readPosition:readPosition + 4]
         readPosition += 4
-        publicSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
+        pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
         readPosition += 64
-        publicEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
+        pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
         readPosition += 64
         specifiedNonceTrialsPerByteLength = decodeVarint(
             decryptedData[readPosition:readPosition + 10])[1]
@@ -530,7 +529,7 @@ def decryptAndCheckPubkeyPayload(data, address):
         signature = decryptedData[readPosition:readPosition + signatureLength]
 
         if not highlevelcrypto.verify(
-                signedData, signature, hexlify(publicSigningKey)):
+                signedData, signature, hexlify(pubSigningKey)):
             logger.info(
                 'ECDSA verify failed (within decryptAndCheckPubkeyPayload)')
             return 'failed'
@@ -538,9 +537,7 @@ def decryptAndCheckPubkeyPayload(data, address):
         logger.info(
             'ECDSA verify passed (within decryptAndCheckPubkeyPayload)')
 
-        sha = hashlib.new('sha512')
-        sha.update(publicSigningKey + publicEncryptionKey)
-        embeddedRipe = RIPEMD160Hash(sha.digest()).digest()
+        embeddedRipe = highlevelcrypto.to_ripe(pubSigningKey, pubEncryptionKey)
 
         if embeddedRipe != ripe:
             # 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'
             'publicSigningKey in hex: %s\npublicEncryptionKey in hex: %s',
             addressVersion, streamNumber, hexlify(ripe),
-            hexlify(publicSigningKey), hexlify(publicEncryptionKey)
+            hexlify(pubSigningKey), hexlify(pubEncryptionKey)
         )
 
         t = (address, addressVersion, storedData, int(time.time()), 'yes')
diff --git a/src/tests/samples.py b/src/tests/samples.py
index 9f6c9d5b..dd862318 100644
--- a/src/tests/samples.py
+++ b/src/tests/samples.py
@@ -8,6 +8,7 @@ sample_double_sha512 = unhexlify(
     '0592a10584ffabf96539f3d780d776828c67da1ab5b169e9e8aed838aaecc9ed36d49ff14'
     '23c55f019e050c66c6324f53588be88894fef4dcffdb74b98e2b200')
 
+sample_bm160 = unhexlify('79a324faeebcbf9849f310545ed531556882487e')
 
 # 500 identical peers:
 # 1626611891, 1, 1, 127.0.0.1, 8444
diff --git a/src/tests/test_crypto.py b/src/tests/test_crypto.py
index e518d7fd..6dbb2f31 100644
--- a/src/tests/test_crypto.py
+++ b/src/tests/test_crypto.py
@@ -8,7 +8,7 @@ import unittest
 from abc import ABCMeta, abstractmethod
 from binascii import hexlify
 
-from pybitmessage import highlevelcrypto, fallback
+from pybitmessage import highlevelcrypto
 
 
 try:
@@ -17,10 +17,10 @@ except ImportError:
     RIPEMD160 = None
 
 from .samples import (
-    sample_deterministic_ripe, sample_double_sha512, sample_hash_data,
-    sample_msg, sample_pubsigningkey, sample_pubencryptionkey,
-    sample_privsigningkey, sample_privencryptionkey, sample_ripe,
-    sample_seed, sample_sig, sample_sig_sha1
+    sample_bm160, sample_deterministic_ripe, sample_double_sha512,
+    sample_hash_data, sample_msg, sample_pubsigningkey,
+    sample_pubencryptionkey, sample_privsigningkey, sample_privencryptionkey,
+    sample_ripe, sample_seed, sample_sig, sample_sig_sha1
 )
 
 
@@ -73,6 +73,19 @@ class TestHighlevelcrypto(unittest.TestCase):
             highlevelcrypto.double_sha512(sample_hash_data),
             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):
         """Dummy checks for random bytes"""
         for n in (8, 32, 64):
@@ -94,8 +107,7 @@ class TestHighlevelcrypto(unittest.TestCase):
         enkey = highlevelcrypto.deterministic_keys(sample_seed, b'+')[1]
         self.assertEqual(
             sample_deterministic_ripe,
-            hexlify(fallback.RIPEMD160Hash(
-                hashlib.sha512(sigkey + enkey).digest()).digest()))
+            hexlify(highlevelcrypto.to_ripe(sigkey, enkey)))
 
     def test_signatures(self):
         """Verify sample signatures and newly generated ones"""