From da11c74f6c76f9547628649ac106fe2a36b16aeb Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Sun, 25 Oct 2020 04:12:42 +0000 Subject: [PATCH] finished closeness measurement --- scripts/generate-onions.py | 9 +++- src/onionrtypes/__init__.py | 2 + src/streamfill/__init__.py | 3 +- src/streamfill/extracted25519.py | 2 +- src/streamfill/neighbors.py | 21 ++++++---- tests/test_streamfill_neighbors.py | 66 ++++++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 11 deletions(-) mode change 100644 => 100755 scripts/generate-onions.py create mode 100644 tests/test_streamfill_neighbors.py diff --git a/scripts/generate-onions.py b/scripts/generate-onions.py old mode 100644 new mode 100755 index d3d4d1bd..65991604 --- a/scripts/generate-onions.py +++ b/scripts/generate-onions.py @@ -9,6 +9,11 @@ if not os.path.exists('onionr.sh'): os.chdir('../') sys.path.append("src/") +try: + sys.argv[1] +except IndexError: + sys.exit(1) + tor_process = process.launch_tor_with_config( completion_percent=0, config = { @@ -23,13 +28,13 @@ tor_process = process.launch_tor_with_config( with Controller.from_port('127.0.0.1', 2778) as controller: controller.authenticate() - for i in range(1024, 2000): + for i in range(1024, 1024 + int(sys.argv[1])): hs = controller.create_ephemeral_hidden_service( {80: i}, key_type='NEW', key_content='ED25519-V3', await_publication=False, detached=True) - print(hs.service_id) + print(hs.service_id + ".onion") tor_process.kill() \ No newline at end of file diff --git a/src/onionrtypes/__init__.py b/src/onionrtypes/__init__.py index afd0f7ee..6ee9a6d7 100644 --- a/src/onionrtypes/__init__.py +++ b/src/onionrtypes/__init__.py @@ -8,6 +8,8 @@ LoopBackIP = NewType('LoopBackIP', str) DeterministicKeyPassphrase = NewType('DeterministicKeyPassphrase', str) +Ed25519PublicKeyBytes = NewType('Ed25519PublicKeyBytes', bytes) + BlockHash = NewType('BlockHash', str) OnboardingConfig = NewType('OnboardingConfig', str) diff --git a/src/streamfill/__init__.py b/src/streamfill/__init__.py index 565d5ed4..1142cf4b 100644 --- a/src/streamfill/__init__.py +++ b/src/streamfill/__init__.py @@ -1 +1,2 @@ -from .extracted25519 import extract_ed25519_from_onion_address \ No newline at end of file +from .extracted25519 import extract_ed25519_from_onion_address +from .neighbors import identify_neighbors \ No newline at end of file diff --git a/src/streamfill/extracted25519.py b/src/streamfill/extracted25519.py index 67844f36..8b9ab5c7 100644 --- a/src/streamfill/extracted25519.py +++ b/src/streamfill/extracted25519.py @@ -8,7 +8,7 @@ if TYPE_CHECKING: def extract_ed25519_from_onion_address( - address: OnionAddressString) -> Ed25519PublicKeyBytes: + address: 'OnionAddressString') -> 'Ed25519PublicKeyBytes': address = str_to_bytes(address).replace(b'.onion', b'').upper() ed25519 = b32decode(address)[:-3] return ed25519 \ No newline at end of file diff --git a/src/streamfill/neighbors.py b/src/streamfill/neighbors.py index ed36622a..39285cab 100644 --- a/src/streamfill/neighbors.py +++ b/src/streamfill/neighbors.py @@ -1,5 +1,8 @@ from onionrtypes import OnionAddressString from typing import Iterable + +from collections import OrderedDict + from .extracted25519 import extract_ed25519_from_onion_address @@ -12,11 +15,15 @@ def identify_neighbors( address_int = int.from_bytes(address, "big") def _calc_closeness(y): - return abs(address_int - int.from_bytes(y, "big")) - - - peer_ed_keys = list(map(extract_ed25519_from_onion_address, peers)) - differences = list(map(_calc_closeness, peer_ed_keys)) - - return sorted(differences)[:closest_n] + return abs(address_int - int.from_bytes(extract_ed25519_from_onion_address(y), "big")) + closeness_values = [] + end_result = [] + for peer in peers: + closeness_values.append((peer, _calc_closeness(peer))) + closeness_values.sort() + for i, result in enumerate(closeness_values): + if i > closest_n: + break + end_result.append(result[0]) + return end_result diff --git a/tests/test_streamfill_neighbors.py b/tests/test_streamfill_neighbors.py new file mode 100644 index 00000000..5f33abb5 --- /dev/null +++ b/tests/test_streamfill_neighbors.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +import sys, os +import subprocess +sys.path.append(".") +sys.path.append("src/") +import uuid +import binascii +from base64 import b32decode +TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/' +print("Test directory:", TEST_DIR) +os.environ["ONIONR_HOME"] = TEST_DIR +import unittest + +from streamfill import identify_neighbors, extract_ed25519_from_onion_address + +class TestStreamfillNeighbors(unittest.TestCase): + def test_neighbor_closeness_consistent(self): + onions = [] + # p = subprocess.Popen(["scripts/generate-onions.py", '5'], + # stdout=subprocess.PIPE, + # stderr=subprocess.PIPE) + # for line in iter(p.stdout.readline, b''): + # line = line.decode() + # onions.append(line.strip()) + main = '7uifxsgidchopmdwmtip6x4ydra6cpf2ov4ghj2lzx5uydyssduh5qid.onion' + others = ['bxxajpimlonmbxb5jzjre3go3dvfobqyayqwpksd6zpjz4s4mknstwyd.onion', '2zofaifd6s3flwbv5wl4vtgnesbprc4f2ptljl4a47dfkvrbmw3e5iqd.onion', '6umslj7jtzu27n4jgf3byn55ztz5mkoqocx32zwjya6rbnxqjpyysyyd.onion'] + main_num = int.from_bytes(extract_ed25519_from_onion_address(main), 'big') + + test_data = identify_neighbors(main, others, 3) + + my_result = [] + for i in others: + my_result.append((i, abs(main_num - int.from_bytes(extract_ed25519_from_onion_address(i), 'big')))) + my_result.sort() + final = [] + for i in my_result: + final.append(i[0]) + self.assertTrue(len(test_data) == 3) + self.assertListEqual(test_data, final) + + def test_neighbor_closeness_random(self): + onions = [] + p = subprocess.Popen(["scripts/generate-onions.py", '100'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + for line in iter(p.stdout.readline, b''): + line = line.decode() + onions.append(line.strip()) + p.terminate() + main = '7uifxsgidchopmdwmtip6x4ydra6cpf2ov4ghj2lzx5uydyssduh5qid.onion' + main_num = int.from_bytes(extract_ed25519_from_onion_address(main), 'big') + + test_data = identify_neighbors(main, onions, 100) + + my_result = [] + for i in onions: + my_result.append((i, abs(main_num - int.from_bytes(extract_ed25519_from_onion_address(i), 'big')))) + my_result.sort() + final = [] + for i in my_result: + final.append(i[0]) + self.assertTrue(len(test_data) == 100) + self.assertListEqual(test_data, final) + + +unittest.main()