def applyBSTransform(sdl_file, config): """ read sdl file to determine interfaces and variable types, etc""" global assignInfo sdl.parseFile(sdl_file, False, ignoreCloudSourcing=True) assignInfo = sdl.getAssignInfo() allTypes = sdl.getVarTypes() varTypes = allTypes.get(sdl.TYPES_HEADER) # 1. extract each function inputSchemeApi = {keygenFuncName:None, signFuncName:None, verifyFuncName:None} funcVars = set() for i in config.functionOrder: print("processing func: ", i) inputSchemeApi[i], _funcVars = getInterface(assignInfo, i) funcVars = funcVars.union(_funcVars) funcVars = list(funcVars) print("funcVars: ", funcVars) schemeTypes = getInterfaceTypes(allTypes, funcVars) name = sdl.assignInfo[sdl.NONE_FUNC_NAME][sdl.SDL_NAME].getAssignNode().getRight().getAttribute() setting = sdl.assignInfo[sdl.NONE_FUNC_NAME][sdl.ALGEBRAIC_SETTING].getAssignNode().getRight().getAttribute() schemeCalls = {} funcInput = {} funcOutput = {} for i in config.functionOrder: schemeCalls[i] = "%s.%s(%s)" % (name, i, getArgString(inputSchemeApi[i][inputKeyword])) print("funcCall: ", schemeCalls[i]) funcInput[i] = inputSchemeApi[i][inputKeyword] funcOutput[i] = inputSchemeApi[i][outputKeyword] bsT = BSTransform(assignInfo, varTypes, schemeTypes, schemeCalls, funcInput, funcOutput) bsT.setSchemeName(name) bsT.setSetting(setting) bsT.constructSDL(config) return
def runAutoStrong(sdlFile, config, options, sdlVerbose=False): sdl.parseFile(sdlFile, sdlVerbose, ignoreCloudSourcing=True) global assignInfo assignInfo = sdl.getAssignInfo() setting = sdl.assignInfo[sdl.NONE_FUNC_NAME][ALGEBRAIC_SETTING].getAssignNode().getRight().getAttribute() assert setting == sdl.SYMMETRIC_SETTING, "AutoStrong requires a symmetric scheme for simplicity." origVarTypes = dict(sdl.getVarTypes().get(sdl.TYPES_HEADER)) # extract property 1 details... generators = [] if hasattr(config, "setupFuncName"): setupConfig = sdl.getVarInfoFuncStmts( config.setupFuncName ) theStmt, theTypes = setupConfig[0], setupConfig[1] extractGenerators(theStmt, theTypes, generators) if hasattr(config, "keygenFuncName"): keygenConfig = sdl.getVarInfoFuncStmts( config.keygenFuncName ) theStmt, theTypes = keygenConfig[0], keygenConfig[1] extractGenerators(theStmt, theTypes, generators) signConfig = sdl.getVarInfoFuncStmts( config.signFuncName ) signStmts, signTypes = signConfig[0], signConfig[1] extractGenerators(signStmts, signTypes, generators) verifyConfig = sdl.getVarInfoFuncStmts( config.verifyFuncName ) theStmt, theTypes = verifyConfig[0], verifyConfig[1] extractGenerators(theStmt, theTypes, generators) assert len(generators) != 0, "signature scheme does not select any generators?" baseGen = generators[0] print("Base generator: ", baseGen) generators.remove(baseGen) print("Other generator: ", generators) #get config parameters msg = config.messageVar msgList = traceMessage(signStmts, signTypes, msg) if len(msgList) == 0: # msg used directly msgVar = msg else: # indirection on msg msgList.append(msg) msgVar = msgList print("msgVar: ", msgVar) sigVar = config.signatureVar (name, varInf) = getVarNameEntryFromAssignInfo(assignInfo, sigVar) if name != config.signFuncName: sys.exit("runAutoStrong: '%s' not in the sign function." % sigVar) #print("identified signature: ", varInf.getAssignNode()) listVars = varInf.getListNodesList() if len(listVars) == 0: listVars.append(sigVar) # probably just one element in signature #print("list of possible vars: ", listVars) sigma = property1Extract(config.signFuncName, assignInfo, listVars, msgVar) #if testForSUCMA: # quick test for whether scheme is SU-CMA secure already # sigma['sigma1'] += sigma['sigma2'] # sigma['sigma2'] = [] if sdlVerbose: print("sigma1 => ", sigma['sigma1']) print("sigma2 => ", sigma['sigma2']) prop2Result = property2Extract(config.verifyFuncName, assignInfo, baseGen, generators, sigma) noSigma2Result = noSigma2Check(sigma) if options.get(skipTransform): return "skip_transform" if prop2Result and not noSigma2Result: print("Applying BSW transformation...") # extract types for all variables varTypes = sdl.getVarTypes().get(TYPES_HEADER) for i in config.functionOrder: #print("Processing func: ", i) varTypes.update( sdl.getVarTypes().get(i) ) #print("Type variables for all: ", varTypes.keys()) bsw = BSWTransform(assignInfo, origVarTypes, varTypes, msgVar, msgList) newSDL = bsw.constructSDL(config, options, sigma) return newSDL elif prop2Result and noSigma2Result: #print("Signature Scheme Already Strongly Unforgeable!") sys.exit(0) else: print("Applying BS transformation...") return applyBSTransform(sdlFile, config)
def main(sdlFile, config, sdlVerbose=False): sdl.parseFile2(sdlFile, sdlVerbose, ignoreCloudSourcing=True) global assignInfo assignInfo = sdl.getAssignInfo() setting = sdl.assignInfo[sdl.NONE_FUNC_NAME][ALGEBRAIC_SETTING].getAssignNode().getRight().getAttribute() bv_name = sdl.assignInfo[sdl.NONE_FUNC_NAME][BV_NAME].getAssignNode().getRight().getAttribute() typesBlock = sdl.getFuncStmts( TYPES_HEADER ) print("name is", bv_name) print("setting is", setting) lines = list(typesBlock[0].keys()) lines.sort() typesBlockLines = [ i.rstrip() for i in sdl.getLinesOfCodeFromLineNos(lines) ] begin = ["BEGIN :: " + TYPES_HEADER] end = ["END :: " + TYPES_HEADER] newLines0 = [ BV_NAME + " := " + bv_name, SETTING + " := " + sdl.ASYMMETRIC_SETTING ] newLines1 = begin + typesBlockLines + end assert setting == sdl.SYMMETRIC_SETTING, "No need to convert to asymmetric setting." # determine user preference in terms of keygen or encrypt contarget = sdl.assignInfo[sdl.NONE_FUNC_NAME]['short'] if contarget: target = contarget.getAssignNode().right.getAttribute() if contarget == None: short = SHORT_KEYS else: short = target print("reducing size of '%s'" % short) varTypes = dict(sdl.getVarTypes().get(TYPES_HEADER)) if not hasattr(config, 'schemeType'): sys.exit("'schemeType' option missing in specified config file.") if config.schemeType == PUB_SCHEME: (stmtS, typesS, depListS, depListNoExpS, infListS, infListNoExpS) = sdl.getVarInfoFuncStmts( config.setupFuncName ) (stmtK, typesK, depListK, depListNoExpK, infListK, infListNoExpK) = sdl.getVarInfoFuncStmts( config.keygenFuncName ) (stmtE, typesE, depListE, depListNoExpE, infListE, infListNoExpE) = sdl.getVarInfoFuncStmts( config.encryptFuncName ) (stmtD, typesD, depListD, depListNoExpD, infListD, infListNoExpD) = sdl.getVarInfoFuncStmts( config.decryptFuncName ) varTypes.update(typesS) varTypes.update(typesK) varTypes.update(typesE) varTypes.update(typesD) # TODO: expand search to encrypt and portentially setup pairingSearch = [stmtD] # aka start with decrypt. elif config.schemeType == SIG_SCHEME: if hasattr(config, 'setupFuncName'): (stmtS, typesS, depListS, depListNoExpS, infListS, infListNoExpS) = sdl.getVarInfoFuncStmts( config.setupFuncName ) (stmtK, typesK, depListK, depListNoExpK, infListK, infListNoExpK) = sdl.getVarInfoFuncStmts( config.keygenFuncName ) (stmtSi, typesSi, depListSi, depListNoExpSi, infListSi, infListNoExpSi) = sdl.getVarInfoFuncStmts( config.signFuncName ) (stmtV, typesV, depListV, depListNoExpV, infListV, infListNoExpV) = sdl.getVarInfoFuncStmts( config.verifyFuncName ) varTypes.update(typesK) varTypes.update(typesSi) varTypes.update(typesV) pairingSearch = [stmtV] # aka start with verify # sys.exit("Still working on this...") else: sys.exit("'schemeType' options are 'PUB' or 'SIG'") generators = [] print("List of generators for scheme") if hasattr(config, "extraSetupFuncName"): (stmtSe, typesSe, depListSe, depListNoExpSe, infListSe, infListNoExpSe) = sdl.getVarInfoFuncStmts( config.extraSetupFuncName ) extractGeneratorList(stmtSe, typesSe, generators) varTypes.update(typesSe) if hasattr(config, 'setupFuncName'): extractGeneratorList(stmtS, typesS, generators) # extract generators from setup if defined else: sys.exit("Assumption failed: setup not defined for this function. Where to extract generators?") # need a Visitor class to build these variables # TODO: expand to other parts of algorithm including setup, keygen, encrypt hashVarList = [] pair_vars_G1_lhs = [] pair_vars_G1_rhs = [] gpv = GetPairingVariables(pair_vars_G1_lhs, pair_vars_G1_rhs) for eachStmt in pairingSearch: lines = eachStmt.keys() for i in lines: if type(eachStmt[i]) == sdl.VarInfo: print("Each: ", eachStmt[i].getAssignNode()) cfp = CheckForPairing() if eachStmt[i].getHasPairings(): sdl.ASTVisitor( gpv ).preorder( eachStmt[i].getAssignNode() ) elif eachStmt[i].getHashArgsInAssignNode(): # in case, there's a hashed values...build up list and check later to see if it appears # in pairing variable list hashVarList.append(str(eachStmt[i].getAssignVar())) else: assignNode = eachStmt[i].getAssignNode() sdl.ASTVisitor( cfp ).preorder( assignNode ) if cfp.getHasPairings(): sdl.ASTVisitor( gpv ).preorder( assignNode ) constraintList = [] # determine if any hashed values in decrypt show up in a pairing for i in hashVarList: if i in pair_vars_G1_lhs or i in pair_vars_G1_rhs: constraintList.append(i) print("pair vars LHS:", pair_vars_G1_lhs) print("pair vars RHS:", pair_vars_G1_rhs) if config.schemeType == SIG_SCHEME: sys.exit(0) # TODO: need to resolve when to incorporate the split pairings technique print("list of gens :", generators) info = {} info[ 'G1_lhs' ] = (pair_vars_G1_lhs, assignTraceback(generators, varTypes, pair_vars_G1_lhs, constraintList)) info[ 'G1_rhs' ] = (pair_vars_G1_rhs, assignTraceback(generators, varTypes, pair_vars_G1_rhs, constraintList)) print("info => G1 lhs : ", info['G1_lhs']) print("info => G1 rhs : ", info['G1_rhs']) print("<===== Determine Asymmetric Generators =====>") (generatorLines, generatorMapG1, generatorMapG2) = Step1_DeriveSetupGenerators(generators, info) print("Generators in G1: ", generatorMapG1) print("Generators in G2: ", generatorMapG2) print("<===== Determine Asymmetric Generators =====>\n") print("<===== Generate XOR clauses =====>") # let the user's preference for fixing the keys or ciphertext guide this portion of the algorithm. # info[ 'G1' ] : represents (varKeyList, depVarMap). assert len(pair_vars_G1_lhs) == len(pair_vars_G1_rhs), "Uneven number of pairings. Please inspect your bv file." varsLen = len(pair_vars_G1_lhs) xorList = [] for i in range(varsLen): xor = BinaryNode(ops.XOR) xor.left = BinaryNode(pair_vars_G1_lhs[i]) xor.right = BinaryNode(pair_vars_G1_rhs[i]) xorList.append(xor) ANDs = [ BinaryNode(ops.AND) for i in range(len(xorList)-1) ] for i in range(len(ANDs)): ANDs[i].left = BinaryNode.copy(xorList[i]) if i < len(ANDs)-1: ANDs[i].right = ANDs[i+1] else: ANDs[i].right = BinaryNode.copy(xorList[i+1]) print("XOR clause: ", ANDs[0]) txor = transformXOR(None) # accepts dictionary of fixed values sdl.ASTVisitor(txor).preorder(ANDs[0]) print("<===== Generate XOR clauses =====>") constraints = "[]" fileSuffix, resultDict = searchForSolution(short, constraintList, txor, varTypes, config) xorVarMap = txor.getVarMap() if short != SHORT_FORALL: res, resMap = NaiveEvaluation(resultDict, short) print("Group Mapping: ", res) # determine whether to make True = G1 and False = G2. # It depends on which counts more since they're interchangeable... groupInfo = DeriveGeneralSolution(res, resMap, xorVarMap, info) else: groupInfo = DeriveSpecificSolution(resultDict, xorVarMap, info) groupInfo['generators'] = generators groupInfo['generatorMapG1'] = generatorMapG1 groupInfo['generatorMapG2'] = generatorMapG2 groupInfo['baseGeneratorG1'] = info['baseGeneratorG1'] # usually 'g' groupInfo['baseGeneratorG2'] = info['baseGeneratorG2'] groupInfo['varTypes'] = {} groupInfo['varTypes'].update(varTypes) noChangeList = [] newLinesSe = [] newLinesS = [] entireSDL = sdl.getLinesOfCode() if hasattr(config, "extraSetupFuncName"): print("<===== transforming %s =====>" % config.extraSetupFuncName) newLinesSe = transformFunction(entireSDL, config.extraSetupFuncName, stmtSe, groupInfo, noChangeList, generatorLines) print("<===== transforming %s =====>" % config.extraSetupFuncName) if hasattr(config, 'setupFuncName'): print("<===== transforming %s =====>" % config.setupFuncName) newLinesS = transformFunction(entireSDL, config.setupFuncName, stmtS, groupInfo, noChangeList, generatorLines) print("<===== transforming %s =====>" % config.setupFuncName) print("<===== transforming %s =====>" % config.keygenFuncName) newLinesK = transformFunction(entireSDL, config.keygenFuncName, stmtK, groupInfo, noChangeList) print("<===== transforming %s =====>" % config.keygenFuncName) if config.schemeType == PUB_SCHEME: print("<===== transforming %s =====>" % config.encryptFuncName) newLines2 = transformFunction(entireSDL, config.encryptFuncName, stmtE, groupInfo, noChangeList) print("<===== transforming %s =====>" % config.encryptFuncName) print("<===== transforming %s =====>" % config.decryptFuncName) newLines3 = transformFunction(entireSDL, config.decryptFuncName, stmtD, groupInfo, noChangeList) print("<===== transforming %s =====>" % config.decryptFuncName) elif config.schemeType == SIG_SCHEME: print("<===== transforming %s =====>" % config.signFuncName) newLines2 = transformFunction(entireSDL, config.signFuncName, stmtSi, groupInfo, noChangeList) print("<===== transforming %s =====>" % config.signFuncName) print("<===== transforming %s =====>" % config.verifyFuncName) newLines3 = transformFunction(entireSDL, config.verifyFuncName, stmtV, groupInfo, noChangeList) print("<===== transforming %s =====>" % config.verifyFuncName) # debug print_sdl(False, newLinesS, newLinesK, newLines2, newLines3) outputFile = bv_name + "_asym_" + fileSuffix writeConfig(outputFile + ".bv", newLines0, newLines1, newLinesSe, newLinesS, newLinesK, newLines2, newLines3) return outputFile