class ackn(MessageHandler): """ Structure of the ackn message. Byte 1: Length of error message Bytes 2-oo: error message if NAK, else empty """ _msg = struct('>B') @staticmethod def encode(rank, seq, crypter, error=None): header = MessageHandler.encodeHeader(rank, seq, MessageTypes.ACKN) payload = ackn._msg.pack( 0x00 if error is None else len(error) ) payload = payload if error is None else payload + error msg = header + payload return MessageHandler.finalizeRequest(msg, crypter) @staticmethod def decode(msg): result = MessageHandler.decodeHeader(msg[:header_length]) unpacked = ackn._msg.unpack(msg[header_length:(header_length + 1)])[0] error = msg[(header_length + 1):] result.update({'ack': ('true' if unpacked == 0x00 else 'false')}) if (unpacked != 0x00): result.update({'reasons': error}) return result @staticmethod def processRequest(msg, state): return RuntimeError('ACKN is only response, not request.')
def pos0(self): print "MONITOR POSITION: %s" % axis0pos.encode('hex').upper() if not self.sim: self.s.write(axis0pos) time.sleep(0.1) v = self.readline().encode('hex').upper() print v else: v = "\x3f\x03\x04\x38\xa5\x00\x00\x38\xb3" vnochk = v[:-2] vck = calc_crc(vnochk) if vck == v: print "crc check ok" else: print "invalid crc" pos = vnochk[3:] print pos.encode('hex').upper() s = struct.struct(">hh") pos = s.unpack(pos) print pos[0], (pos[1] << 16) pos = pos[0] + (pos[1] << 16) print "%f mm" % (pos / 100.0) return pos / 100.0
def __init__(self, sock, data_callback, control_callback=None, close_callback=None, io_loop=None, name=None): """Initiate the network channel for socket server to receive/send messages. Args: sock: The socket for receiving / sending messages. data_callback: The handler for data messages. Function fingerprint: callback(buf, offset, num_bytes) control_callback: The handler for control messages. Function fingerprint: callback(buf, offset, num_bytes) close_callback: The callback method triggered when this channel closed. Function fingerprint: callback() io_loop: The IO loop, on which the read/write operations depends; default using global IOLoop instance. name: The name of this object, could be used in debug info output. """ self._stream = iostream.IOStream(sock, io_loop, name) self._stream.set_close_callback(close_callback) self._data_handler = _callback_to_read_handler(self, data_callback) self._control_handler = _callback_to_read_handler( self, control_callback) self._name = name self._header_parser = struct.struct("<i") self._header_buf = bytearray(4)
def sendSecretShares(self): if (self._protocol_round == 0): """ Use point-to-point connection to send secrets. """ connected_peers = self._getConnectedPeers() seq = self._transactions.getNextSequenceNumber() msgs = [] binary_shares = [] for r in self.getRankList(connected_peers): binary_secret_share_pair = map( lambda x: '{0:0{1}x}'.format(x, 64).decode('hex'), self._transmitted_secrets[r]) binary_secret_share = \ struct('>BB').pack(len(binary_secret_share_pair[0]), len(binary_secret_share_pair[1])) + \ binary_secret_share_pair[0] + \ binary_secret_share_pair[1] binary_shares.append(binary_secret_share) for peer in connected_peers: msg = req.mpcs.encode(self._rank, seq, self._crypters[self._rank], self.getAlgorithm(), self.getID(), self.getIndex(), binary_shares[peer['rank']]) msgs.append(msg) secrets_deferred = self._transactions.addTransaction( EachcastTransaction(self._rank, connected_peers, msgs, seq, None)) self.receivedSecretShare(self._rank, binary_shares[self._rank]) return secrets_deferred elif (self._protocol_round == 1): d = Deferred() d.callback(None) return d else: raise RuntimeError('invalid_round')
def checkSignature(msg, crypter): if (msg is None or crypter is None): return False length = struct('>B').unpack(msg[12])[0] sig = msg[13:(13 + length)] signstr = msg[:12] + (chr(0x00) * (sig_length + 1)) + msg[header_length:] result = crypter.verify(sig, signstr) return result
class helo(MessageHandler): """ Structure of the helo message. Byte 1-16: Session ID Bytes 17-51: Escrow address Bytes 52-55: Length of encrypted output address Bytes 56-oo: Encrypted output address """ _msg = struct('>32s35sI') @staticmethod def encode(rank, seq, crypter, input_peer, encrypted_address): header = MessageHandler.encodeHeader(rank, seq, MessageTypes.HELO) payload = helo._msg.pack( input_peer['session_id'].decode('hex'), input_peer['address'], len(encrypted_address) ) payload += encrypted_address msg = header + payload return MessageHandler.finalizeRequest(msg, crypter) @staticmethod def decode(msg): result = MessageHandler.decodeHeader(msg[:header_length]) unpacked = helo._msg.unpack(msg[header_length:(header_length + 71)]) result.update({ 'sid': unpacked[0].encode('hex'), 'escrow': unpacked[1], 'output': msg[(header_length + 71):(header_length + 71 + unpacked[2])] }) return result @staticmethod def processRequest(msg, state): log.debug('Received helo request.') errors = super(helo, helo).checkResponse(msg) if ('sid' not in msg.keys()): errors.append('sid_missing') if ('escrow' not in msg.keys()): errors.append('escrow_missing') if ('output' not in msg.keys()): errors.append('output_missing') if (len(errors) > 0): super(helo, helo).createSessionErrors(state, errors) response = ackn.encode(state.mixnet.getRank(), msg['seq'], state.crypto.getCrypter(), error=','.join(errors)) return response escrow_address = msg['escrow'].strip(chr(0x00)) log.debug('Flagging input peer with:\nrank=' + str(msg['rank']) + '\nescrow=' + str(escrow_address) + '\nsession_id=' + str(msg['sid']) + '\noutput_address=' + str(msg['output'])) (result, error) = state.input.flagInputPeer( msg['rank'], escrow_address, msg['sid'], msg['output'] ) state.commit.increasePeerCount() state.commit.checkInputPeerThreshold() response = ackn.encode(state.mixnet.getRank(), msg['seq'], state.crypto.getCrypter(), error=error) return response
class addr(MessageHandler): """ Structure of the addr message. Byte 1-4: Length of each list entry Bytes 5-6: Number of list entries Bytes 6-oo: The array of addresses """ _msg = struct('>H') _msg_addr = struct('>I') @staticmethod def encode(rank, seq, crypter, addresses): header = MessageHandler.encodeHeader(rank, seq, MessageTypes.ADDR) payload = addr._msg.pack( len(addresses) ) payload += reduce(lambda x, y: x + y, map(lambda x: addr._msg_addr.pack(len(x)) + x, addresses)) msg = header + payload return MessageHandler.finalizeRequest(msg, crypter) @staticmethod def decode(msg): result = MessageHandler.decodeHeader(msg[:header_length]) number_addresses = addr._msg.unpack(msg[header_length:(header_length + 2)])[0] outputs = [] offset = header_length + 2 for i in xrange(number_addresses): length = addr._msg_addr.unpack(msg[offset:(offset + 4)])[0] offset += 4 outputs.append(msg[offset: (offset + length)]) offset += length result.update({ 'outputs': outputs }) return result @staticmethod def processRequest(msg, state): log.debug('Received addr request.') errors = super(addr, addr).checkResponse(msg) if ('outputs' not in msg.keys()): errors.append('outputs_missing') if (len(errors) > 0 or len(msg['outputs']) < state.input.getNumberInputPeers()): log.critical('addr error occurred, but I\'m not handling it.') return None state.shuffle.receivedAddrBroadcast(msg['outputs'], msg['rank'])
class mpcs(SmpcMessageHandler): """ Structure of the mpcs message. Bytes 1-2: Length of the secret value Bytes 3-oo: Secret value """ _msg = struct('>H') @staticmethod def encode(rank, seq, crypter, alg, id, index, binary_secret_share): header = SmpcMessageHandler.encodeHeader(rank, seq, crypter, MessageTypes.MPCS, alg, id, index) payload = mpcs._msg.pack( len(binary_secret_share) ) payload += binary_secret_share msg = header + payload return MessageHandler.finalizeRequest(msg, crypter) @staticmethod def decode(msg): result, offset = SmpcMessageHandler.decodeHeader(msg) share_length = mpcs._msg.unpack(msg[offset:(offset + 2)])[0] binary_secret_share = msg[(offset + 2):(offset + 2 + share_length)] result.update({ 'share': binary_secret_share }) return result @staticmethod def processRequest(msg, smpc_value): log.debug('Received mpcs request.') errors = super(mpcs, mpcs).checkResponse(msg, smpc_value.getAlgorithm()) if ('share' not in msg.keys()): errors.append('share_missing') if (len(errors) > 0): log.error('Error receiving mpcs request. Error(s): ' + str(errors)) return None try: if (len(errors) == 0): smpc_value.receivedSecretShare(msg['rank'], msg['share']) except BaseException: errors.append('share_internal_error') smpc_value.fireSecretDeferred(msg['rank']) if (len(errors) > 0): log.error('Malformed message. Errors: ' + str(errors)) log.error('Message was: ' + str(msg)) return None else: log.debug('Received mpcs request (' + str(msg['id']) + ', ' + str(msg['index']) + ') from peer ' + str(msg['rank']) + '.') return None
class mpcp(SmpcMessageHandler): """ Structure of the mpcp message. Bytes 1-2: Length of the public value Bytes 3-oo: Public value """ _msg = struct('>H') @staticmethod def encode(rank, seq, crypter, alg, id, index, public_value): header = SmpcMessageHandler.encodeHeader(rank, seq, crypter, MessageTypes.MPCP, alg, id, index) payload = mpcp._msg.pack( len(public_value) ) payload += public_value msg = header + payload return MessageHandler.finalizeRequest(msg, crypter) @staticmethod def decode(msg): result, offset = SmpcMessageHandler.decodeHeader(msg) public_value_length = mpcp._msg.unpack(msg[offset:(offset + 2)])[0] public_value_bin = msg[(offset + 2):(offset + 2 + public_value_length)] result.update({ 'value': public_value_bin }) return result @staticmethod def processRequest(msg, smpc_value): log.debug('Received mpcp request.') errors = super(mpcp, mpcp).checkResponse(msg, smpc_value.getAlgorithm()) if ('value' not in msg.keys()): errors.append('value_missing') if (len(errors) > 0): log.error('Error receiving mpcp request. Error(s): ' + str(errors)) return None try: if (len(errors) == 0): smpc_value.receivedPublicValue(msg['rank'], msg['value']) except BaseException: errors.append('value_internal_error') if (len(errors) > 0): log.error('Malformed message. Errors: ' + str(errors)) log.error('Message was: ' + str(msg)) return None else: log.debug('Received mpcp request (' + str(msg['id']) + ', ' + str(msg['index']) + ') from peer ' + str(msg['rank']) + '.') return None
class comp(SmpcMessageHandler): """ Structure of the comp message. Bytes 1-2: Rank of the mixpeer being blamed Bytes 3-4: Length of the optional parameter Bytes 5-oo: Optional parameter if previous field is > 0 """ _msg = struct('>HH') @staticmethod def encode(rank, seq, crypter, alg, id, index, blamed_peer, opt=None): header = SmpcMessageHandler.encodeHeader(rank, seq, crypter, MessageTypes.COMP, alg, id, index) binary_opt = '{0:x}'.format(opt).decode('hex') if opt is not None else '' # Compute binary presentation of opt payload = comp._msg.pack( blamed_peer, len(binary_opt) ) payload += binary_opt msg = header + payload return MessageHandler.finalizeRequest(msg, crypter) @staticmethod def decode(msg): result, offset = SmpcMessageHandler.decodeHeader(msg) blamed_peer, opt_length = comp._msg.unpack(msg[offset:(offset + 4)]) opt_bin = msg[(offset + 4):(offset + 4 + opt_length)] result.update({ 'blame': blamed_peer }) if opt_length > 0: result.update({ 'opt': int(opt_bin.encode('hex'), 16) }) return result @staticmethod def processRequest(msg, smpc_value): log.debug('Received comp request.') errors = super(comp, comp).checkResponse(msg, smpc_value.getAlgorithm()) if ('blame' not in msg.keys()): errors.append('blame_missing') opt = msg['opt'] if ('opt' in msg.keys()) else None if (len(errors) > 0): log.error('Malformed message. Errors: ' + str(errors)) log.error('Message was: ' + str(msg)) return None smpc_value.receivedComplaint(msg['blame'], msg['rank'], opt) log.debug('Received comp request (' + str(msg['id']) + ', ' + str(msg['index']) + ') from peer ' + str(msg['rank']) + '.') return None
class cmpr(SmpcMessageHandler): """ Structure of the mpcs message. Bytes 1-2: Rank of the mixpeer that blamed the reaction's sender Bytes 3-4: Length of the justification value Bytes 5-oo: The justification value """ _msg = struct('>HH') @staticmethod def encode(rank, seq, crypter, alg, id, index, blaming_peer, justification): header = SmpcMessageHandler.encodeHeader(rank, seq, crypter, MessageTypes.CMPR, alg, id, index) binary_justification = '{0:x}'.format(justification).decode('hex') # Compute binary presentation of justification payload = cmpr._msg.pack( blaming_peer, len(binary_justification) ) payload += binary_justification msg = header + payload return MessageHandler.finalizeRequest(msg, crypter) @staticmethod def decode(msg): result, offset = SmpcMessageHandler.decodeHeader(msg) blaming_peer = cmpr._msg.unpack(msg[offset:(offset + 2)]) justification_length = cmpr._msg.unpack(msg[(offset + 2):(offset + 4)]) justification_bin = msg[(offset + 4):(offset + 4 + justification_length)] result.update({ 'blamer': blaming_peer, 'value': justification_bin }) return result @staticmethod def processRequest(msg, smpc_value): errors = super(cmpr, cmpr).checkResponse(msg, smpc_value.getAlgorithm()) if ('blamer' not in msg.keys()): errors.append('blamer_missing') if ('value' not in msg.keys()): errors.append('value_missing') if (len(errors) > 0): log.error('Malformed message. Errors: ' + str(errors)) log.error('Message was: ' + str(msg)) return None smpc_value.receivedComplaintReaction(msg['rank'], msg['blamer'], msg['value']) log.debug('Received cmpr request (' + str(msg['id']) + ', ' + str(msg['index']) + ') from peer ' + str(msg['rank']) + '.') return None
def receivedSecretShare(self, peer_rank, binary_share): if (peer_rank not in self._qualified): return if (self._shares_ready.called or self._received_secrets[peer_rank] is not None or self._protocol_round != 0): # Ignore late/unexpected shares return share_lengths = struct('>BB').unpack(binary_share[:2]) share = [ int(binary_share[2:(2 + share_lengths[0])].encode('hex'), 16), int( binary_share[(2 + share_lengths[0]):( 2 + share_lengths[0] + share_lengths[1])].encode('hex'), 16), ] self._received_secrets[peer_rank] = share if (len(filter(lambda s: s is None, self._received_secrets)) == 0): self._shares_ready.callback(None) return
def __init__(self, sock, data_callback, control_callback=None, close_callback=None, io_loop=None, name=None): """Initiate the network channel for socket server to receive/send messages. Args: sock: The socket for receiving / sending messages. data_callback: The handler for data messages. Function fingerprint: callback(buf, offset, num_bytes) control_callback: The handler for control messages. Function fingerprint: callback(buf, offset, num_bytes) close_callback: The callback method triggered when this channel closed. Function fingerprint: callback() io_loop: The IO loop, on which the read/write operations depends; default using global IOLoop instance. name: The name of this object, could be used in debug info output. """ self._stream = iostream.IOStream(sock, io_loop, name) self._stream.set_close_callback(close_callback) self._data_handler = _callback_to_read_handler(self, data_callback) self._control_handler = _callback_to_read_handler(self, control_callback) self._name = name self._header_parser = struct.struct("<i") self._header_buf = bytearray(4)
class cbrc(MessageHandler): """ Structure of the broadcast message header. Bits 1-4: Type of broadcast used Bits 5-8: Type of the broadcast message """ _msg = struct('>B') _msg_send = struct('>I') _msg_echo = struct('>B72s') _msg_finl = struct('>H') _msg_fsig = struct('>HB72s') """ Identifiers for the type of broadcast message. """ SEND = 0x00 # Send message by sender ECHO = 0x01 # Echo message by receivers FINL = 0x02 # Final message by sender @staticmethod def getMessageTypeID(msg_type): if (msg_type == 's'): return cbrc.SEND elif (msg_type == 'e'): return cbrc.ECHO elif (msg_type == 'f'): return cbrc.FINL else: return RuntimeError('unknown consistent broadcast message type') @staticmethod def getMessageType(msg_type_id): if (msg_type_id == cbrc.SEND): return 's' elif (msg_type_id == cbrc.ECHO): return 'e' elif (msg_type_id == cbrc.FINL): return 'f' else: return RuntimeError('unknown consistent broadcast message type id') @staticmethod def encode(rank, seq, crypter, msg_type, value): header = MessageHandler.encodeHeader(rank, seq, MessageTypes.CBRC) payload = cbrc._msg.pack( msg_type ) if (msg_type == cbrc.SEND): payload += cbrc._msg_send.pack( len(value) ) payload += value elif (msg_type == cbrc.ECHO): payload += cbrc._msg_echo.pack( len(value), value + (chr(0x00) * (sig_length - len(value))) ) elif (msg_type == cbrc.FINL): payload += cbrc._msg_finl.pack( len(value) ) for i in xrange(len(value)): payload += cbrc._msg_fsig.pack( value[i][0], len(value[i][1]), value[i][1] + (chr(0x00) * (sig_length - len(value[i][1]))) ) msg = header + payload return MessageHandler.finalizeRequest(msg, crypter) @staticmethod def decode(msg): result = MessageHandler.decodeHeader(msg) msg_type = cbrc._msg.unpack(msg[header_length:(header_length + 1)])[0] result.update({ 'type': cbrc.getMessageType(msg_type) }) if (msg_type == cbrc.SEND): msg_length = cbrc._msg_send.unpack(msg[(header_length + 1):(header_length + 5)])[0] msg_encap = msg[(header_length + 5):(header_length + 5 + msg_length)] result.update({ 'm': msg_encap }) elif (msg_type == cbrc.ECHO): length, sig = cbrc._msg_echo.unpack(msg[(header_length + 1):(header_length + 2 + sig_length)]) sig = sig[:length] result.update({ 's': sig }) elif (msg_type == cbrc.FINL): sig_num = cbrc._msg_finl.unpack(msg[(header_length + 1):(header_length + 3)])[0] signatures = [] for i in xrange(sig_num): rank, length, sig = cbrc._msg_fsig.unpack(msg[(header_length + 3 + (i * (2 + 1 + sig_length))):(header_length + 3 + ((i + 1) * (2 + 1 + sig_length)))]) sig = sig[:length] signatures += [[rank, sig]] result.update({ 's': signatures }) return result @staticmethod def processRequest(msg, transaction, state): log.debug('Received cbrc request.') errors = super(cbrc, cbrc).checkResponse(msg) if (len(errors) > 0): log.error('Malformed message. Errors: ' + str(errors)) log.error('Message was: ' + str(msg)) return None transaction.receivedResponse(msg) return None
def getRank(msg): return struct('>H').unpack(msg[2:4])[0]
def serializeEcPoints(points): serialized = struct('>B').pack(len(points)) for i in xrange(len(points)): serialized += struct('>65s').pack(serializeEcPoint(points[i], binary=True)) return serialized
def deserializeEcPoints(points_str): deserialized = [] length = int(struct('>B').unpack(points_str[0])[0]) for i in xrange(length): deserialized.append(deserializeEcPoint(points_str[((i * 65) + 1):(((i + 1) * 65) + 1)], binary=True)) return deserialized
def signRequest(msg, crypter): sig = crypter.sign(msg) length = len(sig) sig = struct('>B').pack(len(sig)) + sig + (chr(0x00) * (sig_length - length)) msg = msg[:12] + sig + msg[header_length:] return msg
def getMessageType(msg): return struct('>B').unpack(msg[1])[0]
def getSequenceNumber(msg): return struct('>I').unpack(msg[4:8])[0]
def setSequenceNumber(msg, seq): return msg[:4] + struct('>I').pack(seq) + msg[8:]
class MessageHandler(object): """ Structure of the message header. Byte 1: Version byte (0x01) Byte 2: Message type Bytes 3,4: Sender rank Bytes 5-8: Sequence Number Bytes 9-12: Packet length Bytes 13-82: ECDSA Signature """ _msg = struct('>BBHII73s') _msg_length = struct('>I') @staticmethod def checkResponse(msg): errors = [] if ('msg' not in msg.keys()): errors.append('msg_missing') if ('rank' not in msg.keys()): errors.append('rank_missing') if ('sig' not in msg.keys()): errors.append('sig_missing') if ('seq' not in msg.keys()): errors.append('seq_missing') if ('msg' in msg.keys() and msg['msg'] == 'rbrc'): if ('m' not in msg.keys()): errors.append('m_missing') else: if ('msg' not in msg['m'].keys()): errors.append('m_msg_missing') else: if (msg['m']['msg'] in MessageHandler.smpc_msgs): if ('id' not in msg['m'].keys()): errors.append('m_id_missing') if ('index' not in msg['m'].keys()): errors.append('m_index_missing') return errors @staticmethod def processRequest(msg_binary, state): return AbstractClassError() @staticmethod def encodeHeader(rank, seq, msg_type): return MessageHandler._msg.pack( VERSION, msg_type, rank, seq, 0, chr(0x00) * (sig_length + 1) # Leave signature empty, must be filled in later ) @staticmethod def decodeHeader(msg): unpacked = MessageHandler._msg.unpack(msg[:header_length]) return { # Ignore version field 'msg': MessageTypes.getString(unpacked[1]), 'rank': unpacked[2], 'seq': unpacked[3], 'sig': unpacked[5] } @staticmethod def setRank(msg, rank): return msg[:2] + struct('>H').pack(rank) + msg[4:] @staticmethod def getRank(msg): return struct('>H').unpack(msg[2:4])[0] @staticmethod def setSequenceNumber(msg, seq): return msg[:4] + struct('>I').pack(seq) + msg[8:] @staticmethod def getSequenceNumber(msg): return struct('>I').unpack(msg[4:8])[0] @staticmethod def getMessageType(msg): return struct('>B').unpack(msg[1])[0] @staticmethod def createSessionErrors(state, errors): if ('rank_missing' in errors or 'sid_missing' in errors): return False # Rank and SID are required to truly log errors... return True @staticmethod def setLength(msg): msg = msg[:8] + MessageHandler._msg_length.pack(len(msg)) + msg[12:] return msg @staticmethod def getLength(msg): return MessageHandler._msg_length.unpack(msg[8:12])[0] @staticmethod def signRequest(msg, crypter): sig = crypter.sign(msg) length = len(sig) sig = struct('>B').pack(len(sig)) + sig + (chr(0x00) * (sig_length - length)) msg = msg[:12] + sig + msg[header_length:] return msg @staticmethod def checkSignature(msg, crypter): if (msg is None or crypter is None): return False length = struct('>B').unpack(msg[12])[0] sig = msg[13:(13 + length)] signstr = msg[:12] + (chr(0x00) * (sig_length + 1)) + msg[header_length:] result = crypter.verify(sig, signstr) return result @staticmethod def finalizeRequest(msg, crypter): msg = MessageHandler.setLength(msg) msg = MessageHandler.signRequest(msg, crypter) return msg
class rbrc(MessageHandler): """ Structure of the broadcast message header. Bits 1-4: Type of broadcast used Bits 5-8: Type of the broadcast message """ _msg = struct('>B') _msg_send = struct('>I') _msg_echo = struct('>72s') _msg_finl = struct('>H') _msg_fsig = struct('>H72s') """ Identifiers for the type of broadcast message. """ SEND = 0x00 # Send message by sender ECHO = 0x01 # Echo message by receivers REDY = 0x02 # Ready message by receivers @staticmethod def getMessageType(msg_type): if (msg_type == 's'): return rbrc.SEND elif (msg_type == 'e'): return rbrc.ECHO elif (msg_type == 'r'): return rbrc.REDY else: return RuntimeError('unknown reliable broadcast message type') @staticmethod def getMessageTypeID(msg_type_id): if (msg_type_id == rbrc.SEND): return 's' elif (msg_type_id == rbrc.ECHO): return 'e' elif (msg_type_id == rbrc.REDY): return 'r' else: return RuntimeError('unknown reliable broadcast message type id') @staticmethod def encode(rank, seq, crypter, msg_type, value): # FIXME: Not refactored return NotImplementedError('Reliable broadcast not yet refactored') header = MessageHandler.encodeHeader(rank, seq, crypter, MessageTypes.CBRC) payload = cbrc._msg.pack( msg_type ) if (msg_type == rbrc.SEND): payload += cbrc._msg_send.pack( len(value) ) payload += value elif (msg_type == rbrc.ECHO): payload += cbrc._msg_echo.pack( value ) elif (msg_type == rbrc.FINL): payload += cbrc._msg_finl.pack( len(value) ) for i in xrange(len(value)): payload += cbrc._msg_fsig.pack( value[0], value[1] ) msg = header + payload return MessageHandler.signRequest(msg, crypter) @staticmethod def decode(msg): # FIXME: Not refactored return NotImplementedError('Reliable broadcast not yet refactored') result = MessageHandler.decodeHeader(msg) msg_type = cbrc._msg.unpack(msg[header_length:(header_length + 1)]) result.update({ 'type': cbrc.getMessageType(msg_type) }) if (msg_type == rbrc.SEND): msg_length = cbrc._msg_send.unpack(msg[(header_length + 1):(header_length + 5)]) msg_encap = msg[(header_length + 5):(header_length + 5 + msg_length)] result.update({ 'm': msg_encap }) elif (msg_type == rbrc.ECHO): sig = cbrc._msg_echo.unpack(msg[(header_length + 1):(header_length + 73)]) result.update({ 's': sig }) elif (msg_type == rbrc.FINL): sig_num = cbrc._msg_finl.unpack(msg[(header_length + 1):(header_length + 3)]) signatures = [] for i in xrange(sig_num): rank, sig = cbrc._msg.fsig.unpack(msg[(header_length + 3 + (i * 74)):(header_length + 3 + ((i + 1) * 74))]) signatures += [[rank, sig]] result.update({ 's': signatures }) return result @staticmethod def processRequest(msg, state): # FIXME: Not refactored return NotImplementedError('Reliable broadcast not yet refactored') log.debug('Received cbrc request.') errors = super(cmpr, cmpr).checkResponse(msg) if (len(errors) > 0): log.error('Malformed message. Errors: ' + str(errors)) log.error('Message was: ' + str(msg)) return None transaction = state.transactions.findTransaction(msg['seq']) if (transaction is None): """ Ignore prematurely received final-messages. If final is received without first receiving send, the msg is unknown and also the sender is malicious. """ if (not msg['type'] == 's'): return None msg_type = MessageHandler.getMessageType(msg['m']) request_handler = getMessageHandler(msg_type) transaction = ConsistentBroadcastTransaction( self.state.mixnet.getRank(), self.state.crypto.getCrypter(), self.state.mixnet.getConnectedMixpeers(), self.state.mixnet.getMixnetSize(), self.state.mixnet.getMixpeerThreshold(), msg['seq'], None, self.state.getP2pClientDeferred() ) self.state.transactions.addTransaction(transaction) if (msg_type in MessageTypes.smpc_msgs): smpc_msg = request_handler.decode(msg['m']) smpc_value = state.smpc.getValue(smpc_msg['id'], smpc_msg['index']) if (smpc_value is None): smpc_value = self.state.smpc.newValue( smpc_msg['alg'], state, smpc_msg['id'], smpc_msg['index'] ) transaction.defineCallback(request_handler, smpc_value) else: transaction.defineCallback(request_handler, state) transaction.receivedResponse(msg) return None
class SmpcMessageHandler(MessageHandler): """ Structure of the smpc message header. Byte 1: Algorithm of the SMPC value Bytes 2-5: Index of the SMPC value Byte 6: The length of the SMPC value identifier Bytes 7-oo: The identifier of the smpc value""" _msg = struct('>BIB') """ Identifiers for active SMPC values; WRAP, CMUL only use local computation, but are nevertheless assigned an ID here. """ WRAP = 0x00 # Wrapper protocol CMUL = 0x01 # Constant multiplication REC = 0x02 # Recombination protocol MUL = 0x03 # Multiplication protocol DKG = 0x04 # Distributed Key Generation protocol JDKG = 0x05 # JfDkg for generation of H as needed for DKG @staticmethod def getAlgorithm(alg): if (alg == SmpcMessageHandler.JDKG): return 'jfdkg' elif (alg == SmpcMessageHandler.DKG): return 'dkg' elif (alg == SmpcMessageHandler.MUL): return 'mul' elif (alg == SmpcMessageHandler.REC): return 'rec' elif (alg == SmpcMessageHandler.WRAP): return 'wrap' elif (alg == SmpcMessageHandler.CMUL): return 'cmul' else: return RuntimeError('unknown smpc algorithm id') @staticmethod def getAlgorithmID(alg_str): if (alg_str == 'jfdkg'): return SmpcMessageHandler.JDKG elif (alg_str == 'dkg'): return SmpcMessageHandler.DKG elif (alg_str == 'mul'): return SmpcMessageHandler.MUL elif (alg_str == 'rec'): return SmpcMessageHandler.REC elif (alg_str == 'wrap'): return SmpcMessageHandler.WRAP elif (alg_str == 'cmul'): return SmpcMessageHandler.CMUL else: return RuntimeError('unknown smpc algorithm') @staticmethod def encodeHeader(rank, seq, crypter, msg_type, alg, id, index): header = MessageHandler.encodeHeader(rank, seq, msg_type) smpc_header = SmpcMessageHandler._msg.pack( SmpcMessageHandler.getAlgorithmID(alg), index, len(id), ) smpc_header += id msg = header + smpc_header return msg @staticmethod def decodeHeader(msg): result = MessageHandler.decodeHeader(msg[:header_length]) (alg, index, idlen) = SmpcMessageHandler._msg.unpack(msg[header_length:(header_length + 6)]) offset = header_length + 6 + idlen id = msg[(header_length + 6):(offset)] result.update({ 'alg': SmpcMessageHandler.getAlgorithm(alg), 'id': id, 'index': index }) return (result, offset) @staticmethod def checkResponse(msg, alg): errors = [] if ('id' not in msg.keys()): errors.append('id_missing') if ('index' not in msg.keys()): errors.append('index_missing') if ('alg' not in msg.keys()): errors.append('alg_missing') if (alg != msg['alg']): errors.append('alg_mismatch') return errors
import md5 import hashlib import struct import binascii s = 'hello world\n' m = md5.new() # hashlib.new('md5') m.update(s) print m.hexdigest() #print hashlib.algorithms d = hashlib.new('sha256') d.update(s) print d.hexdigest() ts = struct.struct(' i 8s f ') val = (100,'whatever', 2.8) pts = ts.pack(*val) print 'Original values:', values print 'Format string :', s.format print 'Uses :', s.size, 'bytes' print 'Packed Value :', binascii.hexlify(packed_data)
def setRank(msg, rank): return msg[:2] + struct('>H').pack(rank) + msg[4:]