started c# pow implementation
parent
fd0f13cf63
commit
60c1ec07e9
|
@ -205,6 +205,7 @@ def insert_block(data: Union[str, bytes], header: str = 'txt',
|
||||||
|
|
||||||
# send block data (and metadata) to POW module to get tokenized block data
|
# send block data (and metadata) to POW module to get tokenized block data
|
||||||
payload = subprocesspow.SubprocessPOW(data, metadata).start()
|
payload = subprocesspow.SubprocessPOW(data, metadata).start()
|
||||||
|
print(payload)
|
||||||
if payload != False: # noqa
|
if payload != False: # noqa
|
||||||
try:
|
try:
|
||||||
retData = onionrstorage.set_data(payload)
|
retData = onionrstorage.set_data(payload)
|
||||||
|
|
|
@ -1,6 +1,28 @@
|
||||||
|
"""Onionr - Private P2P Communication.
|
||||||
|
|
||||||
|
generate a public ed25519 key from a private one
|
||||||
|
"""
|
||||||
from nacl import signing, encoding
|
from nacl import signing, encoding
|
||||||
|
|
||||||
from onionrtypes import UserID, UserIDSecretKey
|
from onionrtypes import UserID, UserIDSecretKey
|
||||||
|
"""
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
def get_pub_key_from_priv(priv_key: UserIDSecretKey, raw_encoding:bool=False)->UserID:
|
This program is distributed in the hope that it will be useful,
|
||||||
return signing.SigningKey(priv_key, encoder=encoding.Base32Encoder).verify_key.encode(encoding.Base32Encoder)
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def get_pub_key_from_priv(priv_key: UserIDSecretKey,
|
||||||
|
raw_encoding: bool = False) -> UserID:
|
||||||
|
return signing.SigningKey(
|
||||||
|
priv_key, encoder=encoding.Base32Encoder).verify_key.encode(
|
||||||
|
encoding.Base32Encoder)
|
||||||
|
|
|
@ -1,27 +1,65 @@
|
||||||
import nacl.signing, nacl.encoding, nacl.pwhash
|
"""Onionr - Private P2P Communication.
|
||||||
|
|
||||||
|
functions to generate ed25519 key pairs
|
||||||
|
"""
|
||||||
|
import nacl.signing
|
||||||
|
import nacl.encoding
|
||||||
|
import nacl.pwhash
|
||||||
|
|
||||||
import onionrexceptions
|
import onionrexceptions
|
||||||
from onionrutils import bytesconverter
|
from onionrutils import bytesconverter
|
||||||
from etc import onionrvalues
|
from etc import onionrvalues
|
||||||
|
"""
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def generate_pub_key():
|
def generate_pub_key():
|
||||||
'''Generate a Ed25519 public key pair, return tuple of base32encoded pubkey, privkey'''
|
"""Generate a Ed25519 public key pair.
|
||||||
|
|
||||||
|
return tuple of base32encoded pubkey, privkey
|
||||||
|
"""
|
||||||
private_key = nacl.signing.SigningKey.generate()
|
private_key = nacl.signing.SigningKey.generate()
|
||||||
public_key = private_key.verify_key.encode(encoder=nacl.encoding.Base32Encoder())
|
public_key = private_key.verify_key.encode(
|
||||||
return (public_key.decode(), private_key.encode(encoder=nacl.encoding.Base32Encoder()).decode())
|
encoder=nacl.encoding.Base32Encoder())
|
||||||
|
return (public_key.decode(), private_key.encode(
|
||||||
|
encoder=nacl.encoding.Base32Encoder()).decode())
|
||||||
|
|
||||||
|
|
||||||
def generate_deterministic(passphrase, bypassCheck=False):
|
def generate_deterministic(passphrase, bypassCheck=False):
|
||||||
'''Generate a Ed25519 public key pair from a phase, not intended for human-generated key'''
|
"""Generate a Ed25519 public key pair from a phase.
|
||||||
|
|
||||||
|
not intended for human-generated key
|
||||||
|
"""
|
||||||
passStrength = onionrvalues.PASSWORD_LENGTH
|
passStrength = onionrvalues.PASSWORD_LENGTH
|
||||||
passphrase = bytesconverter.str_to_bytes(passphrase) # Convert to bytes if not already
|
# Convert to bytes if not already
|
||||||
|
passphrase = bytesconverter.str_to_bytes(passphrase)
|
||||||
# Validate passphrase length
|
# Validate passphrase length
|
||||||
if not bypassCheck:
|
if not bypassCheck:
|
||||||
if len(passphrase) < passStrength:
|
if len(passphrase) < passStrength:
|
||||||
raise onionrexceptions.PasswordStrengthError("Passphase must be at least %s characters" % (passStrength,))
|
raise onionrexceptions.PasswordStrengthError(
|
||||||
|
"Passphase must be at least %s characters" % (passStrength,))
|
||||||
# KDF values
|
# KDF values
|
||||||
kdf = nacl.pwhash.argon2id.kdf
|
kdf = nacl.pwhash.argon2id.kdf
|
||||||
salt = b"U81Q7llrQcdTP0Ux" # Does not need to be secret, but must be 16 bytes
|
# Does not need to be secret, but must be 16 bytes
|
||||||
|
salt = b"U81Q7llrQcdTP0Ux"
|
||||||
ops = nacl.pwhash.argon2id.OPSLIMIT_SENSITIVE
|
ops = nacl.pwhash.argon2id.OPSLIMIT_SENSITIVE
|
||||||
mem = nacl.pwhash.argon2id.MEMLIMIT_SENSITIVE
|
mem = nacl.pwhash.argon2id.MEMLIMIT_SENSITIVE
|
||||||
|
|
||||||
key = kdf(32, passphrase, salt, opslimit=ops, memlimit=mem) # Generate seed for ed25519 key
|
# Generate seed for ed25519 key
|
||||||
|
key = kdf(32, passphrase, salt, opslimit=ops, memlimit=mem)
|
||||||
key = nacl.signing.SigningKey(key)
|
key = nacl.signing.SigningKey(key)
|
||||||
return (key.verify_key.encode(nacl.encoding.Base32Encoder).decode(), key.encode(nacl.encoding.Base32Encoder).decode())
|
return (
|
||||||
|
key.verify_key.encode(nacl.encoding.Base32Encoder).decode(),
|
||||||
|
key.encode(nacl.encoding.Base32Encoder).decode())
|
||||||
|
|
|
@ -8,13 +8,15 @@ import os
|
||||||
from multiprocessing import Pipe, Process
|
from multiprocessing import Pipe, Process
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import secrets
|
||||||
|
|
||||||
import onionrproofs
|
import onionrproofs
|
||||||
|
|
||||||
import ujson as json
|
import ujson as json
|
||||||
|
|
||||||
import logger
|
import logger
|
||||||
import onionrcrypto as crypto
|
|
||||||
from onionrutils import bytesconverter
|
from onionrutils import bytesconverter
|
||||||
|
from onionrcrypto.hashers import sha3_hash
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -111,6 +113,7 @@ class SubprocessPOW:
|
||||||
nonce = 0
|
nonce = 0
|
||||||
data = self.data
|
data = self.data
|
||||||
metadata = self.metadata
|
metadata = self.metadata
|
||||||
|
metadata['nonce'] = secrets.randbits(16)
|
||||||
puzzle = self.puzzle
|
puzzle = self.puzzle
|
||||||
difficulty = self.difficulty
|
difficulty = self.difficulty
|
||||||
|
|
||||||
|
@ -127,7 +130,7 @@ class SubprocessPOW:
|
||||||
payload = json.dumps(metadata).encode() + b'\n' + data
|
payload = json.dumps(metadata).encode() + b'\n' + data
|
||||||
# Check sha3_256 hash of block, compare to puzzle
|
# Check sha3_256 hash of block, compare to puzzle
|
||||||
# Send payload if puzzle finished
|
# Send payload if puzzle finished
|
||||||
token = crypto.hashers.sha3_hash(payload)
|
token = sha3_hash(payload)
|
||||||
# ensure token is string
|
# ensure token is string
|
||||||
token = bytesconverter.bytes_to_str(token)
|
token = bytesconverter.bytes_to_str(token)
|
||||||
if puzzle == token[0:difficulty]:
|
if puzzle == token[0:difficulty]:
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
'''
|
"""Onionr - Private P2P Communication.
|
||||||
Onionr - Private P2P Communication
|
|
||||||
|
|
||||||
import new blocks from disk, providing transport agnosticism
|
import new blocks from disk, providing transport agnosticism
|
||||||
'''
|
"""
|
||||||
'''
|
import glob
|
||||||
|
|
||||||
|
import logger
|
||||||
|
from onionrutils import blockmetadata
|
||||||
|
from coredb import blockmetadb
|
||||||
|
import filepaths
|
||||||
|
import onionrcrypto as crypto
|
||||||
|
from etc.onionrvalues import BLOCK_EXPORT_FILE_EXT
|
||||||
|
"""
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
@ -16,18 +23,11 @@
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
'''
|
"""
|
||||||
import glob
|
|
||||||
import logger
|
|
||||||
from onionrutils import blockmetadata
|
|
||||||
from coredb import blockmetadb
|
|
||||||
import filepaths
|
|
||||||
import onionrcrypto as crypto
|
|
||||||
from etc.onionrvalues import BLOCK_EXPORT_FILE_EXT
|
|
||||||
def import_new_blocks(scanDir=''):
|
def import_new_blocks(scanDir=''):
|
||||||
'''
|
"""Scan for new blocks ON THE DISK and import them"""
|
||||||
This function is intended to scan for new blocks ON THE DISK and import them
|
|
||||||
'''
|
|
||||||
blockList = blockmetadb.get_block_list()
|
blockList = blockmetadb.get_block_list()
|
||||||
exist = False
|
exist = False
|
||||||
if scanDir == '':
|
if scanDir == '':
|
||||||
|
@ -35,18 +35,26 @@ def import_new_blocks(scanDir=''):
|
||||||
if not scanDir.endswith('/'):
|
if not scanDir.endswith('/'):
|
||||||
scanDir += '/'
|
scanDir += '/'
|
||||||
for block in glob.glob(scanDir + "*%s" % (BLOCK_EXPORT_FILE_EXT,)):
|
for block in glob.glob(scanDir + "*%s" % (BLOCK_EXPORT_FILE_EXT,)):
|
||||||
if block.replace(scanDir, '').replace(BLOCK_EXPORT_FILE_EXT, '') not in blockList:
|
if block.replace(scanDir, '').replace(BLOCK_EXPORT_FILE_EXT, '') \
|
||||||
|
not in blockList:
|
||||||
exist = True
|
exist = True
|
||||||
logger.info('Found new block on dist %s' % block, terminal=True)
|
logger.info('Found new block on dist %s' % block, terminal=True)
|
||||||
with open(block, 'rb') as newBlock:
|
with open(block, 'rb') as newBlock:
|
||||||
block = block.replace(scanDir, '').replace(BLOCK_EXPORT_FILE_EXT, '')
|
block = block.replace(scanDir, '').replace(
|
||||||
if crypto.hashers.sha3_hash(newBlock.read()) == block.replace(BLOCK_EXPORT_FILE_EXT, ''):
|
BLOCK_EXPORT_FILE_EXT, '')
|
||||||
blockmetadb.add_to_block_DB(block.replace(BLOCK_EXPORT_FILE_EXT, ''), dataSaved=True)
|
if crypto.hashers.sha3_hash(newBlock.read()) == block.replace(
|
||||||
|
BLOCK_EXPORT_FILE_EXT, ''):
|
||||||
|
blockmetadb.add_to_block_DB(block.replace(
|
||||||
|
BLOCK_EXPORT_FILE_EXT, ''), dataSaved=True)
|
||||||
logger.info('Imported block %s' % block, terminal=True)
|
logger.info('Imported block %s' % block, terminal=True)
|
||||||
blockmetadata.process_block_metadata(block)
|
blockmetadata.process_block_metadata(block)
|
||||||
else:
|
else:
|
||||||
logger.warn('Failed to verify hash for %s' % block, terminal=True)
|
logger.warn('Failed to verify hash for %s' % block,
|
||||||
|
terminal=True)
|
||||||
if not exist:
|
if not exist:
|
||||||
logger.info('No blocks found to import', terminal=True)
|
logger.info('No blocks found to import', terminal=True)
|
||||||
|
|
||||||
import_new_blocks.onionr_help = f"Scans the Onionr data directory under {filepaths.block_data_location} for new block files (.db not supported) to import"
|
|
||||||
|
import_new_blocks.onionr_help = \
|
||||||
|
f"Scan the Onionr data directory under {filepaths.block_data_location}" + \
|
||||||
|
"for new block files (.db not supported) to import"
|
||||||
|
|
Loading…
Reference in New Issue