示例#1
0
	def begin_announcement_phase(self):
		"""Begins the announcement phase."""
		sprint(self.name, 'Beginning announcement phase...')
		self.phase = Constants.ANNOUNCEMENT_PHASE

		# shuffle list of servers
		random.shuffle(self.servers)

		# update servers and neighbors
		self.servers_ready = 0
		self.broadcast_neighbors()

		# pause before beginning announcement phase
		while self.servers_ready != self.num_servers:
			time.sleep(0.01)

		server_addr = self.servers[0]

		# get ciphertexts (secret, encrypted reputation)
		secret, reputation = sendrecv(server_addr, [Constants.GET_CIPHERTEXTS])

		clients = []
		for server_addr in self.servers:
			clients.extend(sendrecv(server_addr, [Constants.GET_CLIENTS]))

		for server_addr in self.servers:
			sendrecv(server_addr,
				[Constants.UPDATE_CLIENTS, secret, reputation, clients])

		send(self.servers[0], [Constants.NEW_ANNOUNCEMENT,
				Constants.G, [], [], 0, 0, Constants.INIT_ID])
示例#2
0
    def lrs_sign(self, msg):
        """Sign for LRS."""
        generator = sendrecv(self.server_addr, [Constants.GET_GENERATOR])
        stp_array = sendrecv(self.server_addr, [Constants.GET_STP_ARRAY])
        stp = powm(generator, self.pri_key)
        stp_idx = stp_array.index(stp)

        # modify stp_array to prevent duplicate voting
        stp_array.append(msg_hash(msg, sha1))

        return lrs.sign(msg, self.pri_key, stp_idx, stp_array, g=generator)
示例#3
0
    def __init__(self, server_host, server_port, private_key=None):
        self.name = 'CLIENT'

        # core variables
        self.pri_key = randkey() if private_key is None else private_key
        self.pub_key = powm(Constants.G, self.pri_key)

        # socket variables
        self.server_addr = (server_host, server_port)

        # new client
        sendrecv(self.server_addr, [Constants.NEW_CLIENT, self.pub_key])
示例#4
0
    def post(self, msg):
        """Post a message."""
        generator = sendrecv(self.server_addr, [Constants.GET_GENERATOR])

        stp = powm(generator, self.pri_key)
        sig = self.sign(msg, generator)

        send(self.server_addr, [Constants.NEW_MESSAGE, msg, stp, sig])
示例#5
0
    def lrs_sign(self, msg):
        """Sign for LRS."""
        ltp_array = sendrecv(self.server_addr, [Constants.GET_LTP_ARRAY])
        ltp_idx = ltp_array.index(self.pub_key)

        # modify stp_array to prevent duplicate voting
        ltp_array.append(msg_hash(msg, sha1))

        return lrs.sign(msg, self.pri_key, ltp_idx, ltp_array)
示例#6
0
    def vote(self, amount, msg_id):
        """Vote on a message."""
        messages = sendrecv(config.COORDINATOR_ADDR, [Constants.DISP_BOARD])

        # verify message id
        if msg_id < 0 or msg_id >= len(messages):
            eprint(self.name, 'Invalid message id.')
            return False

        msg = messages[msg_id][1][Constants.MSG]
        sig = self.lrs_sign(msg)

        response = sendrecv(self.server_addr,
                            [Constants.NEW_FEEDBACK, msg_id, msg, amount, sig])
        if response[0] == Constants.FAIL:
            eprint(self.name, response[1])
            return False
        else:
            return True
示例#7
0
    def __init__(self, server_host, server_port):
        self.contract_address = sendrecv(config.COORDINATOR_ADDR,
                                         [Constants.GET_CONTRACT_ADDRESS])
        self.blockchain = bc.LocalBlockchain()
        self.blockchain.connect_to_contract('reputation.sol',
                                            self.contract_address)
        self.wallets = []
        self.listening = False

        self.respond = {
            Constants.PARTICIPATION_STATUS: self.give_keys,
            Constants.KEYS: self.get_keys,
        }

        self.msg_types = {
            Constants.PARTICIPATION_STATUS: [int],
            Constants.KEYS: [list, list],
        }

        assert set(self.respond.keys()) == set(self.msg_types.keys())

        super().__init__(server_host, server_port)
示例#8
0
 def get_message_board(self):
     return sendrecv(config.COORDINATOR_ADDR, [Constants.DISP_BOARD])
示例#9
0
    if len(sys.argv) != 3:
        print('USAGE: python client_blockchain.py server_host server_port')
        sys.exit(1)

    client_host = sys.argv[1]
    client_port = int(sys.argv[2])
    c = BlockchainClient(client_host, client_port)
    c.show_help()

    while True:
        try:
            s = input('> ').strip().upper()
            if s == 'HELP':
                c.show_help()
            elif s == 'SHOW':
                messages = sendrecv(config.COORDINATOR_ADDR,
                                    [Constants.DISP_BOARD])
                pprint.PrettyPrinter(indent=4).pprint(messages)
            elif s == 'GET REP':
                print('Your reputation is: {}'.format(
                    sum(
                        c.blockchain.get_reputation(x.address)
                        for x in c.wallets)))
            elif re.match("^WRITE \d+$", s) is not None:
                msg = input('Write message here: ')
                c.post(msg, int(s.split()[-1]))
                pass
            elif re.match("^VOTE UP \d+$", s) is not None:
                c.vote(1, int(s.split()[-1]))
                pass
            elif re.match("^VOTE DOWN \d+$", s) is not None:
                c.vote(-1, int(s.split()[-1]))
示例#10
0
    def start_coinshuffle(self):
        """Begins Coinshuffle phase."""
        sprint(self.name, 'Beginning CoinShuffle phase...')
        # Commits all the changes in reputation to the blockchain.
        promises = []
        for i in range(self.message_marker, len(self.board)):
            addresses = self.board[i][1][Constants.REP]
            net_fb = (self.board[i][1][Constants.FB][0] +
                      self.board[i][1][Constants.FB][1])
            if net_fb > 0:
                promises.append(
                    self.blockchain.add_reputation(addresses[0], net_fb))
            elif net_fb < 0:
                to_remove = -net_fb
                for address in addresses:
                    can_remove = min(to_remove,
                                     self.blockchain.get_reputation(address))
                    promises.append(
                        self.blockchain.remove_reputation(address, can_remove))
                    to_remove -= can_remove
                    if to_remove <= 0:
                        break

        for promise in promises:
            promise.resolve()

        # reset used_wallets
        self.used_wallets = set()

        self.coordinator.phase = Constants.COINSHUFFLE_PHASE
        # contains a list of (wallet, balance_of_wallet) that need to be transfered
        # to another wallet
        self.spending_wallets = []
        self.spending_wallets_total = 0

        # determine which clients should participate in the coinshuffle
        final_balances = defaultdict(int)
        for i in range(self.message_marker, len(self.board)):
            addr = self.msg_id_to_addr[i]

            # check if this user has > 0 reputation
            for wallet in self.board[i][1][Constants.REP]:
                balance = self.blockchain.get_reputation(wallet)
                final_balances[addr] += balance
                if balance > 0:
                    self.spending_wallets.append((wallet, balance))
                    self.spending_wallets_total += balance

        # let all clients know whether they are participating in the shuffle or not.
        participants = []
        for addr, balance in final_balances.items():
            if balance > 0:
                encryption_key = sendrecv(
                    addr, [Constants.PARTICIPATION_STATUS, balance])
                participants.append((addr, encryption_key))
            else:
                send(addr, [Constants.PARTICIPATION_STATUS, balance])

        # iterate over participants and send them the encyption keys that
        # they need, get ack.
        e_keys = []
        for i, (addr, e_key) in enumerate(reversed(participants)):
            if i == 0:
                next_addr = self.coordinator.addr
            else:
                next_addr = participants[len(participants) - i][0]
            # send participants encryption keys next hop in the ring
            sendrecv(addr, [Constants.KEYS, next_addr, e_keys])
            e_keys.append(e_key)

        # start the shuffling
        if len(participants) == 0:
            self.coordinator.phase = Constants.COINSHUFFLE_FINISHED_PHASE
            return
        sendbytes(participants[0][0], b'')