async def send_message(self, m): # Submit a message to be mixed contract_concise = ConciseContract(self.contract) # Step 1. Wait until there is input available, and enough triples while True: inputmasks_available = contract_concise.inputmasks_available() # logging.infof'inputmasks_available: {inputmasks_available}') if inputmasks_available >= 1: break await asyncio.sleep(5) # Step 2. Reserve the input mask tx_hash = self.contract.functions.reserve_inputmask().transact( {"from": self.w3.eth.accounts[0]} ) tx_receipt = await wait_for_receipt(self.w3, tx_hash) rich_logs = self.contract.events.InputMaskClaimed().processReceipt(tx_receipt) if rich_logs: inputmask_idx = rich_logs[0]["args"]["inputmask_idx"] else: raise ValueError # Step 3. Fetch the input mask from the servers inputmask = await self._get_inputmask(inputmask_idx) message = int.from_bytes(m.encode(), "big") maskedinput = message + inputmask maskedinput_bytes = self.w3.toBytes(hexstr=hex(maskedinput.value)) maskedinput_bytes = maskedinput_bytes.rjust(32, b"\x00") # Step 4. Publish the masked input tx_hash = self.contract.functions.submit_message( inputmask_idx, maskedinput_bytes ).transact({"from": self.w3.eth.accounts[0]}) tx_receipt = await wait_for_receipt(self.w3, tx_hash)
async def _offline_inputmasks_loop(self): contract_concise = ConciseContract(self.contract) n = contract_concise.n() t = contract_concise.t() K = contract_concise.K() # noqa: N806 preproc_round = 0 k = K // (n - 2 * t) # batch size while True: # Step 1b. I) Wait until needed while True: inputmasks_available = contract_concise.inputmasks_available() totalmasks = contract_concise.preprocess()[2] # Policy: try to maintain a buffer of 10 * K input masks target = 10 * K if inputmasks_available < target: break # already have enough input masks, sleep await asyncio.sleep(5) # Step 1b. II) Run Randousha logging.info(f"[{self.myid}] totalmasks: {totalmasks} \ inputmasks available: {inputmasks_available} \ target: {target} Initiating Randousha {k * (n - 2*t)}") send, recv = self.get_send_recv( f"preproc:inputmasks:{preproc_round}") start_time = time.time() rs_t, rs_2t = zip( *await randousha(n, t, k, self.myid, send, recv, field)) assert len(rs_t) == len(rs_2t) == k * (n - 2 * t) # Note: here we just discard the rs_2t # In principle both sides of randousha could be used with # a small modification to randousha end_time = time.time() logging.info( f"[{self.myid}] Randousha finished in {end_time-start_time}") self._inputmasks += rs_t # Step 1b. III) Submit an updated report await self._preprocess_report() # Increment the preprocessing round and continue preproc_round += 1