def __realMix(self, message, path, tempProcess=None): temp = message.permute(self.permutation[path]) result = Vector([ CyclicGroupVector.scalarMultiply(temp.at(i), self.S[path].array.at(i)) for i in range(0, self.b) ]) if not self.__finalNode(path): self.__toNextNode( path, Message(self.realMixCallback[path], [v.vector for v in result.vector])) else: self.network.broadcastToNodes( self.id, Message(self.mixCommitCallback[path], [v.vector for v in result.vector])) temp = CyclicGroupVector.multiply(self.decryptionShare[path], self.mixMessageComponents[path]) if tempProcess is not None: temp = tempProcess(temp) result = Vector([ CyclicGroupVector.scalarMultiply(result.at(i), temp.at(i)) for i in range(0, self.b) ]) self.network.sendToNH( Message(self.realPostProcessCallback[path], [True, [v.vector for v in result.vector]])) return Status.OK
def readResponse(self, message): # un-blind the response and store it for future reference responseVector = CyclicGroupVector.scalarMultiply( CyclicGroupVector(vector=message.payload), self.keyManager.getCombinedKey(type=KeyManager.RESPONSE, inverse=True)) self.callbackHandler.responseHandler(self, responseVector) self.responseGot = responseVector.copyVector() return Status.OK
def sendMessage(self, userId, messageId, messageVector): # store the message for future reference self.messageSent = messageVector.copyVector() # append the userId (the receiver) # the NH will read this id (after the message is un-blinded) and route the message accordingly messageVector.append(userId) # blind the message with the combined key and send it to the NH combinedKey = self.keyManager.getCombinedKey(type=KeyManager.MESSAGE, inverse=True) blindMessage = CyclicGroupVector.scalarMultiply( messageVector, combinedKey) self.network.sendToNH( Message(Callback.USER_MESSAGE, [self.id, messageId, blindMessage.vector]))
def __realPostProcess(self, message, path, getUsersCallback): code = message.callback isLastNode = message.payload[0] # the last node send the mix results along with his decryption share if isLastNode: self.mixResult[path] = Vector(vector=[ CyclicGroupVector(vector=v) for v in message.payload[1] ]) else: self.__appendDecrShare( CyclicGroupVector(vector=message.payload[1]), path) # gradually un-blind messages if self.mixResult[path] is not None and self.decryptionShares[ path] is not None: self.mixResult[path] = Vector([ CyclicGroupVector.scalarMultiply( self.mixResult[path].at(i), self.decryptionShares[path].at(i)) for i in range(0, self.b) ]) # when they are un-blinded, send to users if self.isLastCall(code): users = getUsersCallback() for i in range(0, self.b): if path == 'FOR': # in the forward path, also send the index # the response will contain this index, so the NH will know which slot to associate it with # NOTE: as an alternative, the NH could wait for a response before he delivers the next message # that way, the index is not needed to be sent payload = [i, self.mixResult[path].at(i).vector] else: payload = self.mixResult[path].at(i).vector self.network.sendToUser( users[i], Message(self.sendCallback[path], payload)) else: if path == 'RET': self.reset() return Status.OK
def scalarMultiply(self, cyclicVector): for i in range(0, self.b): self.messages[i] = CyclicGroupVector.scalarMultiply( self.messages[i], cyclicVector.at(i))