def send_msg(self, to, msg, imp): r = self.clock_round() fchannelsid = (self.ssid, (self.sid,self.pid), (self.sid,to), r, self.delta) log.debug("\nsending import: {}".format(imp)) self.write('p2f', ((fchannelsid,'F_chan'), ('send',msg)), imp) m = wait_for(self.channels['f2p']) assert m.msg[1] == 'OK', str(m)
def get_ideal_wrapper_leaks(self): # grab leaks from the ideal world wrapper self.channels['a2w'].write( ('get-leaks',) ) m = wait_for( self.channels['w2a'] ) msg = m.msg n = 0 pid_idx = None for leak in msg: self.tick(1) sender,msg,imp = leak if msg[0] == 'input' and sender == (self.sid, 'F_bracha'): self.dealer_input = msg[2]; assert type(msg[2]) == int # F_bracha leaks the dealer input, simulated it n = len(self.parties) self.log.debug('\033[94m Simulation beginning\033[0m') m = self.sim_write_and_wait('z2p', ((self.sim_sid,1),('input',msg[2])), imp, 'a2z', 'p2z') assert m.msg[1] == 'OK', str(m.msg) self.log.debug('\033[94m Simulation ending\033[0m') elif msg[0] == 'schedule': # some new codeblocks scheduled in simulated wrapper if sender == (self.sid, 'F_bracha'): if not pid_idx: pid_idx = 1 self.add_output_schedule(msg, pid_idx) pid_idx += 1 else: self.add_new_schedule(msg) else: raise Exception("new kind of leak " + str(msg)) if pid_idx: assert pid_idx-1 == len(self.parties), "n={}, pid_idx={}".format(len(self.parties), pid_idx)
def party_send(self, sender, msg, imp): if sender == self.sender: self.write('f2w', ('schedule', self.send_message, (msg, imp), self.delta), 0) assert wait_for(self.channels['w2f']).msg == ('OK', ) self.leak(msg) self.write('f2p', (self.sender, 'OK')) else: self.pump.write("dump")
def sim_party_output(self, m): # If we got output from the party, it outputed a committed value (or bot) # tell the ideal wrapper to execute the corresponding codeblock fro,msg = m.msg _sid,_pid = fro self.log.debug('\033[91m Got some output from pid={}, msg={}\033[0m'.format(_pid,msg)) if self.is_dishonest(_sid,_pid):#isdishonest(_sid,_pid): self.tick(1) # forward this output to the environment self.write('a2z', ('P2A', msg) ) # don't do anything else since corrupt output in the ideal world doesn't # get delivered return elif not self.dealer_input: assert len(self.internal_run_queue) == 0 # If output and not dealer input, dealer is crupt. Call input on functonality self.tick(1) assert self.is_dishonest(self.sid, 1)#isdishonest(self.sid,1) n = len(self.parties) print('\n\t sending input to f_bracha \n\t') self.write( 'a2p', ((self.sid, 1), ('P2F', ((self.sid, 'F_bracha'), ('input',msg)) )), n*(4*n + 1)) m = waits(self.pump, self.channels['p2a']) print('\n******m\n', m, '\n') _fro,_msg = m.msg self.dealer_input = msg; assert type(msg) == int, 'msg:{}, fro:{}'.format(msg, fro) assert _msg == 'OK', str('fro={}, msg={}'.format(_fro,_msg)) # Now get leaks, and populate self.pid_to_queue #leaks = self.get_ideal_wrapper_leaks() self.tick(1) self.write( 'a2w', ('get-leaks',)) m = wait_for(self.channels['w2a']) msg = m.msg pid_idx = None for leak in msg: self.tick(1) sender,msg,imp = leak if sender == (self.sid, 'F_bracha'): if msg[0] == 'schedule': if not pid_idx: pid_idx = 1 self.add_output_schedule(msg, pid_idx) pid_idx += 1 if pid_idx: assert pid_idx-1 == len(self.parties) self.expect_output = True # If dealer gave input to the functionality rnd,idx = self.pid_to_queue[_pid] self.internal_run_queue[rnd].pop(idx) for p in self.pid_to_queue: self.tick(1) if p > _pid: r,i = self.pid_to_queue[p] self.pid_to_queue[p] = (r, i-1) self.write('a2w', ('exec', rnd, idx))
def broadcast(self, msg, imp): self.leak(msg) self.write( 'f2w', ('schedule', self.send_to, ((self.sid, self.P_s), msg, imp), 1), 0 ) assert wait_for(self.channels['w2f']).msg == ('OK',) self.write('f2w', ('schedule', self.send_to, ((self.sid, self.P_r), msg, imp), 1), 0 ) assert wait_for(self.channels['w2f']).msg == ('OK',) self.leak(('bcast', msg)) self.pump.write('dump')
def party_input(self, pid, inp): if pid == 1: for p in self.parties: #self.f2w.write( ('schedule', self.send_output, ((self.sid,p), inp), self.delta), 0) print('scheduling input') self.write('f2w', ('schedule', self.send_output, ((self.sid,p), inp), self.delta), 0) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) n = len(self.parties) self.leak( ('input', pid, inp), n*(4*n + 1)) print('f2p channel', self.channels['f2p']) self.write('f2p', ((self.sid,pid), 'OK'))
def offchain_channel(self, _from, _to, msg, imp): codeblock = ( 'schedule', self.__send2p, (_to, msg, imp), 1 ) self.write('f2w', codeblock, imp) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) leaked_msg = ('send', (_from, _to, _amt)) self.leak(leaked_msg, 0)
def close_channel(self, _from): if self.flag == 'OPEN': delay = self.delta # on-chain communication delay codeblock = ( 'schedule' self.__close, (), delay ) self.write('f2w', codeblock) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) leaked_msg = ('close channel', (_from)) self.leak(leaked_msg, 0)
def init_channel(self, _from, amount): if self.flag == 'CLOSED': delay = self.delta # on-chain communication delay codeblock = ( 'schedule' self.__init, (_from, amount), delay ) self.write('f2w', codeblock) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) # supposed to get this immediately, just to check if the message is successfully queued in wrapper leaked_msg = 'leaked msg (i don know what is the format of leaked message is look like, so a placeholder here)' self.leak(leaked_msg, 0) # leak msg to the adversary because this part simulates the msg being sent to the synchronous channel in the real world
def withdraw(self, _from, amount): if self.flag == 'CLOSED': # can withdraw only after channel is closed delay = self.delta # on-chain communication delay codeblock = ( 'schedule' self.__withdraw, (_from, amount), delay ) self.write('f2w', codeblock) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) leaked_msg = 'leaked msg (i don know what is the format of leaked message is look like, so a placeholder here)' self.leak(leaked_msg, 0)
def deposit(self, _from, amount): if self.flag == 'OPEN': delay = self.delta # on-chain communication delay codeblock = ( 'schedule' self.__deposit, (_from, amount), delay ) self.write('f2w', codeblock) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) leaked_msg = 'leaked msg (i don know what is the format of leaked message is look like, so a placeholder here)' self.leak(leaked_msg, 0)
def wrapper_contract(self, sender, msg, imp): if sender > 0: # sender is parties codeblock = ( 'schedule', self.__send2c, (msg, imp), self.delta ) self.write('f2w', codeblock, imp) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) elif sender == -1: # sender is contract, and this is broadcast for _to in range(self.n): codeblock = ( 'schedule', self.__send2p, (_to, msg, imp), 1 ) self.write('f2w', codeblock, imp) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) else: return
def party_msg(self, d): msg = d.msg imp = d.imp (_sid, _sender),msg = msg self.write( 'f2w', ('schedule', self.route_party_msg, (_sender, msg, imp), self.delta), 0 ) assert wait_for(self.channels['w2f']).msg == ('OK',) self.leak(msg) self.pump.write('dump')
def pay(self, _from, _to, amount): if self.flag == 'CLOSED': return # if there's no channel, cannot pay offchain delay = 1 # delay only 1 round because pay is supposed to be off-chain codeblock = ( 'schedule' self.__pay, (_from, _to, amount), delay ) self.write('f2w', codeblock) m = wait_for(self.channels['w2f']).msg assert m == ('OK',) leaked_msg = ('pay', (_from, _to, amount)) self.leak(leaked_msg, 0)
def clock_round(self): self.write('p2w', ('clock-round', ), 0) rnd = wait_for(self.channels['w2p']).msg[1] return rnd