- Working on new algorithm. Some memory error can occur.
This commit is contained in:
ccremers 2004-08-18 14:06:14 +00:00
parent c5695d6fe8
commit b2d21f0a8a
9 changed files with 418 additions and 341 deletions

View File

@ -36,6 +36,7 @@ Role I_E;
Role I_D; Role I_D;
static int indentDepth; static int indentDepth;
static int max_encryption_level;
#ifdef DEBUG #ifdef DEBUG
static char *explanation; // Pointer to a string that describes what we just tried to do static char *explanation; // Pointer to a string that describes what we just tried to do
@ -68,6 +69,7 @@ int iterate ();
void void
arachneInit (const System mysys) arachneInit (const System mysys)
{ {
Term GVT;
Roledef rd = NULL; Roledef rd = NULL;
Termlist tl, know0; Termlist tl, know0;
@ -102,8 +104,9 @@ arachneInit (const System mysys)
*/ */
INTRUDER = protocolCreate (makeGlobalConstant (" INTRUDER ")); INTRUDER = protocolCreate (makeGlobalConstant (" INTRUDER "));
GVT = makeGlobalVariable ("GlobalVariable");
add_event (SEND, NULL); add_event (SEND, GVT);
I_M = add_role ("I_M: Atomic message"); I_M = add_role ("I_M: Atomic message");
add_event (READ, NULL); add_event (READ, NULL);
@ -148,6 +151,18 @@ indentPrint ()
#endif #endif
} }
//! Print indented binding
void
binding_indent_print (Binding b, int flag)
{
indentPrint ();
if (flag)
eprintf ("!! ");
binding_print (b);
eprintf ("\n");
}
//! Iterate but discard the info of the termlist //! Iterate but discard the info of the termlist
int int
mgu_iterate (const Termlist tl) mgu_iterate (const Termlist tl)
@ -161,7 +176,7 @@ mgu_iterate (const Termlist tl)
*@returns The number of goals added (for destructions) *@returns The number of goals added (for destructions)
*/ */
int int
add_read_goals (const int run, int old, int new) add_read_goals (const int run, const int old, const int new)
{ {
int count; int count;
int i; int i;
@ -170,11 +185,13 @@ add_read_goals (const int run, int old, int new)
sys->runs[run].length = new; sys->runs[run].length = new;
i = old; i = old;
rd = roledef_shift (sys->runs[run].start, i); rd = roledef_shift (sys->runs[run].start, i);
while (i < new) count = 0;
while (i < new && rd != NULL)
{ {
if (rd->type == READ) if (rd->type == READ)
{ {
goal_add (rd->message, run, i); goal_add (rd->message, run, i);
count++;
} }
rd = rd->next; rd = rd->next;
i++; i++;
@ -301,78 +318,43 @@ bind_existing_to_goal (const Binding b, const int index, const int run,
int subterm_iterate (Termlist substlist, Termlist keylist) int subterm_iterate (Termlist substlist, Termlist keylist)
{ {
int keycount;
int flag; int flag;
flag = 1;
if (goal_bind (b, run, index))
{
int keycount;
Termlist tl;
#ifdef DEBUG #ifdef DEBUG
if (DEBUGL (5)) if (DEBUGL (5))
{ {
binding_indent_print (b, 0);
indentPrint (); indentPrint ();
eprintf ("Adding key list : "); eprintf ("Adding key list for subterm iteration: ");
termlistPrint (keylist); termlistPrint (keylist);
eprintf ("\n"); eprintf ("\n");
} }
#endif #endif
flag = 1;
keycount = 0; keycount = 0;
while (flag && keylist != NULL) tl = keylist;
while (tl != NULL)
{ {
int keyrun; int keyrun;
goal_add (keylist->term, b->run_to, b->ev_to); goal_add (tl->term, b->run_to, b->ev_to);
keylist = keylist->next; tl = tl->next;
keycount++; keycount++;
} }
flag = flag && iterate (); flag = flag && iterate ();
while (keycount > 0) while (keycount > 0)
{ {
goal_remove_last (); goal_remove_last ();
keycount--; keycount--;
} }
termlistDestroy (keylist); termlistDestroy (keylist);
return flag;
}
int interm_iterate (Termlist substlist)
{
iterate ();
}
//----------------------------
// Roledef entry
rd = roledef_shift (sys->runs[run].start, index);
// Fix length
old_length = sys->runs[run].length;
if ((index + 1) > old_length)
{
newgoals = add_read_goals (run, old_length, index+1);
}
else
{
newgoals = 0;
}
#ifdef DEBUG
if (DEBUGL (3))
{
explanation = "Bind existing run (generic) ";
e_run = run;
e_term1 = b->term;
}
#endif
if (goal_bind (b, run, index))
{
if (subterm)
{
flag = termMguSubTerm (b->term, rd->message,
subterm_iterate, sys->know->inverses, NULL);
}
else
{
flag = termMguInTerm (b->term, rd->message,
interm_iterate);
}
} }
else else
{ {
@ -383,8 +365,33 @@ bind_existing_to_goal (const Binding b, const int index, const int run,
eprintf ("Aborted binding existing run because of cycle.\n"); eprintf ("Aborted binding existing run because of cycle.\n");
} }
#endif #endif
flag = 0;
} }
goal_unbind (b); goal_unbind (b);
return flag;
}
//----------------------------
// Roledef entry
rd = roledef_shift (sys->runs[run].start, index);
// Fix length
old_length = sys->runs[run].length;
if ((index + 1) > old_length)
newgoals = add_read_goals (run, old_length, index + 1);
else
newgoals = 0;
#ifdef DEBUG
if (DEBUGL (3))
{
explanation = "Bind existing run (generic) ";
e_run = run;
e_term1 = b->term;
}
#endif
flag = termMguSubTerm (b->term, rd->message,
subterm_iterate, sys->know->inverses, NULL);
// Reset length // Reset length
remove_read_goals (newgoals); remove_read_goals (newgoals);
sys->runs[run].length = old_length; sys->runs[run].length = old_length;
@ -404,7 +411,7 @@ bind_existing_run (const Binding b, const Protocol p, const Role r,
indentPrint (); indentPrint ();
eprintf ("Trying to bind "); eprintf ("Trying to bind ");
termPrint (b->term); termPrint (b->term);
eprintf (" to an existing instance of "); eprintf (" to an existing (of %i runs) instance of ", sys->maxruns);
termPrint (p->nameterm); termPrint (p->nameterm);
eprintf (", "); eprintf (", ");
termPrint (r->nameterm); termPrint (r->nameterm);
@ -447,9 +454,9 @@ bind_new_run (const Binding b, const Protocol p, const Role r,
eprintf (", run %i (subterm:%i)\n", run, subterm); eprintf (", run %i (subterm:%i)\n", run, subterm);
} }
#endif #endif
flag = bind_existing_to_goal (b, index, run, subterm); flag = bind_existing_to_goal (b, index, run, 1);
roleInstanceDestroy (sys);
remove_read_goals (newgoals); remove_read_goals (newgoals);
roleInstanceDestroy (sys);
return flag; return flag;
} }
@ -461,11 +468,9 @@ printSemiState ()
int open; int open;
List bl; List bl;
int binding_indent_print (void *data) int binding_state_print (void *dt)
{ {
indentPrint (); binding_indent_print ((Binding) dt, 1);
eprintf ("!! ");
binding_print (data);
return 1; return 1;
} }
@ -515,7 +520,7 @@ printSemiState ()
{ {
indentPrint (); indentPrint ();
eprintf ("!!\n"); eprintf ("!!\n");
list_iterate (sys->bindings, binding_indent_print); list_iterate (sys->bindings, binding_state_print);
} }
indentPrint (); indentPrint ();
eprintf ("!!\n"); eprintf ("!!\n");
@ -536,7 +541,9 @@ select_goal ()
{ {
List bl; List bl;
Binding best; Binding best;
float min_constrain;
min_constrain = 2; // 1 is the maximum, but we want to initialize it.
best = NULL; best = NULL;
bl = sys->bindings; bl = sys->bindings;
while (bl != NULL) while (bl != NULL)
@ -546,141 +553,20 @@ select_goal ()
b = (Binding) bl->data; b = (Binding) bl->data;
if (!b->done) if (!b->done)
{ {
// For now, we simply take the first encountered goal float cons;
return b;
cons = term_constrain_level (b->term);
if (cons < min_constrain)
{
min_constrain = cons;
best = b;
}
} }
bl = bl->next; bl = bl->next;
} }
return best; return best;
} }
//! Bind a regular goal
int
bind_goal_regular (const Binding b)
{
int flag;
/*
* This is a local function so we have access to goal
*/
int bind_this_role_send (Protocol p, Role r, Roledef rd, int index)
{
int test_unification (Termlist substlist)
{
// A unification exists; return the signal
return 0;
}
if (p == INTRUDER)
{
/* only bind to regular runs */
return 1;
}
else
{
// Test for interm unification
#ifdef DEBUG
if (DEBUGL (5))
{
indentPrint ();
eprintf ("Checking send candidate with message ");
termPrint (rd->message);
eprintf (" from ");
termPrint (p->nameterm);
eprintf (", ");
termPrint (r->nameterm);
eprintf (", index %i\n", index);
}
#endif
if (!termMguInTerm (b->term, rd->message, test_unification))
{
// A good candidate
#ifdef DEBUG
if (DEBUGL (5))
{
indentPrint ();
eprintf ("Term ");
termPrint (b->term);
eprintf (" can possibly be bound by role ");
termPrint (r->nameterm);
eprintf (", index %i\n", index);
}
#endif
return (bind_new_run (b, p, r, index, 0) &&
bind_existing_run (b, p, r, index, 0));
}
else
{
// Cannot unify: no attacks
return 1;
}
}
}
// Bind to all possible sends or intruder node;
#ifdef DEBUG
if (DEBUGL (5))
{
indentPrint ();
eprintf ("Try regular role send.\n");
}
#endif
flag = iterate_role_sends (bind_this_role_send);
#ifdef DEBUG
if (DEBUGL (5))
{
indentPrint ();
eprintf ("Try intruder send.\n");
}
#endif
return flag;
// return (flag && add_intruder_goal_iterate (b));
}
//! Bind an intruder goal to a regular run
int
bind_intruder_to_regular (Binding b)
{
int bind_this_roleevent (Protocol p, Role r, Roledef rd, int index)
{
int cannotUnify;
int test_unification (Termlist substlist, Termlist keylist)
{
// Signal that unification is possible.
return 0;
}
/**
* Note that we only bind to regular runs here
*/
if (p == INTRUDER)
{
return 1; // don't abort scans
}
else
{ // Test for subterm unification
if (termMguSubTerm
(b->term, rd->message, test_unification,
sys->know->inverses, NULL))
{
// cannot unify
return 1;
}
else
{
/**
* Either from an existing, or from a new run.
*/
return (bind_new_run (b, p, r, index, 1)
&& bind_existing_run (b, p, r, index, 1));
}
}
}
// Bind to all possible sends?
return iterate_role_sends (bind_this_roleevent);
}
//! Bind an intruder goal by intruder construction //! Bind an intruder goal by intruder construction
/** /**
* Handles the case where the intruder constructs a composed term himself. * Handles the case where the intruder constructs a composed term himself.
@ -696,9 +582,9 @@ bind_intruder_to_construct (const Binding b)
flag = 1; flag = 1;
term = b->term; term = b->term;
/** /**
* Two options. * Three options.
* *
* 1. Constructed from composite terms * 1. Constructed from smaller composite terms
*/ */
if (!realTermLeaf (term)) if (!realTermLeaf (term))
{ {
@ -706,6 +592,7 @@ bind_intruder_to_construct (const Binding b)
if (realTermTuple (term)) if (realTermTuple (term))
{ {
warning ("Goal that is a tuple should not occur!");
// tuple construction // tuple construction
t1 = term->left.op1; t1 = term->left.op1;
t2 = term->right.op2; t2 = term->right.op2;
@ -719,12 +606,61 @@ bind_intruder_to_construct (const Binding b)
goal_add (t1, b->run_to, b->ev_to); goal_add (t1, b->run_to, b->ev_to);
goal_add (t2, b->run_to, b->ev_to); goal_add (t2, b->run_to, b->ev_to);
#ifdef DEBUG
if (DEBUGL (3))
{
indentPrint ();
eprintf ("Constructing ");
termPrint (term);
eprintf (" from smaller terms ");
termPrint (t1);
eprintf (" and ");
termPrint (t2);
eprintf ("\n");
}
#endif
flag = flag && iterate (); flag = flag && iterate ();
goal_remove_last (); goal_remove_last ();
goal_remove_last (); goal_remove_last ();
} }
/** /**
* 2. Retrieved from M_0 * 2. Constructed from bigger term and decryption key
*/
/*
if (!realTermLeaf (term))
{
if (realTermEncrypt (term))
{
Term t1, t2;
t1 = term->left.op;
t2 = term->right.key;
goal_add (t1, b->run_to, b->ev_to);
goal_add (t2, b->run_to, b->ev_to);
#ifdef DEBUG
if (DEBUGL (3))
{
indentPrint ();
eprintf ("Deriving ");
termPrint (term);
eprintf (" from encrypted term ");
termPrint (t1);
eprintf (" and key ");
termPrint (t2);
eprintf ("\n");
}
#endif
flag = flag && iterate ();
goal_remove_last ();
goal_remove_last ();
}
}
*/
/**
* 3. Retrieved from M_0
*/ */
m0tl = knowledgeSet (sys->know); m0tl = knowledgeSet (sys->know);
while (flag && m0tl != NULL) while (flag && m0tl != NULL)
@ -747,15 +683,20 @@ bind_intruder_to_construct (const Binding b)
#ifdef DEBUG #ifdef DEBUG
if (DEBUGL (3)) if (DEBUGL (3))
{ {
if (DEBUGL (5))
{
binding_indent_print (b, 0);
}
indentPrint (); indentPrint ();
eprintf ("Retrieving "); eprintf ("Retrieving ");
termPrint (term); termPrint (term);
eprintf (" from the initial knowledge.\n"); eprintf (" from the initial knowledge.\n");
} }
#endif #endif
iterate (); flag = flag && iterate ();
} }
goal_unbind (b); goal_unbind (b);
roleInstanceDestroy (sys);
termlistSubstReset (subst); termlistSubstReset (subst);
termlistDelete (subst); termlistDelete (subst);
} }
@ -770,40 +711,96 @@ bind_intruder_to_construct (const Binding b)
} }
//! Bind an intruder goal //! Bind a regular goal
/**
* Computes F2 as in Athena explanations.
*/
int int
bind_goal_intruder (const Binding b) bind_goal_regular (const Binding b)
{ {
/**
* Special case: when the intruder can bind it to the initial knowledge.
*/
Termlist tl;
int flag; int flag;
flag = 1; /*
tl = knowledgeSet (sys->know); * This is a local function so we have access to goal
while (flag && tl != NULL) */
int bind_this_role_send (Protocol p, Role r, Roledef rd, int index)
{ {
int hasvars; int test_unification (Termlist substlist)
Termlist substlist; {
// A unification exists; return the signal
return 0;
}
substlist = termMguTerm (tl->term, b->term); // Test for interm unification
if (substlist != MGUFAIL) #ifdef DEBUG
if (DEBUGL (5))
{ {
// This seems to work indentPrint ();
flag = flag && iterate (); eprintf ("Checking send candidate with message ");
termlistSubstReset (substlist); termPrint (rd->message);
termlistDelete (substlist); eprintf (" from ");
termPrint (p->nameterm);
eprintf (", ");
termPrint (r->nameterm);
eprintf (", index %i\n", index);
} }
tl = tl->next; #endif
if (!termMguSubTerm
(b->term, rd->message, test_unification, sys->know->inverses, NULL))
{
int flag;
// A good candidate
#ifdef DEBUG
if (DEBUGL (5))
{
indentPrint ();
eprintf ("Term ");
termPrint (b->term);
eprintf (" can possibly be bound by role ");
termPrint (r->nameterm);
eprintf (", index %i\n", index);
} }
termlistDelete (tl); #endif
return (flag && bind_intruder_to_regular (b) && // Bind to existing run
bind_intruder_to_construct (b)); flag = bind_existing_run (b, p, r, index, 1);
if (p != INTRUDER)
{
// No intruder: bind to new run
flag = flag && bind_new_run (b, p, r, index, 1);
} }
return flag;
}
else
{
// Cannot unify: no attacks
return 1;
}
}
// Bind to all possible sends or intruder node;
#ifdef DEBUG
if (DEBUGL (5))
{
indentPrint ();
eprintf ("Try regular role send.\n");
}
#endif
flag = iterate_role_sends (bind_this_role_send);
#ifdef DEBUG
if (DEBUGL (5))
{
indentPrint ();
eprintf ("Try intruder send.\n");
}
#endif
// Other option: bind to term construction
flag = flag && bind_intruder_to_construct (b);
// Return result
return flag;
}
//! Bind a goal in all possible ways //! Bind a goal in all possible ways
int int
@ -811,16 +808,7 @@ bind_goal (const Binding b)
{ {
if (!b->done) if (!b->done)
{ {
int flag; return bind_goal_regular (b);
if (sys->runs[b->run_to].protocol == INTRUDER)
{
flag = bind_goal_intruder (b);
}
else
{
flag = bind_goal_regular (b);
}
return flag;
} }
else else
{ {
@ -906,6 +894,19 @@ prune ()
tl = tl->next; tl = tl->next;
} }
// Check for c-minimality
if (!bindings_c_minimal ())
{
#ifdef DEBUG
if (DEBUGL (3))
{
indentPrint ();
eprintf ("Pruned because this is not <=c-minimal.\n");
}
#endif
return 1;
}
return 0; return 0;
} }
@ -976,7 +977,7 @@ iterate ()
*/ */
b = select_goal (); b = select_goal ();
if (b != NULL) if (b == NULL)
{ {
/* /*
* all goals bound, check for property * all goals bound, check for property
@ -1046,11 +1047,26 @@ arachne ()
eprintf (", %i, ", index); eprintf (", %i, ", index);
roledefPrint (rd); roledefPrint (rd);
eprintf ("\n"); eprintf ("\n");
return 1;
} }
int determine_encrypt_max (Protocol p, Role r, Roledef rd, int index)
{
int tlevel;
tlevel = term_encryption_level (rd->message);
if (tlevel > max_encryption_level)
max_encryption_level = tlevel;
return 1;
}
max_encryption_level = 0;
iterate_role_sends (determine_encrypt_max);
#ifdef DEBUG #ifdef DEBUG
if (DEBUGL (1)) if (DEBUGL (1))
{ {
eprintf ("Maximum encryption level: %i\n", max_encryption_level);
iterate_role_sends (print_send); iterate_role_sends (print_send);
} }
#endif #endif
@ -1123,13 +1139,3 @@ arachne ()
cl = cl->next; cl = cl->next;
} }
} }
/**
* Done: add_read_goals, remove_read_goals.
*
* Now we must make the new algorithm.
* At role instance (of e.g. claim), fix add_read_goals.
*
* Iterate on roles. Create new roles for intruder (encrypt RRS, decrypt RRS, and M_0 S)
* Check for bindings_c_minimal.
*/

View File

@ -78,7 +78,8 @@ bindingDone ()
} }
//! Destroy graph //! Destroy graph
void goal_graph_destroy () void
goal_graph_destroy ()
{ {
if (graph != NULL) if (graph != NULL)
{ {
@ -88,7 +89,8 @@ void goal_graph_destroy ()
} }
//! Compute unclosed graph //! Compute unclosed graph
void goal_graph_create () void
goal_graph_create ()
{ {
int run, ev; int run, ev;
List bl; List bl;
@ -120,14 +122,18 @@ void goal_graph_create ()
Binding b; Binding b;
b = (Binding) bl->data; b = (Binding) bl->data;
if (b->done)
{
#ifdef DEBUG #ifdef DEBUG
if (graph_nodes (nodes, b->run_from, b->ev_from, b->run_to, b->ev_to) >= if (graph_nodes
(nodes * nodes)) (nodes, b->run_from, b->ev_from, b->run_to,
b->ev_to) >= (nodes * nodes))
error ("Node out of scope for %i,%i -> %i,%i.\n", b->run_from, error ("Node out of scope for %i,%i -> %i,%i.\n", b->run_from,
b->ev_from, b->run_to, b->ev_to); b->ev_from, b->run_to, b->ev_to);
#endif #endif
graph[graph_nodes (nodes, b->run_from, b->ev_from, b->run_to, b->ev_to)] graph[graph_nodes
= 1; (nodes, b->run_from, b->ev_from, b->run_to, b->ev_to)] = 1;
}
bl = bl->next; bl = bl->next;
} }
} }
@ -203,13 +209,14 @@ graph_nodes (const int nodes, const int run1, const int ev1, const int run2,
//! Print a binding (given a binding list pointer) //! Print a binding (given a binding list pointer)
int int
binding_print (void *bindany) binding_print (const Binding b)
{ {
Binding b; if (b->done)
eprintf ("Binding (%i,%i) --( ", b->run_from, b->ev_from);
b = (Binding) bindany; else
eprintf ("Binding (%i,%i) --->> (%i,%i)\n", b->run_from, b->ev_from, eprintf ("Unbound --( ");
b->run_to, b->ev_to); termPrint (b->term);
eprintf (" )->> (%i,%i)", b->run_to, b->ev_to);
return 1; return 1;
} }
@ -306,21 +313,35 @@ goal_unbind (const Binding b)
* *
*@returns True, if it's okay. If false, it needs to be pruned. *@returns True, if it's okay. If false, it needs to be pruned.
*/ */
int bindings_c_minimal () int
bindings_c_minimal ()
{ {
List bl; List bl;
// Ensure a state graph // Ensure a state graph
if (graph == NULL)
{
goal_graph_create (); goal_graph_create ();
// Recompute closure; does that work?
if (!warshall (graph, nodes))
{
// Hmm, cycle
return 0;
}
}
// For all goals // For all goals
bl = sys->bindings; bl = sys->bindings;
while (bl != NULL) while (bl != NULL)
{ {
Binding b; Binding b;
b = (Binding) bl->data;
if (b->done)
{
int run; int run;
int node_from; int node_from;
b = (Binding) bl->data;
node_from = node_number (b->run_from, b->ev_from); node_from = node_number (b->run_from, b->ev_from);
// Find all preceding events // Find all preceding events
for (run = 0; run <= sys->maxruns; run++) for (run = 0; run <= sys->maxruns; run++)
@ -347,10 +368,8 @@ int bindings_c_minimal ()
} }
} }
} }
}
bl = bl->next; bl = bl->next;
} }
return 1; return 1;
} }

View File

@ -34,7 +34,7 @@ int node_count ();
int node_number (int run, int ev); int node_number (int run, int ev);
int binding_print (void *bindany); int binding_print (Binding b);
void goal_add (Term term, const int run, const int ev); void goal_add (Term term, const int run, const int ev);
void goal_remove_last (); void goal_remove_last ();

View File

@ -109,6 +109,13 @@ makeGlobalConstant (const char *s)
return levelDeclare (symbolSysConst (s), 0, 0); return levelDeclare (symbolSysConst (s), 0, 0);
} }
//! Make a global variable
Term
makeGlobalVariable (const char *s)
{
return levelDeclare (symbolSysConst (s), 1, 0);
}
//! Clean up afterwards //! Clean up afterwards
void void
compilerDone (void) compilerDone (void)

View File

@ -12,6 +12,7 @@ void compile (Tac tc, int maxruns);
void preprocess (const System sys); void preprocess (const System sys);
Term findGlobalConstant (const char *s); Term findGlobalConstant (const char *s);
Term makeGlobalConstant (const char *s); Term makeGlobalConstant (const char *s);
Term makeGlobalVariable (const char *s);
void compute_role_variables (const System sys, Protocol p, Role r); void compute_role_variables (const System sys, Protocol p, Role r);
#endif #endif

48
src/ns3
View File

@ -12,8 +12,8 @@ protocol ns3(I,R)
send_1(I,R, {I,ni}pk(R) ); send_1(I,R, {I,ni}pk(R) );
read_2(R,I, {ni,nr}pk(I) ); read_2(R,I, {ni,nr}pk(I) );
send_3(I,R, {nr}pk(R) ); send_3(I,R, {nr}pk(R) );
claim_4(I,Secret,ni,nr); // claim_4(I,Secret,ni,nr);
claim_6(I,Nisynch); // claim_6(I,Nisynch);
} }
role R role R
@ -24,49 +24,13 @@ protocol ns3(I,R)
read_1(I,R, {I,ni}pk(R) ); read_1(I,R, {I,ni}pk(R) );
send_2(R,I, {ni,nr}pk(I) ); send_2(R,I, {ni,nr}pk(I) );
read_3(I,R, {nr}pk(R) ); read_3(I,R, {nr}pk(R) );
claim_5(R,Secret,ni,nr); claim_5(R,Secret,nr);
claim_7(R,Nisynch); // claim_5(R,Secret,ni,nr);
// claim_7(R,Nisynch);
} }
} }
// We leave out: M (from M_0) and Decryption, because that causes const Alice,Eve: Agent;
// problems with the inverse key.
protocol I_MALICE (I_F, I_T, I_V, I_R, I_E)
{
role I_F {
var t;
read_if1 (F,F, t);
}
role I_T {
var t;
read_it1 (T,T, t);
send_it2 (T,T, t);
send_it3 (T,T, t);
}
role I_V {
var t1;
var t2;
read_iv1 (V,V, t1);
read_iv2 (V,V, t2);
send_iv3 (V,V, (t1,t2));
}
role I_R {
var t1;
var t2;
read_ir1 (I_R,I_R, (t1,t2));
read_ir2 (I_R,I_R, t1);
send_ir3 (I_R,I_R, t2);
}
role I_E {
var t1;
var t2;
read_ie1 (I_E,I_E, t1);
read_ie2 (I_E,I_E, t2);
send_ie3 (I_E,I_E, {t1}t2);
}
}
const Alice,Bob,Eve: Agent;
untrusted Eve; untrusted Eve;
const nc: Nonce; const nc: Nonce;

View File

@ -1037,3 +1037,69 @@ term_rolelocals_are_variables ()
{ {
rolelocal_variable = 1; rolelocal_variable = 1;
} }
//! Count the encryption level of a term
int
term_encryption_level (const Term term)
{
int level, maxlevel, flag;
int nodel (const Term term)
{
if (realTermEncrypt (term))
{
level++;
if (level > maxlevel)
maxlevel = level;
}
return 1;
}
int noder (const Term term)
{
if (realTermEncrypt (term))
{
level--;
}
return 1;
}
maxlevel = 0;
level = 0;
flag = term_iterate_deVar (term, NULL, nodel, NULL, noder);
return maxlevel;
}
//! Determine 'constrained factor' of a term
/**
* Actually this is (#vars/structure).
* Thus, 0 means very constrained, no variables.
* Everything else has higher float, but always <=1. In fact, only a single variable has a level 1.
*/
float
term_constrain_level (const Term term)
{
int vars;
int structure;
int flag;
int leaf (const Term t)
{
structure++;
if (realTermVariable (t))
vars++;
return 1;
}
int nodel (const Term t)
{
structure++;
return 1;
}
if (term == NULL)
error ("Cannot determine constrain level of empty term.");
vars = 0;
structure = 0;
flag = term_iterate_deVar (term, leaf, nodel, NULL, NULL);
return ((float) vars / (float) structure);
}

View File

@ -175,5 +175,7 @@ int term_iterate_deVar (const Term term, int (*leaf) (), int (*nodel) (),
int term_iterate_leaves (const Term t, int (*func) ()); int term_iterate_leaves (const Term t, int (*func) ());
int term_iterate_open_leaves (const Term term, int (*func) ()); int term_iterate_open_leaves (const Term term, int (*func) ());
void term_rolelocals_are_variables (); void term_rolelocals_are_variables ();
int term_encryption_level (const Term term);
float term_constrain_level (const Term term);
#endif #endif

View File

@ -1,8 +1,10 @@
/** /**
* Temp file. I just forgot Warshall... * Warshall's algorithm for transitive closure computation.
*
*/ */
#include "warshall.h"
#include "debug.h"
void void
graph_fill (int *graph, int nodes, int value) graph_fill (int *graph, int nodes, int value)
{ {
@ -17,7 +19,8 @@ graph_fill (int *graph, int nodes, int value)
} }
//! Show a graph //! Show a graph
void graph_display (int *graph, int nodes) void
graph_display (int *graph, int nodes)
{ {
int i; int i;
@ -78,11 +81,20 @@ warshall (int *graph, int nodes)
{ {
if (graph[index (k, j)] == 1) if (graph[index (k, j)] == 1)
{ {
if (k == i) /**
* Previously, we tested k == i (self-loop).
* Now we test 2-node loops, i.e. wether there is also a path from i to k.
*/
if (graph[index (i, k)] > 0)
{ {
// Oh no! A cycle. // Oh no! A cycle.
graph[index (k, i)] = 2; graph[index (k, i)] = 2;
#ifdef DEBUG
if (DEBUGL (5))
{
graph_display (graph, nodes); graph_display (graph, nodes);
}
#endif
return 0; return 0;
} }
graph[index (k, i)] = 1; graph[index (k, i)] = 1;