diff --git a/onionr/onionr.py b/onionr/onionr.py
index 378eb892..62dc2fda 100755
--- a/onionr/onionr.py
+++ b/onionr/onionr.py
@@ -34,6 +34,8 @@ from utils import detectoptimization
if detectoptimization.detect_optimization():
sys.stderr.write('Error, Onionr cannot be run in optimized mode\n')
sys.exit(1)
+from utils import createdirs
+createdirs.create_dirs()
import os, base64, random, shutil, time, platform, signal
from threading import Thread
import config, logger, onionrplugins as plugins, onionrevents as events
@@ -42,7 +44,7 @@ from netcontroller import NetController
from onionrblockapi import Block
import onionrproofs, onionrexceptions, communicator, setupconfig
import onionrcommands as commands # Many command definitions are here
-from utils import identifyhome, createdirs
+from utils import identifyhome
from coredb import keydb
import filepaths
@@ -75,7 +77,6 @@ class Onionr:
# Load global configuration data
data_exists = Onionr.setupConfig(self.dataDir, self)
- createdirs.create_dirs()
if netcontroller.tor_binary() is None:
logger.error('Tor is not installed', terminal=True)
diff --git a/onionr/onionrblacklist.py b/onionr/onionrblacklist.py
index 3542a1f5..d0702e5e 100755
--- a/onionr/onionrblacklist.py
+++ b/onionr/onionrblacklist.py
@@ -21,7 +21,7 @@ import sqlite3, os
import logger, onionrcrypto
from onionrutils import epoch, bytesconverter
from coredb import dbfiles
-crypto = onionrcrypto.OnionrCrypto()
+
class OnionrBlackList:
def __init__(self):
self.blacklistDB = dbfiles.blacklist_db
@@ -31,7 +31,7 @@ class OnionrBlackList:
return
def inBlacklist(self, data):
- hashed = bytesconverter.bytes_to_str(crypto.sha3Hash(data))
+ hashed = bytesconverter.bytes_to_str(onionrcrypto.hashers.sha3_hash(data))
retData = False
if not hashed.isalnum():
@@ -100,6 +100,7 @@ class OnionrBlackList:
1=peer
2=pubkey
'''
+
# we hash the data so we can remove data entirely from our node's disk
hashed = bytesconverter.bytes_to_str(crypto.sha3Hash(data))
if len(hashed) > 64:
diff --git a/onionr/onionrblocks/__init__.py b/onionr/onionrblocks/__init__.py
index 3e3c20ba..93e9fd3f 100644
--- a/onionr/onionrblocks/__init__.py
+++ b/onionr/onionrblocks/__init__.py
@@ -1 +1,3 @@
-from . import insert
\ No newline at end of file
+from . import insert
+
+insert = insert.insert_block
\ No newline at end of file
diff --git a/onionr/onionrblocks/insert.py b/onionr/onionrblocks/insert.py
index b4727511..073ae9e0 100644
--- a/onionr/onionrblocks/insert.py
+++ b/onionr/onionrblocks/insert.py
@@ -3,15 +3,18 @@ from onionrutils import bytesconverter, epoch
import storagecounter, filepaths, onionrstorage
import onionrevents as events
from etc import powchoice, onionrvalues
-def insert_block(onionr_inst, data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta = {}, expire=None, disableForward=False):
+import config, onionrcrypto as crypto, subprocesspow, onionrexceptions
+from onionrusers import onionrusers
+from onionrutils import localcommand, blockmetadata
+import coredb
+def insert_block(data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta = {}, expire=None, disableForward=False):
'''
Inserts a block into the network
encryptType must be specified to encrypt a block
'''
- use_subprocess = powchoice.use_subprocess(onionr_inst.config)
+ use_subprocess = powchoice.use_subprocess(config)
requirements = onionrvalues.OnionrValues()
storage_counter = storagecounter.StorageCounter()
- crypto = onionr_inst.crypto
allocationReachedMessage = 'Cannot insert block, disk allocation reached.'
if storage_counter.isFull():
logger.error(allocationReachedMessage)
@@ -23,7 +26,7 @@ def insert_block(onionr_inst, data, header='txt', sign=False, encryptType='', sy
createTime = epoch.get_epoch()
- dataNonce = bytesconverter.bytes_to_str(hashers.sha3_hash(data))
+ dataNonce = bytesconverter.bytes_to_str(crypto.hashers.sha3_hash(data))
try:
with open(filepaths.data_nonce_file, 'r') as nonces:
if dataNonce in nonces:
@@ -78,31 +81,23 @@ def insert_block(onionr_inst, data, header='txt', sign=False, encryptType='', sy
jsonMeta = json.dumps(meta)
plaintextMeta = jsonMeta
if sign:
- signature = crypto.edSign(jsonMeta.encode() + data, key=crypto.privKey, encodeResult=True)
+ signature = crypto.signing.ed_sign(jsonMeta.encode() + data, key=crypto.priv_key, encodeResult=True)
signer = crypto.pubKey
if len(jsonMeta) > 1000:
raise onionrexceptions.InvalidMetadata('meta in json encoded form must not exceed 1000 bytes')
- user = onionrusers.OnionrUser(symKey)
-
# encrypt block metadata/sig/content
if encryptType == 'sym':
-
- if len(symKey) < requirements.passwordLength:
- raise onionrexceptions.SecurityError('Weak encryption key')
- jsonMeta = crypto.symmetricEncrypt(jsonMeta, key=symKey, returnEncoded=True).decode()
- data = crypto.symmetricEncrypt(data, key=symKey, returnEncoded=True).decode()
- signature = crypto.symmetricEncrypt(signature, key=symKey, returnEncoded=True).decode()
- signer = crypto.symmetricEncrypt(signer, key=symKey, returnEncoded=True).decode()
+ raise NotImplementedError("not yet implemented")
elif encryptType == 'asym':
if stringvalidators.validate_pub_key(asymPeer):
# Encrypt block data with forward secrecy key first, but not meta
jsonMeta = json.dumps(meta)
- jsonMeta = crypto.pubKeyEncrypt(jsonMeta, asymPeer, encodedData=True).decode()
- data = crypto.pubKeyEncrypt(data, asymPeer, encodedData=True).decode()
- signature = crypto.pubKeyEncrypt(signature, asymPeer, encodedData=True).decode()
- signer = crypto.pubKeyEncrypt(signer, asymPeer, encodedData=True).decode()
+ jsonMeta = crypto.encryption.pub_key_encrypt(jsonMeta, asymPeer, encodedData=True).decode()
+ data = crypto.encryption.pub_key_encrypt(data, asymPeer, encodedData=True).decode()
+ signature = crypto.pub_key_encrypt(signature, asymPeer, encodedData=True).decode()
+ signer = crypto.pub_key_encrypt(signer, asymPeer, encodedData=True).decode()
try:
onionrusers.OnionrUser(asymPeer, saveUser=True)
except ValueError:
@@ -141,8 +136,8 @@ def insert_block(onionr_inst, data, header='txt', sign=False, encryptType='', sy
coredb.daemonqueue.daemon_queue_add('uploadBlock', retData)
else:
pass
- coredb.blockmetadb.add_to_block_DB(retData, selfInsert=True, dataSaved=True)
- coredb.blockmetadata.process_block_metadata(retData)
+ coredb.blockmetadb.add.add_to_block_DB(retData, selfInsert=True, dataSaved=True)
+ blockmetadata.process_block_metadata(retData)
'''
if retData != False:
if plaintextPeer == onionrvalues.DENIABLE_PEER_ADDRESS:
diff --git a/onionr/onionrcommands/onionrstatistics.py b/onionr/onionrcommands/onionrstatistics.py
index 4a9e6350..6511af08 100755
--- a/onionr/onionrcommands/onionrstatistics.py
+++ b/onionr/onionrcommands/onionrstatistics.py
@@ -25,7 +25,6 @@ from onionrutils import checkcommunicator, mnemonickeys
from utils import sizeutils
from coredb import blockmetadb, daemonqueue, keydb
import onionrcrypto
-crypto = onionrcrypto.OnionrCrypto()
def show_stats(o_inst):
try:
# define stats messages here
@@ -89,7 +88,7 @@ def show_details(o_inst):
details = {
'Node Address' : o_inst.get_hostname(),
'Web Password' : o_inst.getWebPassword(),
- 'Public Key' : crypto.pubKey,
+ 'Public Key' : onionrcrypto.pub_key,
'Human-readable Public Key' : mnemonickeys.get_human_readable_ID()
}
diff --git a/onionr/onionrcrypto/__init__.py b/onionr/onionrcrypto/__init__.py
index df5a9088..d650d647 100755
--- a/onionr/onionrcrypto/__init__.py
+++ b/onionr/onionrcrypto/__init__.py
@@ -17,178 +17,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
'''
-import os, binascii, base64, hashlib, time, sys, hmac, secrets
-import nacl.signing, nacl.encoding, nacl.public, nacl.hash, nacl.pwhash, nacl.utils, nacl.secret
-import unpaddedbase32
-import logger, onionrproofs
-from onionrutils import stringvalidators, epoch, bytesconverter
-import filepaths
-import onionrexceptions, keymanager, onionrutils
-import config
-from . import generate, hashers
-config.reload()
-class OnionrCrypto:
- def __init__(self):
- self._keyFile = filepaths.keys_file
- self.pubKey = None
- self.privKey = None
- self.secrets = secrets
- self.deterministicRequirement = 25 # Min deterministic password/phrase length
- self.HASH_ID_ROUNDS = 2000
- self.keyManager = keymanager.KeyManager()
-
- # Load our own pub/priv Ed25519 keys, gen & save them if they don't exist
- if os.path.exists(self._keyFile):
- if len(config.get('general.public_key', '')) > 0:
- self.pubKey = config.get('general.public_key')
- else:
- self.pubKey = self.keyManager.getPubkeyList()[0]
- self.privKey = self.keyManager.getPrivkey(self.pubKey)
- else:
- keys = self.generatePubKey()
- self.pubKey = keys[0]
- self.privKey = keys[1]
- self.keyManager.addKey(self.pubKey, self.privKey)
- return
+from . import generate, hashers, getourkeypair, signing, encryption
- def pubKeyEncrypt(self, data, pubkey, encodedData=False):
- '''Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)'''
- pubkey = unpaddedbase32.repad(bytesconverter.str_to_bytes(pubkey))
- retVal = ''
- box = None
- data = bytesconverter.str_to_bytes(data)
-
- pubkey = nacl.signing.VerifyKey(pubkey, encoder=nacl.encoding.Base32Encoder()).to_curve25519_public_key()
-
- if encodedData:
- encoding = nacl.encoding.Base64Encoder
- else:
- encoding = nacl.encoding.RawEncoder
-
- box = nacl.public.SealedBox(pubkey)
- retVal = box.encrypt(data, encoder=encoding)
-
- return retVal
-
- def symmetricEncrypt(self, data, key, encodedKey=False, returnEncoded=True):
- '''Encrypt data with a 32-byte key (Salsa20-Poly1305 MAC)'''
- if encodedKey:
- encoding = nacl.encoding.Base64Encoder
- else:
- encoding = nacl.encoding.RawEncoder
-
- # Make sure data is bytes
- if type(data) != bytes:
- data = data.encode()
-
- box = nacl.secret.SecretBox(key, encoder=encoding)
-
- if returnEncoded:
- encoding = nacl.encoding.Base64Encoder
- else:
- encoding = nacl.encoding.RawEncoder
-
- encrypted = box.encrypt(data, encoder=encoding)
- return encrypted
-
- def symmetricDecrypt(self, data, key, encodedKey=False, encodedMessage=False, returnEncoded=False):
- '''Decrypt data to a 32-byte key (Salsa20-Poly1305 MAC)'''
- if encodedKey:
- encoding = nacl.encoding.Base64Encoder
- else:
- encoding = nacl.encoding.RawEncoder
- box = nacl.secret.SecretBox(key, encoder=encoding)
-
- if encodedMessage:
- encoding = nacl.encoding.Base64Encoder
- else:
- encoding = nacl.encoding.RawEncoder
- decrypted = box.decrypt(data, encoder=encoding)
- if returnEncoded:
- decrypted = base64.b64encode(decrypted)
- return decrypted
-
- def generateSymmetric(self):
- '''Generate a symmetric key (bytes) and return it'''
- return binascii.hexlify(nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE))
-
- def generatePubKey(self):
- '''Generate a Ed25519 public key pair, return tuple of base32encoded pubkey, privkey'''
- return generate.generate_pub_key()
-
- def generateDeterministic(self, passphrase, bypassCheck=False):
- '''Generate a Ed25519 public key pair from a password'''
- passStrength = self.deterministicRequirement
- passphrase = bytesconverter.str_to_bytes(passphrase) # Convert to bytes if not already
- # Validate passphrase length
- if not bypassCheck:
- if len(passphrase) < passStrength:
- raise onionrexceptions.PasswordStrengthError("Passphase must be at least %s characters" % (passStrength,))
- # KDF values
- kdf = nacl.pwhash.argon2id.kdf
- salt = b"U81Q7llrQcdTP0Ux" # Does not need to be unique or secret, but must be 16 bytes
- ops = nacl.pwhash.argon2id.OPSLIMIT_SENSITIVE
- mem = nacl.pwhash.argon2id.MEMLIMIT_SENSITIVE
-
- key = kdf(32, passphrase, salt, opslimit=ops, memlimit=mem) # Generate seed for ed25519 key
- key = nacl.signing.SigningKey(key)
- return (key.verify_key.encode(nacl.encoding.Base32Encoder).decode(), key.encode(nacl.encoding.Base32Encoder).decode())
-
- def pubKeyHashID(self, pubkey=''):
- '''Accept a ed25519 public key, return a truncated result of X many sha3_256 hash rounds'''
- if pubkey == '':
- pubkey = self.pubKey
- prev = ''
- pubkey = bytesconverter.str_to_bytes(pubkey)
- for i in range(self.HASH_ID_ROUNDS):
- try:
- prev = prev.encode()
- except AttributeError:
- pass
- hasher = hashlib.sha3_256()
- hasher.update(pubkey + prev)
- prev = hasher.hexdigest()
- result = prev
- return result
-
- def sha3Hash(self, data):
- return hashers.sha3_hash(data)
-
- def blake2bHash(self, data):
- return hashers.blake2b_hash(data)
-
- def verifyPow(self, blockContent):
- '''
- Verifies the proof of work associated with a block
- '''
- retData = False
-
- dataLen = len(blockContent)
-
- try:
- blockContent = blockContent.encode()
- except AttributeError:
- pass
-
- blockHash = self.sha3Hash(blockContent)
- try:
- blockHash = blockHash.decode() # bytes on some versions for some reason
- except AttributeError:
- pass
-
- difficulty = onionrproofs.getDifficultyForNewBlock(blockContent, ourBlock=False)
-
- if difficulty < int(config.get('general.minimum_block_pow')):
- difficulty = int(config.get('general.minimum_block_pow'))
- mainHash = '0000000000000000000000000000000000000000000000000000000000000000'#nacl.hash.blake2b(nacl.utils.random()).decode()
- puzzle = mainHash[:difficulty]
-
- if blockHash[:difficulty] == puzzle:
- # logger.debug('Validated block pow')
- retData = True
- else:
- logger.debug("Invalid token, bad proof")
-
- return retData
\ No newline at end of file
+keypair = getourkeypair.get_keypair()
+pub_key = keypair[0]
+priv_key = keypair[1]
diff --git a/onionr/onionrcrypto/encryption/__init__.py b/onionr/onionrcrypto/encryption/__init__.py
index e676851e..d334bc78 100644
--- a/onionr/onionrcrypto/encryption/__init__.py
+++ b/onionr/onionrcrypto/encryption/__init__.py
@@ -1,9 +1,29 @@
import nacl.encoding, nacl.public, nacl.signing
from .. import getourkeypair
+import unpaddedbase32
pair = getourkeypair.get_keypair()
our_pub_key = pair[0]
our_priv_key = pair[1]
+def pub_key_encrypt(data, pubkey, encodedData=False):
+ '''Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)'''
+ pubkey = unpaddedbase32.repad(bytesconverter.str_to_bytes(pubkey))
+ retVal = ''
+ box = None
+ data = bytesconverter.str_to_bytes(data)
+
+ pubkey = nacl.signing.VerifyKey(pubkey, encoder=nacl.encoding.Base32Encoder()).to_curve25519_public_key()
+
+ if encodedData:
+ encoding = nacl.encoding.Base64Encoder
+ else:
+ encoding = nacl.encoding.RawEncoder
+
+ box = nacl.public.SealedBox(pubkey)
+ retVal = box.encrypt(data, encoder=encoding)
+
+ return retVal
+
def pub_key_decrypt(data, pubkey='', privkey='', encodedData=False):
'''pubkey decrypt (Curve25519, taken from Ed25519 pubkey)'''
decrypted = False
diff --git a/onionr/onionrevents.py b/onionr/onionrevents.py
index beaeca01..f8d16653 100755
--- a/onionr/onionrevents.py
+++ b/onionr/onionrevents.py
@@ -33,11 +33,11 @@ def __event_caller(event_name, data = {}, onionr = None):
try:
call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(onionr, data))
except ModuleNotFoundError as e:
- logger.warn('Disabling nonexistant plugin "%s"...' % plugin)
+ logger.warn('Disabling nonexistant plugin "%s"...' % plugin, terminal=True)
plugins.disable(plugin, onionr, stop_event = False)
except Exception as e:
- logger.warn('Event "%s" failed for plugin "%s".' % (event_name, plugin))
- logger.debug(str(e))
+ logger.warn('Event "%s" failed for plugin "%s".' % (event_name, plugin), terminal=True)
+ logger.debug(str(e), terminal=True)
def event(event_name, data = {}, onionr = None, threaded = True):
diff --git a/onionr/onionrpluginapi.py b/onionr/onionrpluginapi.py
index 1208b267..f5731e69 100755
--- a/onionr/onionrpluginapi.py
+++ b/onionr/onionrpluginapi.py
@@ -18,7 +18,7 @@
along with this program. If not, see .
'''
-import onionrplugins, logger, onionrcrypto
+import onionrplugins, logger
from onionrutils import localcommand
from coredb import daemonqueue
class DaemonAPI:
@@ -154,7 +154,6 @@ class pluginapi:
self.plugins = PluginAPI(self)
self.commands = CommandAPI(self)
self.web = WebAPI(self)
- self.crypto = onionrcrypto.OnionrCrypto()
def get_onionr(self):
return self.onionr
@@ -162,9 +161,6 @@ class pluginapi:
def get_data(self):
return self.data
- def get_crypto(self):
- return self.crypto
-
def get_daemonapi(self):
return self.daemon
diff --git a/onionr/onionrproofs.py b/onionr/onionrproofs.py
index 349d8ec7..1388dcd0 100755
--- a/onionr/onionrproofs.py
+++ b/onionr/onionrproofs.py
@@ -26,7 +26,6 @@ def getDifficultyModifier():
'''returns the difficulty modifier for block storage based
on a variety of factors, currently only disk use.
'''
- classInst = coreOrUtilsInst
retData = 0
useFunc = storagecounter.StorageCounter().getPercent
diff --git a/onionr/onionrstorage/__init__.py b/onionr/onionrstorage/__init__.py
index c642baad..46e0aac9 100755
--- a/onionr/onionrstorage/__init__.py
+++ b/onionr/onionrstorage/__init__.py
@@ -24,14 +24,7 @@ import filepaths, onionrcrypto, dbcreator, onionrexceptions
from onionrcrypto import hashers
DB_ENTRY_SIZE_LIMIT = 10000 # Will be a config option
-def dbCreate():
- try:
- dbcreator.DBCreator().createBlockDataDB()
- except FileExistsError:
- pass
-
def _dbInsert(blockHash, data):
- dbCreate()
conn = sqlite3.connect(dbfiles.block_data_db, timeout=10)
c = conn.cursor()
data = (blockHash, data)
@@ -40,7 +33,6 @@ def _dbInsert(blockHash, data):
conn.close()
def _dbFetch(blockHash):
- dbCreate()
conn = sqlite3.connect(dbfiles.block_data_db, timeout=10)
c = conn.cursor()
for i in c.execute('SELECT data from blockData where hash = ?', (blockHash,)):
@@ -54,7 +46,6 @@ def deleteBlock(blockHash):
if os.path.exists('%s/%s.dat' % (filepaths.block_data_location, blockHash)):
os.remove('%s/%s.dat' % (filepaths.block_data_location, blockHash))
return True
- dbCreate()
conn = sqlite3.connect(dbfiles.block_data_db, timeout=10)
c = conn.cursor()
data = (blockHash,)
@@ -91,7 +82,7 @@ def getData(bHash):
with open(fileLocation, 'rb') as block:
retData = block.read()
else:
- retData = _dbFetch(coreInst, bHash)
+ retData = _dbFetch(bHash)
if retData is None:
raise onionrexceptions.NoDataAvailable("Block data for %s is not available" % [bHash])
return retData
\ No newline at end of file
diff --git a/onionr/onionrstorage/setdata.py b/onionr/onionrstorage/setdata.py
index 096612f8..6558d3f9 100644
--- a/onionr/onionrstorage/setdata.py
+++ b/onionr/onionrstorage/setdata.py
@@ -1,12 +1,11 @@
import sys, sqlite3
-import onionrstorage, onionrexceptions, onionrcrypto
+import onionrstorage, onionrexceptions, onionrcrypto as crypto
import filepaths, storagecounter
from coredb import dbfiles
def set_data(data):
'''
Set the data assciated with a hash
'''
- crypto = onionrcrypto.OnionrCrypto()
storage_counter = storagecounter.StorageCounter()
data = data
dataSize = sys.getsizeof(data)
@@ -14,7 +13,7 @@ def set_data(data):
if not type(data) is bytes:
data = data.encode()
- dataHash = crypto.sha3Hash(data)
+ dataHash = crypto.hashers.sha3_hash(data)
if type(dataHash) is bytes:
dataHash = dataHash.decode()
diff --git a/onionr/onionrutils/localcommand.py b/onionr/onionrutils/localcommand.py
index 54df8640..073182bd 100644
--- a/onionr/onionrutils/localcommand.py
+++ b/onionr/onionrutils/localcommand.py
@@ -30,9 +30,13 @@ def get_hostname():
maxWait = 3
while True:
if cache.get('client_api') is None:
- hostname = getclientapiserver.get_client_API_server()
- cache.put('hostname', hostname)
- cache.flush()
+ try:
+ hostname = getclientapiserver.get_client_API_server()
+ except FileNotFoundError:
+ hostname = False
+ else:
+ cache.put('hostname', hostname)
+ cache.flush()
else:
hostname = cache.get('hostname')
if hostname == '' or hostname is None:
@@ -48,9 +52,11 @@ def local_command(command, data='', silent = True, post=False, postData = {}, ma
'''
# TODO: URL encode parameters, just as an extra measure. May not be needed, but should be added regardless.
hostname = get_hostname()
+ if hostname == False: return False
if data != '':
data = '&data=' + urllib.parse.quote_plus(data)
payload = 'http://%s/%s%s' % (hostname, command, data)
+
try:
if post:
retData = requests.post(payload, data=postData, headers={'token': config.get('client.webpassword'), 'Connection':'close'}, timeout=(maxWait, maxWait)).text
diff --git a/onionr/onionrutils/mnemonickeys.py b/onionr/onionrutils/mnemonickeys.py
index 8310f072..527b455f 100644
--- a/onionr/onionrutils/mnemonickeys.py
+++ b/onionr/onionrutils/mnemonickeys.py
@@ -23,6 +23,6 @@ import onionrcrypto
def get_human_readable_ID(pub=''):
'''gets a human readable ID from a public key'''
if pub == '':
- pub = onionrcrypto.OnionrCrypto().pubKey
+ pub = onionrcrypto.pub_key
pub = base64.b16encode(base64.b32decode(pub)).decode()
return ' '.join(pgpwords.wordify(pub))
diff --git a/onionr/static-data/default-plugins/flow/main.py b/onionr/static-data/default-plugins/flow/main.py
index d98f6585..4d5954b7 100755
--- a/onionr/static-data/default-plugins/flow/main.py
+++ b/onionr/static-data/default-plugins/flow/main.py
@@ -96,7 +96,6 @@ def on_init(api, data = None):
inputted is executed. Could be called when daemon is starting or when
just the client is running.
'''
-
# Doing this makes it so that the other functions can access the api object
# by simply referencing the variable `pluginapi`.
global pluginapi
diff --git a/onionr/subprocesspow.py b/onionr/subprocesspow.py
index 95586ca0..730d2307 100755
--- a/onionr/subprocesspow.py
+++ b/onionr/subprocesspow.py
@@ -22,9 +22,8 @@
import subprocess, os
import multiprocessing, threading, time, json
from multiprocessing import Pipe, Process
-import onionrblockapi, config, onionrutils, logger, onionrproofs, onionrcrypto
+import onionrblockapi, config, onionrutils, logger, onionrproofs, onionrcrypto as crypto
from onionrutils import bytesconverter
-crypto = onionrcrypto.OnionrCrypto()
class SubprocessPOW:
def __init__(self, data, metadata, subproc_count=None):
'''
@@ -105,7 +104,7 @@ class SubprocessPOW:
# Serialize metadata, combine with block data
payload = json.dumps(metadata).encode() + b'\n' + data
# Check sha3_256 hash of block, compare to puzzle. Send payload if puzzle finished
- token = crypto.sha3Hash(payload)
+ token = crypto.hashers.sha3_hash(payload)
token = bytesconverter.bytes_to_str(token) # ensure token is string
if puzzle == token[0:difficulty]:
pipe.send(payload)