def test_encrypt_decrypt(): msg = b"test yeah" privkey = ecies.generate_privkey() ciphertext = ecies.encrypt(msg, privkey.public_key) decrypted = ecies.decrypt(ciphertext, privkey) assert decrypted == msg privkey2 = ecies.generate_privkey() with pytest.raises(ecies.DecryptionError): decrypted = ecies.decrypt(ciphertext, privkey2)
def test_submit_work_with_guardian(self): now = 42 doublesha = ConsensusType.POW_DOUBLESHA256 block = RootBlock( RootBlockHeader(create_time=42, extra_data=b"{}", difficulty=1000)) priv = ecies.generate_privkey() async def create(retry=True): return block async def add(block_to_add): h = block_to_add.header diff = h.difficulty if h.verify_signature(priv.public_key): diff = Guardian.adjust_difficulty(diff, h.height) validate_seal(block_to_add.header, doublesha, adjusted_diff=diff) miner = self.miner_gen(doublesha, create, add, remote=True, guardian_private_key=priv) async def go(): for i in range(42, 100): work, _ = await miner.get_work(now=now) self.assertEqual(work.height, 0) # guardian: diff 1000 -> 1, any number should work res = await miner.submit_work(work.hash, i, sha3_256(b"")) self.assertTrue(res) loop = asyncio.get_event_loop() loop.run_until_complete(go())
def test_submit_work_with_guardian(self): now = 42 block = RootBlock( RootBlockHeader(create_time=42, extra_data=b"{}", difficulty=1000)) async def create(retry=True): return block async def add(_): pass miner = self.miner_gen( ConsensusType.POW_SHA3SHA3, create, add, remote=True, # fake pk, will succeed in test but fail in real world when # adding the block to the root chain guardian_private_key=ecies.generate_privkey(), ) async def go(): for i in range(42, 100): work = await miner.get_work(now=now) self.assertEqual(work.height, 0) # guardian: diff 1000 -> 1, any number should work res = await miner.submit_work(work.hash, i, sha3_256(b"")) self.assertTrue(res) loop = asyncio.get_event_loop() loop.run_until_complete(go())
def __init__(self, env, master_server, loop): self.loop = loop self.env = env self.master_server = master_server master_server.network = self # cannot say this is a good design self.cancel_token = CancelToken("p2pserver") if env.cluster_config.P2P.BOOT_NODES: bootstrap_nodes = env.cluster_config.P2P.BOOT_NODES.split(",") else: bootstrap_nodes = [] if env.cluster_config.P2P.PRIV_KEY: privkey = keys.PrivateKey(bytes.fromhex(env.cluster_config.P2P.PRIV_KEY)) else: privkey = ecies.generate_privkey() self.server = QuarkServer( privkey=privkey, port=env.cluster_config.P2P_PORT, network_id=env.cluster_config.P2P.NETWORK_ID, bootstrap_nodes=tuple( [kademlia.Node.from_uri(enode) for enode in bootstrap_nodes] ), token=self.cancel_token, upnp=env.cluster_config.P2P.UPNP, )
def main(): parser = argparse.ArgumentParser() parser.add_argument( "--bootnode", default= "enode://c571e0db93d17cc405cb57640826b70588a6a28785f38b21be471c609ca12fcb06cb306ac44872908f5bed99046031a5af82072d484e3ef9029560c1707193a0@127.0.0.1:29000", type=str, ) parser.add_argument( "--privkey", default= "31552f186bf90908ce386fb547dd0410bf443309125cc43fd0ffd642959bf6d9", help="hex string of private key; if empty, will be auto-generated", type=str, ) parser.add_argument( "--listen_port", default=29000, help="port for discovery UDP and P2P TCP connection", type=int, ) parser.add_argument("--max_peers", default=10, type=int) parser.add_argument("--logging_level", default="info", type=str) parser.add_argument( "--upnp", default=False, action="store_true", help= "if set, will automatically set up port-fowarding if upnp devices that support port forwarding can be found", ) args = parser.parse_args() Logger.set_logging_level(args.logging_level) if args.privkey: privkey = keys.PrivateKey(bytes.fromhex(args.privkey)) else: privkey = ecies.generate_privkey() cancel_token = CancelToken("server") server = ParagonServer( privkey=privkey, port=args.listen_port, network_id=NETWORK_ID, bootstrap_nodes=tuple([kademlia.Node.from_uri(args.bootnode)]), token=cancel_token, upnp=args.upnp, ) loop = asyncio.get_event_loop() # loop.set_debug(True) for sig in [signal.SIGINT, signal.SIGTERM]: loop.add_signal_handler(sig, cancel_token.trigger) loop.run_until_complete(server.run()) loop.run_until_complete(server.cancel()) loop.close()
def main(): Logger.set_logging_level("debug") loop = asyncio.get_event_loop() loop.set_debug(True) parser = argparse.ArgumentParser() parser.add_argument( "--bootnode", default="enode://c571e0db93d17cc405cb57640826b70588a6a28785f38b21be471c609ca12fcb06cb306ac44872908f5bed99046031a5af82072d484e3ef9029560c1707193a0@127.0.0.1:29000", type=str, ) parser.add_argument("--listen_host", default="127.0.0.1", type=str) parser.add_argument( "--listen_port", default=29000, help="port for discovery UDP and P2P TCP connection", type=int, ) parser.add_argument("--max_peers", default=10, type=int) # private key of the bootnode above is 31552f186bf90908ce386fb547dd0410bf443309125cc43fd0ffd642959bf6d9 parser.add_argument( "--privkey", default="", help="hex string of private key; if empty, will be auto-generated", type=str, ) args = parser.parse_args() if args.privkey: privkey = keys.PrivateKey(bytes.fromhex(args.privkey)) else: privkey = ecies.generate_privkey() addr = kademlia.Address(args.listen_host, args.listen_port, args.listen_port) bootstrap_nodes = tuple([kademlia.Node.from_uri(args.bootnode)]) cancel_token = CancelToken("discovery") discovery = DiscoveryProtocol(privkey, addr, bootstrap_nodes, cancel_token) async def run() -> None: await loop.create_datagram_endpoint( lambda: discovery, local_addr=("0.0.0.0", args.listen_port) ) try: await discovery.bootstrap() while True: Logger.info("Routing table size={}".format(len(discovery.routing))) await cancel_token.cancellable_wait(asyncio.sleep(5)) except OperationCancelled: pass finally: await discovery.stop() for sig in [signal.SIGINT, signal.SIGTERM]: loop.add_signal_handler(sig, cancel_token.trigger) loop.run_until_complete(run()) loop.close()
def __init__( self, remote: kademlia.Node, privkey: datatypes.PrivateKey, use_eip8: bool, token: CancelToken, ) -> None: self.remote = remote self.privkey = privkey self.ephemeral_privkey = ecies.generate_privkey() self.use_eip8 = use_eip8 self.cancel_token = token
def __init__(self, env, master_server, loop): self.loop = loop self.env = env self.master_server = master_server master_server.network = self # cannot say this is a good design self.cancel_token = CancelToken("p2pserver") if env.cluster_config.P2P.BOOT_NODES: bootstrap_nodes = env.cluster_config.P2P.BOOT_NODES.split(",") else: bootstrap_nodes = [] if env.cluster_config.P2P.PRIV_KEY: privkey = keys.PrivateKey( bytes.fromhex(env.cluster_config.P2P.PRIV_KEY)) else: privkey = ecies.generate_privkey() if env.cluster_config.P2P.PREFERRED_NODES: preferred_nodes = env.cluster_config.P2P.PREFERRED_NODES.split(",") else: preferred_nodes = [] if len(str(env.quark_chain_config.NETWORK_ID)) > 4: raise Exception("NETWORK_ID too long for discovery") self.server = QuarkServer( privkey=privkey, port=env.cluster_config.P2P_PORT, network_id=env.quark_chain_config.NETWORK_ID, bootstrap_nodes=tuple( [Node.from_uri(enode) for enode in bootstrap_nodes]), preferred_nodes=[ Node.from_uri(enode) for enode in preferred_nodes ], token=self.cancel_token, max_peers=env.cluster_config.P2P.MAX_PEERS, upnp=env.cluster_config.P2P.UPNP, allow_dial_in_ratio=env.cluster_config.P2P.ALLOW_DIAL_IN_RATIO, crawling_routing_table_path=env.cluster_config.P2P. CRAWLING_ROUTING_TABLE_FILE_PATH, ) QuarkPeer.env = env SecurePeer.env = env SecurePeer.network = self SecurePeer.master_server = master_server # used in HelloCommand.peer_id which is hash256 self.self_id = privkey.public_key.to_bytes()[:32] self.ip = ipaddress.ip_address( socket.gethostbyname(socket.gethostname())) self.port = env.cluster_config.P2P_PORT
def test_submit_work_with_remote_guardian(self): now = 42 doublesha = ConsensusType.POW_DOUBLESHA256 block = RootBlock( RootBlockHeader( create_time=42, extra_data=b"{}", difficulty=1000, hash_prev_block=RootBlockHeader().get_hash(), )) priv = ecies.generate_privkey() async def create(coinbase_addr=None, retry=True): return block async def add(block_to_add): h = block_to_add.header diff = h.difficulty if h.verify_signature(priv.public_key): diff = Guardian.adjust_difficulty(diff, h.height) validate_seal(block_to_add.header, doublesha, adjusted_diff=diff) # just with the guardian public key miner = self.miner_gen(doublesha, create, add, remote=True) async def go(): for i in range(42, 100): work, _ = await miner.get_work(EMPTY_ADDR, now=now) self.assertEqual(work.height, 0) # remote guardian: diff 1000 -> 1, any number should work # mimic the sign process of the remote guardian server block.header.nonce = i block.header.mixhash = sha3_256(b"") block.header.sign_with_private_key(priv) signature = block.header.signature # reset the signature to the default value block.header.signature = bytes(65) # submit the signature through the submit work res = await miner.submit_work(work.hash, i, sha3_256(b""), signature) self.assertTrue(res) res = await miner.submit_work(work.hash, i, sha3_256(b""), bytes(65)) self.assertFalse(res) loop = asyncio.get_event_loop() loop.run_until_complete(go())
def main(): privkey = ecies.generate_privkey() print( "Here is a new SECP256K1 private key, please keep it in a safe place:") print("*" * 50) print(privkey.to_bytes().hex()) print("*" * 50) print("You can pass it to --privkey when running cluster.py") print( "If you want to use the key for bootnode, here is what you want others to use (replace IP/PORT):" ) print("*" * 50) print("enode://{}@IP:PORT".format(privkey.public_key.to_bytes().hex())) print("*" * 50)
def main(): parser = argparse.ArgumentParser() parser.add_argument( "--privkey", default="", help="hex string of private key; if empty, will be auto-generated", type=str, ) parser.add_argument( "--listen_port", default=29000, help="port for discovery UDP and P2P TCP connection", type=int, ) parser.add_argument("--logging_level", default="info", type=str) args = parser.parse_args() Logger.set_logging_level(args.logging_level) if args.privkey: privkey = keys.PrivateKey(bytes.fromhex(args.privkey)) else: privkey = ecies.generate_privkey() cancel_token = CancelToken("server") server = ParagonServer( privkey=privkey, port=args.listen_port, network_id=NETWORK_ID, token=cancel_token, ) loop = asyncio.get_event_loop() loop.set_debug(True) for sig in [signal.SIGINT, signal.SIGTERM]: loop.add_signal_handler(sig, cancel_token.trigger) loop.run_until_complete(server.run()) loop.run_until_complete(server.cancel()) loop.close()
def get_quark_peer_factory(): privkey = ecies.generate_privkey() server = QuarkServer(privkey=privkey, port=38291, network_id=0) return server.peer_pool.get_peer_factory()
async def get_directly_linked_peers_without_handshake( alice_factory: BasePeerFactory = None, bob_factory: BasePeerFactory = None ) -> Tuple[BasePeer, BasePeer]: """ See get_directly_linked_peers(). Neither the P2P handshake nor the sub-protocol handshake will be performed here. """ cancel_token = CancelToken("get_directly_linked_peers_without_handshake") if alice_factory is None: alice_factory = ParagonPeerFactory( privkey=ecies.generate_privkey(), context=ParagonContext(), token=cancel_token, listen_port=30303, ) if bob_factory is None: bob_factory = ParagonPeerFactory( privkey=ecies.generate_privkey(), context=ParagonContext(), token=cancel_token, listen_port=30303, ) alice_private_key = alice_factory.privkey bob_private_key = bob_factory.privkey alice_remote = kademlia.Node( bob_private_key.public_key, kademlia.Address("0.0.0.0", 0, 0) ) bob_remote = kademlia.Node( alice_private_key.public_key, kademlia.Address("0.0.0.0", 0, 0) ) use_eip8 = False initiator = auth.HandshakeInitiator( alice_remote, alice_private_key, use_eip8, cancel_token ) f_alice = asyncio.Future() # : 'asyncio.Future[BasePeer]' handshake_finished = asyncio.Event() ( (alice_reader, alice_writer), (bob_reader, bob_writer), ) = get_directly_connected_streams() async def do_handshake() -> None: aes_secret, mac_secret, egress_mac, ingress_mac = await auth._handshake( initiator, alice_reader, alice_writer, cancel_token ) connection = PeerConnection( reader=alice_reader, writer=alice_writer, aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac, ingress_mac=ingress_mac, ) alice = alice_factory.create_peer(alice_remote, connection) f_alice.set_result(alice) handshake_finished.set() asyncio.ensure_future(do_handshake()) use_eip8 = False responder = auth.HandshakeResponder( bob_remote, bob_private_key, use_eip8, cancel_token ) auth_cipher = await bob_reader.read(constants.ENCRYPTED_AUTH_MSG_LEN) initiator_ephemeral_pubkey, initiator_nonce, _ = decode_authentication( auth_cipher, bob_private_key ) responder_nonce = keccak(os.urandom(constants.HASH_LEN)) auth_ack_msg = responder.create_auth_ack_message(responder_nonce) auth_ack_ciphertext = responder.encrypt_auth_ack_message(auth_ack_msg) bob_writer.write(auth_ack_ciphertext) await handshake_finished.wait() alice = await f_alice aes_secret, mac_secret, egress_mac, ingress_mac = responder.derive_secrets( initiator_nonce, responder_nonce, initiator_ephemeral_pubkey, auth_cipher, auth_ack_ciphertext, ) assert egress_mac.digest() == alice.ingress_mac.digest() assert ingress_mac.digest() == alice.egress_mac.digest() connection = PeerConnection( reader=bob_reader, writer=bob_writer, aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac, ingress_mac=ingress_mac, ) bob = bob_factory.create_peer(bob_remote, connection) return alice, bob