- Code cleanup.

- Removed the need for local temp files.
This commit is contained in:
ccremers 2005-03-04 16:23:22 +00:00
parent 470da10745
commit eec5057460
4 changed files with 159 additions and 245 deletions

View File

@ -4,24 +4,6 @@
# #
# (c)2004 Cas Cremers # (c)2004 Cas Cremers
# #
# Input of this script:
#
# - A number on the commandline of stuff to test
# - A list of files on stdin to be used (lines starting with '#' are
# ignored)
#
#
# Tips and tricks:
#
# Use e.g.
# $ ulimit -v 100000
# to counteract memory problems
#
# If you know where to look, use
# $ ls s*.spdl t*.spdl -1 | ./multiprotocoltest.py 2
# To verify combos of protocols starting with s and t
#
# *********************** # ***********************
# MODULES # MODULES
# *********************** # ***********************
@ -31,9 +13,9 @@ import sys
import string import string
import commands import commands
import copy import copy
from tempfile import NamedTemporaryFile
from optparse import OptionParser from optparse import OptionParser
# My own stuff
import tuplesdo import tuplesdo
import scythertest import scythertest
import protocollist import protocollist
@ -43,28 +25,12 @@ import protocollist
# PARAMETERS # PARAMETERS
# *********************** # ***********************
# Temporary files
TempFileList = "scyther-blap.tmp"
TempFileTuples = "scyther-blip.tmp"
# External programs
TupleProgram = "./tuples.py"
# Some default settings for Agents, untrusted e with sk(e) and k(a,e) etc.
ScytherDefaults = "--summary"
IncludeProtocols = '../spdl/spdl-defaults.inc'
# Some protocols are causing troubles: this is a hard-coded filter to exclude
# the problem children. Unfair, yes. Practical, yes.
#SkipList = [ 'gong-nonce.spdl', 'gong-nonce-b.spdl', 'splice-as-hc.spdl', 'kaochow-palm.spdl' ]
SkipList = []
ClaimToResultMap = {} # maps protocol claims to correctness in singular tests (0,1) ClaimToResultMap = {} # maps protocol claims to correctness in singular tests (0,1)
ProtocolToFileMap = {} # maps protocol names to file names ProtocolToFileMap = {} # maps protocol names to file names
ProtocolToStatusMap = {} # maps protocol names to status: 0 all false, 1 all correct, otherwise (2) mixed ProtocolToStatusMap = {} # maps protocol names to status: 0 all false, 1 all correct, otherwise (2) mixed
ProtocolToEffectsMap = {} # maps protocols that help create multiple flaws, to the protocol names of the flaws they caused ProtocolToEffectsMap = {} # maps protocols that help create multiple flaws, to the protocol names of the flaws they caused
CommandPrefix = "not yet initialised." CommandPrefix = ""
ArgumentsList = [] # argument lists that have been displayed onscreen ArgumentsList = [] # argument lists that have been displayed onscreen
# Ugly hack. Works. # Ugly hack. Works.
@ -122,6 +88,8 @@ def PrintProtStatus (file, prname):
# Returns a dictionary of claim -> bool; where 1 means that it is # Returns a dictionary of claim -> bool; where 1 means that it is
# correct, and 0 means that it is false (i.e. there exists an attack) # correct, and 0 means that it is false (i.e. there exists an attack)
def ScytherEval (plist): def ScytherEval (plist):
global options
# Flush before trying (possibly fatal) external commands # Flush before trying (possibly fatal) external commands
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()
@ -173,6 +141,8 @@ LastProgress = {}
ProgressBarWidth = 50 ProgressBarWidth = 50
def ShowProgress (i,n,txt): def ShowProgress (i,n,txt):
global options
def IntegerPart (x): def IntegerPart (x):
return int (( x * i ) / n) return int (( x * i ) / n)
@ -181,13 +151,13 @@ def ShowProgress (i,n,txt):
percentage = IntegerPart (100) percentage = IntegerPart (100)
factor = IntegerPart (ProgressBarWidth) factor = IntegerPart (ProgressBarWidth)
showme = 0 showme = False
if LastProgress.has_key(n): if LastProgress.has_key(n):
if LastProgress[n]<>(factor,txt): if LastProgress[n]<>(factor,txt):
showme = 1 showme = True
else: else:
showme = 1 showme = True
if showme == 1: if showme:
bar = "\r[" bar = "\r["
i = 0 i = 0
while i < ProgressBarWidth: while i < ProgressBarWidth:
@ -202,6 +172,8 @@ def ShowProgress (i,n,txt):
LastProgress[n] = (factor, txt) LastProgress[n] = (factor, txt)
def ClearProgress (n,txt): def ClearProgress (n,txt):
global options
if not options.progressbar: if not options.progressbar:
return return
bar = " " * (1 + ProgressBarWidth + 2 + 5 + len(txt)) bar = " " * (1 + ProgressBarWidth + 2 + 5 + len(txt))
@ -279,7 +251,7 @@ def DescribeContext (filep, protocols, claim):
# the protocol of the claim. However, if the # the protocol of the claim. However, if the
# partner protocol is completely correct or # partner protocol is completely correct or
# completely false, we summarize. # completely false, we summarize.
summary = 0 summary = False
all = 0 all = 0
if claim.split()[0] <> prname: if claim.split()[0] <> prname:
count = [0,0] count = [0,0]
@ -287,12 +259,12 @@ def DescribeContext (filep, protocols, claim):
count[v] = count[v]+1 count[v] = count[v]+1
if count[0] == 0 and count[1] > 0: if count[0] == 0 and count[1] > 0:
all = 1 all = 1
summary = 1 summary = True
if count[1] == 0 and count[0] > 0: if count[1] == 0 and count[0] > 0:
all = 0 all = 0
summary = 1 summary = True
if summary == 1: if summary:
DC_Claim (cl.split()[0] + " *ALL*", all) DC_Claim (cl.split()[0] + " *ALL*", all)
else: else:
for cl,v in cllist: for cl,v in cllist:
@ -315,7 +287,7 @@ def RequiresAllProtocols (protocols, claim):
# claim was always false # claim was always false
return 0 return 0
# check for simple cases # check for simple cases
if int(TupleWidth) <= 2: if TupleWidth <= 2:
# nothing to remove # nothing to remove
return 1 return 1
@ -387,118 +359,104 @@ def SignalAttack (protocols, claim):
# #
# Furthermore, TempFileList is created. # Furthermore, TempFileList is created.
parser = OptionParser() def main():
scythertest.default_options(parser) global options
parser.add_option("-t","--tuplewidth", dest="tuplewidth", global processed, newattacks, StartSkip
global TupleWidth, TupleCount
parser = OptionParser()
scythertest.default_options(parser)
parser.add_option("-t","--tuplewidth", dest="tuplewidth",
default = 2, default = 2,
help = "number of concurrent protocols to test, >=2") help = "number of concurrent protocols to test, >=2")
parser.add_option("-p","--protocols", dest="protocols", parser.add_option("-p","--protocols", dest="protocols",
default = 0, default = 0,
help = "protocol selection (0: all, 1:literature only)") help = "protocol selection (0: all, 1:literature only)")
parser.add_option("-s","--start", dest="startpercentage", parser.add_option("-s","--start", dest="startpercentage",
default = 0, default = 0,
help = "start test at a certain percentage") help = "start test at a certain percentage")
parser.add_option("-B","--disable-progressbar", dest="progressbar", parser.add_option("-B","--disable-progressbar", dest="progressbar",
default = "True", default = "True",
action = "store_false", action = "store_false",
help = "suppress a progress bar") help = "suppress a progress bar")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
# Where should we start (if this is a number) # Where should we start (if this is a number)
StartPercentage = int (options.startpercentage) StartPercentage = int (options.startpercentage)
if StartPercentage < 0 or StartPercentage > 100: if StartPercentage < 0 or StartPercentage > 100:
print "Illegal range for starting percentage (0-100):", StartPercentage print "Illegal range for starting percentage (0-100):", StartPercentage
sys.exit() sys.exit()
# Send protocollist to temp file (is this necessary?) # Send protocollist to temp file (is this necessary?)
ProtocolFileList = protocollist.select(options.protocols) ProtocolFileList = protocollist.select(options.protocols)
ProtocolCount = len(ProtocolFileList) ProtocolCount = len(ProtocolFileList)
outp = open(TempFileList, 'w')
for l in ProtocolFileList:
outp.write(l + "\n")
outp.close()
# Determine arguments # Determine arguments
TupleWidth = str(options.tuplewidth) TupleWidth = int(options.tuplewidth)
# Match # Match
ScytherMethods = "--match=" + str(options.match) ScytherMethods = "--match=" + str(options.match)
# Method of bounding will be determined in ScytherEval # Method of bounding will be determined in ScytherEval
# Caching of single-protocol results for speed gain. # Caching of single-protocol results for speed gain.
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# #
# The script first computes the singular results for all the protocols # The script first computes the singular results for all the protocols
# and stores this in an array, or something like that. # and stores this in an array, or something like that.
print "Evaluating tuples of", TupleWidth, "for", ProtocolCount, "protocols, using the command '" + CommandPrefix + "'" TupleCount = tuplesdo.tuples_count(ProtocolCount, TupleWidth)
i = 0 print "Evaluating", TupleCount, "tuples of", TupleWidth, "for", ProtocolCount, "protocols."
while i < ProtocolCount: i = 0
while i < ProtocolCount:
ShowProgress (i, ProtocolCount,ProtocolFileList[i]+safetxt) ShowProgress (i, ProtocolCount,ProtocolFileList[i]+safetxt)
ScytherEval1 ( ProtocolFileList[i] ) ScytherEval1 ( ProtocolFileList[i] )
i = i + 1 i = i + 1
ClearProgress(ProtocolCount, safetxt) ClearProgress(ProtocolCount, safetxt)
print "Evaluated single results." print "Evaluated single results."
# Show classification # Show classification
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# #
print "Correct protocols: ", GetKeys (ProtocolToStatusMap, 1) print "Correct protocols: ", GetKeys (ProtocolToStatusMap, 1)
print "Partly flawed protocols: ", GetKeys (ProtocolToStatusMap, 2) print "Partly flawed protocols: ", GetKeys (ProtocolToStatusMap, 2)
print "Completely flawed protocols: ", GetKeys (ProtocolToStatusMap, 0) print "Completely flawed protocols: ", GetKeys (ProtocolToStatusMap, 0)
# Computation of combined list. # Testing of protocol tuples
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# #
# We use the tuple script to generate the list of tuples we need. # We take the list of tuples and test each combination.
# We use a temporary file (again) to store that list.
# This requires that 'tuples.py' is in the same directory.
lstatus=os.system(TupleProgram + ' ' + TupleWidth + ' <' + TempFileList + ' >' + TempFileTuples) processed = 0
newattacks = 0
StartSkip = 0
inp = open(TempFileTuples, 'r') # Possibly skip some
TupleCount = 0 if StartPercentage > 0:
for x in inp:
TupleCount = TupleCount + 1
inp.close()
print "Commencing test for", TupleCount, "protocol combinations."
# Testing of protocol tuples
#----------------------------------------------------------------------
#
# We take the list of tuples and test each combination.
inp = open(TempFileTuples, 'r')
processed = 0
newattacks = 0
StartSkip = 0
# Possibly skip some
if StartPercentage > 0:
StartSkip = int ((TupleCount * StartPercentage) / 100) StartSkip = int ((TupleCount * StartPercentage) / 100)
print "Resuming. Skipping the first", StartSkip,"tuples." print "Resuming. Skipping the first", StartSkip,"tuples."
# #
# Check all these protocols # Check all these protocols
# #
for tline in inp: def process(protocols):
global processed, newattacks, StartSkip
if (processed >= StartSkip): if (processed >= StartSkip):
# #
# Get the next tuple # Get the next tuple
# #
protocols = tline.split()
ShowProgress (processed, TupleCount, " ".join(protocols) + safetxt) ShowProgress (processed, TupleCount, " ".join(protocols) + safetxt)
# #
# Determine whether there are valid claims at all in # Determine whether there are valid claims at all in
# this set of file names # this set of file names
# #
has_valid_claims = 0 has_valid_claims = False
for prname in GetListKeys (ProtocolToFileMap, protocols): for prname in GetListKeys (ProtocolToFileMap, protocols):
if ProtocolToStatusMap[prname] != 0: if ProtocolToStatusMap[prname] != 0:
has_valid_claims = 1 has_valid_claims = True
if has_valid_claims == 1: if has_valid_claims:
# #
# Use Scyther to verify the claims # Use Scyther to verify the claims
# #
@ -515,19 +473,24 @@ for tline in inp:
# Next! # Next!
processed = processed + 1 processed = processed + 1
inp.close()
ClearProgress (TupleCount, safetxt) tuplesdo.tuples_do(process,ProtocolFileList,TupleWidth)
print "Processed", processed,"tuple combinations in total."
if StartSkip > 0: ClearProgress (TupleCount, safetxt)
print "Processed", processed,"tuple combinations in total."
if StartSkip > 0:
print "In this session, checked the last",(processed - StartSkip),"tuples. " print "In this session, checked the last",(processed - StartSkip),"tuples. "
print "Found", newattacks, "new attacks." print "Found", newattacks, "new attacks."
if newattacks > 0: if newattacks > 0:
print " These were helped by:" print " These were helped by:"
for helper in ProtocolToEffectsMap.keys(): for helper in ProtocolToEffectsMap.keys():
sys.stdout.write (" ") sys.stdout.write (" ")
PrintProtStatus (sys.stdout, helper) PrintProtStatus (sys.stdout, helper)
sys.stdout.write (". This possibly breaks " + str(ProtocolToEffectsMap[helper]) + "\n") sys.stdout.write (". This possibly breaks " + str(ProtocolToEffectsMap[helper]) + "\n")
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()
if __name__ == '__main__':
main()

View File

@ -1,21 +0,0 @@
# Tuple module
#
# tuplesDo generates all unordered sets (in a list) of size n of the
# elements of the list l. The resulting lists (of length n) are passed
# to the function f.
def tuplesDo (f,l,n):
def tuplesDoRecurse (l,r):
if r and (len(r) == n):
f(r)
else:
if l and (n > 0):
# Larger size: we have options
# Option 1: include first
tuplesDoRecurse (l[1:], r + [l[0]])
# Option 2: exclude first
tuplesDoRecurse (l[1:], r)
tuplesDoRecurse (l,[])

View File

@ -1,51 +0,0 @@
#!/usr/bin/python
#
# Given a number of input lines on std and an argument int, this program
# generates unordered tuples, e.g.:
#
# arg: 2
# in: a
# b
# c
# d
#
# out: a,b
# a,c
# a,d
# b,c
# b,d
# c,d
#
# This should make it clear what happens.
#
import sys
import string
import tuplesdo
# Retrieve the tuple width
tuplesize = int(sys.argv[1])
# Read stdin into list and count
list = []
loop = 1
while loop:
line = sys.stdin.readline()
if line != '':
# not the end of the input
line = string.strip(line)
if line != '':
# not a blank line
list.append(line)
else:
# end of the input
loop = 0
def tuplesPrint (l, n):
def f (resultlist):
print " ".join(resultlist)
tuplesdo.tuplesDo (f, l, n)
# Generate tuples...
tuplesPrint (list, tuplesize)
# Thanks for your attention

View File

@ -4,18 +4,41 @@
# elements of the list l. The resulting lists (of length n) are passed # elements of the list l. The resulting lists (of length n) are passed
# to the function f. # to the function f.
def tuplesDo (f,l,n):
def tuplesDoRecurse (l,r): # First some generic combinatorial stuff
def faculty_gen(n,k):
if n <= k:
return 1
else:
return n * faculty_gen(n-1,k)
def faculty(n):
return faculty_gen(n,1)
def binomial(n,k):
b1 = faculty_gen(n,k)
b2 = faculty(n-k)
return b1/b2
# How many elements will there be?
def tuples_count (l,n):
return binomial(l,n)
# Generate those elements, and apply f
def tuples_do (f,l,n):
def recurse (l,r):
if r and (len(r) == n): if r and (len(r) == n):
f(r) f(r)
else: else:
if l and (n > 0): if l and (n > 0):
# Larger size: we have options # Larger size: we have options
# Option 1: include first # Option 1: include first
tuplesDoRecurse (l[1:], r + [l[0]]) recurse (l[1:], r + [l[0]])
# Option 2: exclude first # Option 2: exclude first
tuplesDoRecurse (l[1:], r) recurse (l[1:], r)
tuplesDoRecurse (l,[]) recurse (l,[])