diff --git a/onionr/communicator.py b/onionr/communicator.py index 673668bc..03ed35c5 100755 --- a/onionr/communicator.py +++ b/onionr/communicator.py @@ -19,7 +19,7 @@ and code to operate as a daemon, getting commands from the command queue databas You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import sqlite3, requests, hmac, hashlib, time, sys, os, math, logger, urllib.parse, random, base64, binascii +import sqlite3, requests, hmac, hashlib, time, sys, os, math, logger, urllib.parse, base64, binascii, secrets import core, onionrutils, onionrcrypto, netcontroller, onionrproofs, btc, config, onionrplugins as plugins class OnionrCommunicate: @@ -149,7 +149,7 @@ class OnionrCommunicate: peersCheck = len(peerList) while peersCheck > peersChecked: - i = random.randint(0, maxN) + i = secrets.randbelow(maxN) logger.info('Using ' + peerList[i] + ' to find new peers', timestamp=True) try: newAdders = self.performGet('pex', peerList[i], skipHighFailureAddress=True) @@ -260,7 +260,7 @@ class OnionrCommunicate: blocks = '' for i in peerList: hasher = hashlib.sha3_256() - data = self.performGet('getData', i, hash) + data = self.performGet('getData', i, hash, skipHighFailureAddress=True) if data == False or len(data) > 10000000 or data == '': continue try: diff --git a/onionr/core.py b/onionr/core.py index 9ad4f47f..1ac22426 100644 --- a/onionr/core.py +++ b/onionr/core.py @@ -221,12 +221,14 @@ class Core: ''' Create a database for blocks - hash - the hash of a block + hash - the hash of a block dateReceived - the date the block was recieved, not necessarily when it was created - decrypted - if we can successfully decrypt the block (does not describe its current state) - dataType - data type of the block - dataFound - if the data has been found for the block - dataSaved - if the data has been saved for the block + decrypted - if we can successfully decrypt the block (does not describe its current state) + dataType - data type of the block + dataFound - if the data has been found for the block + dataSaved - if the data has been saved for the block + signature - optional signature by the author (not optional if author is specified) + author - multi-round partial scrypt hash of authors public key ''' if os.path.exists(self.blockDB): raise Exception("Block database already exists") @@ -238,7 +240,10 @@ class Core: decrypted int, dataType text, dataFound int, - dataSaved int); + dataSaved int, + signature text, + author text, + ); ''') conn.commit() conn.close() @@ -584,15 +589,19 @@ class Core: return - def insertBlock(self, data, header='txt'): + def insertBlock(self, data, header='txt', sign=False): ''' Inserts a block into the network ''' retData = '' + metadata = header + if sign: + metadata += '-' + self._crypto.pubKeyHashID() + '-' + metadata += self._crypto.edSign(data, encodeResult=True) + '-' if len(data) == 0: logger.error('Will not insert empty block') else: - addedHash = self.setData('-' + header + '-' + data) + addedHash = self.setData(metadata + data) self.addToBlockDB(addedHash, selfInsert=True) self.setBlockType(addedHash, header) retData = addedHash diff --git a/onionr/onionr.py b/onionr/onionr.py index 54937e0f..164900e3 100755 --- a/onionr/onionr.py +++ b/onionr/onionr.py @@ -576,7 +576,7 @@ class Onionr: except FileNotFoundError: logger.warn('That file does not exist. Improper path?') else: - print(new) + logger.debug(new) self.onionrCore.insertBlock(new, header='bin') diff --git a/onionr/onionrcrypto.py b/onionr/onionrcrypto.py index 00e6d520..5f462b51 100644 --- a/onionr/onionrcrypto.py +++ b/onionr/onionrcrypto.py @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import nacl.signing, nacl.encoding, nacl.public, nacl.secret, os, binascii, base64 +import nacl.signing, nacl.encoding, nacl.public, nacl.secret, os, binascii, base64, hashlib class OnionrCrypto: def __init__(self, coreInstance): @@ -25,6 +25,8 @@ class OnionrCrypto: self._keyFile = 'data/keys.txt' self.pubKey = None self.privKey = None + + self.HASH_ID_ROUNDS = 2000 # Load our own pub/priv Ed25519 keys, gen & save them if they don't exist if os.path.exists(self._keyFile): @@ -170,4 +172,15 @@ class OnionrCrypto: '''Generate a Ed25519 public key pair, return tuple of base32encoded pubkey, privkey''' private_key = nacl.signing.SigningKey.generate() public_key = private_key.verify_key.encode(encoder=nacl.encoding.Base32Encoder()) - return (public_key.decode(), private_key.encode(encoder=nacl.encoding.Base32Encoder()).decode()) \ No newline at end of file + return (public_key.decode(), private_key.encode(encoder=nacl.encoding.Base32Encoder()).decode()) + + def pubKeyHashID(self, pubkey=self.pubKey): + '''Accept a ed25519 public key, return a truncated result of X many sha3_256 hash rounds''' + prev = '' + pubkey = pubkey.encode() + for i in range(self.HASH_ID_ROUNDS): + hasher = hashlib.sha3_256() + hasher.update(pubkey + prev.encode()) + prev = hasher.hexdigest() + result = prev + return result \ No newline at end of file