def __init__(self, arguments=[], constructedtype=False): super().__init__("senc", arguments, constructedtype) try: assert isinstance(arguments[0], Term) except Exception: raise ProtocolError(("", "Constructed type ")[constructedtype] + "senc does not have the right first argument (term) : " + arguments[0].__str__()) if constructedtype: try: assert isinstance(arguments[1], Type) except Exception: raise ProtocolError("Constructed type senc does not have the right second argument (type) : " + arguments[1].__str__()) else: try: assert isinstance(arguments[1], Variable) except Exception: raise ProtocolError("senc does not have the right second argument (variable) : " + arguments[1].__str__()) # the first argument cannot be honest as it is a message if isinstance(arguments[0], Variable): arguments[0].type.honest = False
def __init__(self, arguments=[], constructedtype=False): super().__init__("vk", arguments, constructedtype) if constructedtype: try: assert isinstance(arguments[0], Type) except Exception: raise ProtocolError("Constructed type vk does not have the right argument (type) : " + arguments[0].__str__()) else: try: assert isinstance(arguments[0], Variable) except Exception: raise ProtocolError("vk does not have the right argument (variable) : " + arguments[0].__str__())
def isTypeCompliant(self, action2): print(self.__str__() + "|" + action2.__str__()) listVars = [ [], [] ] # This parameter listVars is the list of vars those are unifiable with all terms isConcat = False if isinstance(self.rootTerm, Variable) and isinstance( action2.rootTerm, Variable): if not isinstance(self.rootTerm.type, Type) and not isinstance( action2.rootTerm.type, Type): if self.rootTerm.type.constructedtype or action2.rootTerm.type.constructedtype: isConcat = True if not self.rootTerm.isTypeCompliant(action2.rootTerm, listVars, isConcat): return False for i in range(0, len(listVars[0])): var0 = listVars[0][i] var1 = listVars[1][i] type0 = var0.type type1 = var1.type msgError= "Type-compliance error due to subterm " + str(var0.__str__())\ + " of action " + str(self) + " and subterm " + str(var1.__str__())\ + " of action " + str(action2.__str__()) + ".\nSubterms " + str(var0.__str__())\ + " and " + str(var1.__str__()) + " are unifiable whereas they have different"\ + " types: " + str(var0.__str__()) + " has type " + str(type0.__str__())\ + " and " + str(var1.__str__()) + " has type "+ str(type1.__str__()) + "." if not isinstance(type0, Type) and not isinstance( type1, Type): #it's a constructed type listT = [[], []] if not type0.isTypeCompliant(type1, listT, False): return False print(listT) for j in range(0, len(listT[0])): if not listT[0][j] == listT[1][j]: print( str(type0.__str__()) + " and " + str(type1.__str__())) raise ProtocolError(msgError) else: if not type0 == type1: # in listVars if the 2 types are the sames => OK # else typecompliance error print( str(type0.__str__()) + " and " + str(type1.__str__())) raise ProtocolError(msgError) print("Unifiable !!!") return True
def __init__(self, name, arguments=[], constructedtype=False): # if arity does not match the number of arguments (arity<0=>there is no fixed arity) if len(arguments) != self.arity and self.arity >= 0: raise ProtocolError("Error : the primitive " + name + " does not match the arity " + str(len(arguments))) Term.__init__(self) # string representing this primitive (ex : aenc) self.name = name # list of terms, their amount is the arity of the primitive self.arguments = arguments # true if it's use to construct a type, false otherwise self.constructedtype = constructedtype
def getPrimitive(name, arguments=[], constructedtype=False): if name == "pub": return pub.pub(arguments, constructedtype) elif name == "aenc": return aenc.aenc(arguments, constructedtype) elif name == "senc": return senc.senc(arguments, constructedtype) elif name == "sign": return sign.sign(arguments, constructedtype) elif name == "vk": return vk.vk(arguments, constructedtype) elif name == "concat" or name == "pair": return concat.concat(arguments, constructedtype) else: raise ProtocolError("No primitive found with the name " + name)
def __init__(self, arguments=[], constructedtype=False): super().__init__("concat", arguments, constructedtype) compt = 0 for arg in arguments: compt += 1 try: assert isinstance(arg, Term) # this argument cannot be honest as it is seen by the attacker if self.constructedtype: if isinstance(arg, Type): arg.honest = False else: if isinstance(arg, Variable): arg.type.honest = False except Exception: raise ProtocolError(("", "Constructed type ")[constructedtype] + "concat does not have the right " + str(compt) + "argument (term) :" + arg.__str__())
def exploreTree(tree, protocol): # eliminate blank lines and other weird nodes if not (hasattr(tree, "data")): return data = tree.data # beginning of protocol if data == "start": for c in tree.children: exploreTree(c, protocol) # variables declarations bloc elif data == "public" or data == "private": for vardeclaration in tree.children: # skips "weirds" elements of the tree like blanks or newlines if not hasattr(vardeclaration, "data") or vardeclaration.data != "vardeclaration": continue vardeclarationchildren = removeTokenSpace(vardeclaration) # gets the variable name new_var = vardeclarationchildren[0].children[0] # error if variable name already exists if new_var in mapVarType: raise ProtocolError( "Variable " + vardeclarationchildren[0].children[0] + " in line " + str(vardeclaration.meta.line) + " already defined before : the variable names must be unique" ) # For the private constants, the type are honest. The type is put at public when it's instantiate. new_type = Type(vardeclarationchildren[1].children[0], data == "private", True) # construct variable with given type rightTypeDeclared = protocol.getTypeInlist(new_type) # new type encountered if rightTypeDeclared is None: protocol.listTypes.append(new_type) nvar = Variable(new_var, False, new_type, data == "public") protocol.listVar.append(nvar) mapVarType[new_var] = new_type # type already exists somewhere, we have to use it else: mapVarType[new_var] = rightTypeDeclared # constants are divided in public and private. nvar2 = Variable(new_var, False, new_type, data == "public") protocol.listVar.append(nvar2) # if rightTypeDeclared.public != new_type.public: # raise ProtocolError("Variable " + new_var + " in line " + str( # vardeclaration.meta.line) + " already defined with another privacy") # if the var is declared in public bloc, the variable cannot be honest if rightTypeDeclared.honest and data == "public": rightTypeDeclared.honest = False # transaction elif data == "transaction": new_trans = Transaction("", []) protocol.listTransactions.append(new_trans) for i in range(0, len(tree.children)): c = tree.children[i] res = exploreTree(c, protocol) if res is not None: new_trans.actions.append(res) # action : we should only be there if a transaction has been found previously elif data == "action": length = len(protocol.listTransactions) - 1 div = length / 24 modulo = length % 24 # if length < 24: # name = EGreekCharacters(modulo).__str__ # else: # name = EGreekCharacters(modulo).__str__ + str(div) # name += str(len(protocol.listTransactions[len(protocol.listTransactions) - 1].actions)) \ # + tree.children[0].children[0] type = tree.children[0] actionchildren = removeTokenSpace(tree) new_action = Action( type == "in", int(actionchildren[0].children[0].value), EGreekCharacters(modulo), str( len(protocol.listTransactions[len(protocol.listTransactions) - 1].actions)), exploreTree(actionchildren[1], protocol)) updateParent(new_action.rootTerm) return new_action # term : we should only be there if an action has been found previously elif data == "term": # primitive (except concat) if tree.children[0].data == "primitive": arguments = [] # remove space primitivechildren = removeTokenSpace(tree) # let's explore arguments for i in range(1, len(primitivechildren)): arg = exploreTree(primitivechildren[i], protocol) if isinstance(arg, str): # variable arg = mapVarType[arg] arguments.append(arg) try: prim = getPrimitive(primitivechildren[0].children[0].__str__(), arguments) except ProtocolError as err: raise ProtocolError( str(err.args[0]) + " at line " + str(tree.meta.line)) return prim # special case of concat which is not written concat(var1,var2) but <var1,var2> elif tree.children[0].data == "concat": # primitive concat arguments = [] # remove space concatchildren = removeTokenSpace(tree.children[0]) for i in range(0, len(concatchildren)): arg = exploreTree(concatchildren[i], protocol) if isinstance(arg, str): # variable arg = mapVarType[arg] arguments.append(arg) try: prim = getPrimitive("concat", arguments) except ProtocolError as err: raise ProtocolError( str(err.args[0]) + " at line " + str(tree.meta.line)) return prim # vardeclaration : on the fly declarations elif tree.children[0].data == "typevardeclaration": vardeclaration = tree.children[0] vardeclarationchildren = removeTokenSpace(vardeclaration) # variable declared on the flight new_var = vardeclarationchildren[0].children[0] rightTypeDeclared = exploreTree(vardeclarationchildren[1], protocol) # type of variables declared on the flight are constants and cannot be honest if isinstance(rightTypeDeclared, Type): rightTypeDeclared.honest = False var = Variable(new_var, True, rightTypeDeclared, True) var.foundInProtocol = True protocol.listVar.append(var) return var # variable else: try: var = protocol.getVarInlist(tree.children[0].children[0]) var.foundInProtocol = True return var except ProtocolError: raise ProtocolError("Variable undeclared at line " + str(tree.meta.line) + " : " + tree.children[0].children[0]) # constructed type elif data == "constructedtype": # primitive (except concat) if tree.children[0].data == "primitive": arguments = [] # remove space primitivechildren = removeTokenSpace(tree) # let's explore arguments for i in range(1, len(primitivechildren)): arg = exploreTree(primitivechildren[i], protocol) arguments.append(arg) try: prim = getPrimitive(primitivechildren[0].children[0].__str__(), arguments, True) except ProtocolError as err: raise ProtocolError( str(err.args[0]) + " at line " + str(tree.meta.line)) return prim # special case of concat which is not written concat(var1,var2) but <var1,var2> elif tree.children[0].data == "typeconcat": # primitive concat arguments = [] # remove space concatchildren = removeTokenSpace(tree.children[0]) for i in range(0, len(concatchildren)): arg = exploreTree(concatchildren[i], protocol) arguments.append(arg) try: prim = getPrimitive("concat", arguments, True) except ProtocolError as err: raise ProtocolError( str(err.args[0]) + " at line " + str(tree.meta.line)) return prim # type declared elif tree.children[0].data == "type": typechildren = tree.children[0] # temporary attributes for Type element type = Type(typechildren.children[0], False, True) # rightTypeDeclared represents the already defined type that this type has rightTypeDeclared = protocol.getTypeInlist(type) if rightTypeDeclared is None: # type currently doesn't exist protocol.listTypes.append(type) rightTypeDeclared = type return rightTypeDeclared # unrecognized item, probably an "unknown" non-terminal for Lark else: print(tree.data) raise ProtocolError("Unknown expression at line " + str(tree.meta.line) + " : " + tree.children[0].__str__())