- Minor improvements.

* Old bindings detections (immediately binds them to older binding)
  * Know_only derivation for keylevel lemmas.
This commit is contained in:
ccremers 2005-03-08 13:02:16 +00:00
parent 291353a14f
commit c8df32c7a2

View File

@ -211,6 +211,67 @@ getTermFunction (Term t)
return NULL; return NULL;
} }
//! Keylevel tester: can this term ever be sent at this keylevel?
int
isKeylevelRight (Term t, const int kl)
{
t = deVar (t);
if (realTermLeaf (t))
{
// Leaf
if (isTermVariable (t))
{
// Variables are okay
return 1;
}
else
{
// Constant, does it have a keylevel?
int mykl;
mykl = TermSymb (t)->keylevel;
if (mykl < INT_MAX)
{
// Sensible keylevel, so it must be possible
return (mykl <= kl);
}
else
{
// Never sent?
// So we can not expect it to come from that
return 0;
}
}
}
else
{
// Node
if (realTermTuple (t))
{
// Tuple
return isKeylevelRight (TermOp1 (t), kl)
&& isKeylevelRight (TermOp2 (t), kl);
}
else
{
// Crypt
return isKeylevelRight (TermOp1 (t), kl)
&& isKeylevelRight (TermOp2 (t), kl + 1);
}
}
}
//! Keylevel tester: can this term ever be sent at this keylevel?
/**
* Depends on the keylevel lemma (TODO) and the keylevel constructors in symbol.c
* The idea is that certain terms will never be sent.
*/
int
isPossiblySent (Term t)
{
return isKeylevelRight (t, 0);
}
//! Wrapper for roleInstance //! Wrapper for roleInstance
/** /**
*@return Returns the run number *@return Returns the run number
@ -247,6 +308,39 @@ semiRunDestroy ()
} }
} }
//! Fix the keylevels of any agents
/**
* We simply extract the agent names from m0 (ugly hack)
*/
void
fixAgentKeylevels (void)
{
Termlist tl, m0tl;
m0tl = knowledgeSet (sys->know);
tl = m0tl;
while (tl != NULL)
{
Term t;
t = deVar (tl->term);
if (realTermLeaf (t))
{
{
// a real agent type thing
if (TermSymb (t)->keylevel == INT_MAX)
{
// Fix the keylevel
TermSymb (t)->keylevel = 0;
}
}
}
tl = tl->next;
}
termlistDelete (m0tl);
}
//! After a role instance, or an extension of a run, we might need to add some goals //! After a role instance, or an extension of a run, we might need to add some goals
/** /**
* From old to new. Sets the new length to new. * From old to new. Sets the new length to new.
@ -689,18 +783,19 @@ bind_new_run (const Binding b, const Protocol p, const Role r,
* *
* Returns the baseline of the highest number + 1; thus the number of lines. * Returns the baseline of the highest number + 1; thus the number of lines.
*/ */
int ranks_to_lines(int *ranks, const int nodes) int
ranks_to_lines (int *ranks, const int nodes)
{ {
int ranksdone, baseline; int ranksdone, baseline;
ranksdone = 0; // All values lower than this have been done, so it is the next value ranksdone = 0; // All values lower than this have been done, so it is the next value
baseline = 0; // The line numbers that get assigned baseline = 0; // The line numbers that get assigned
while (1) while (1)
{ {
int newlow; int newlow;
int run; int run;
int i; int i;
// Determine lowest rank for non-intruder events, that has not been done // Determine lowest rank for non-intruder events, that has not been done
newlow = INT_MAX; newlow = INT_MAX;
run = 0; run = 0;
@ -741,7 +836,7 @@ int ranks_to_lines(int *ranks, const int nodes)
i++; i++;
} }
baseline++; baseline++;
ranksdone = newlow+1; ranksdone = newlow + 1;
} }
} }
@ -856,7 +951,7 @@ iterate_outgoing_arrows (void (*func) (), const int run, const int ev)
} }
else else
{ {
ev2++; ev2++;
} }
} }
@ -947,7 +1042,7 @@ latexSemiState ()
maxrank = graph_ranks (graph, ranks, nodes); // determine ranks maxrank = graph_ranks (graph, ranks, nodes); // determine ranks
// Convert ranks to lines // Convert ranks to lines
maxline = ranks_to_lines(ranks, nodes); maxline = ranks_to_lines (ranks, nodes);
// Draw headings (boxes) // Draw headings (boxes)
run = 0; run = 0;
@ -1025,10 +1120,10 @@ latexSemiState ()
} }
*/ */
/* /*
roledefPrint (rd); roledefPrint (rd);
eprintf (" $\\longrightarrow$ "); eprintf (" $\\longrightarrow$ ");
roledefPrint (rd2); roledefPrint (rd2);
*/ */
eprintf ("}{r%i}{r%i}", run, run2); eprintf ("}{r%i}{r%i}", run, run2);
delta = ranks[node_number (run2, ev2)] - myline; delta = ranks[node_number (run2, ev2)] - myline;
@ -1044,9 +1139,9 @@ latexSemiState ()
// We only need to consider reads and claims, but for fun we just consider everything. // We only need to consider reads and claims, but for fun we just consider everything.
rd = roledef_shift (sys->runs[run].start, ev); rd = roledef_shift (sys->runs[run].start, ev);
iterate_outgoing_arrows (outgoing_arrow, run, ev); iterate_outgoing_arrows (outgoing_arrow, run, ev);
eprintf("\\action{"); eprintf ("\\action{");
roledefPrint (rd); roledefPrint (rd);
eprintf("}{r%i}\n", run); eprintf ("}{r%i}\n", run);
} }
ev++; ev++;
} }
@ -1748,6 +1843,36 @@ select_goal ()
return best; return best;
} }
//! Check if a binding duplicates an old one: if so, simply connect
int
bind_old_goal (const Binding b_new)
{
if (!b_new->done)
{
List bl;
bl = sys->bindings;
while (bl != NULL)
{
Binding b_old;
b_old = (Binding) bl->data;
if (b_old->done && isTermEqual (b_new->term, b_old->term))
{
// Old is done and has the same term!
// So we copy this binding, and fix it.
b_new->run_from = b_old->run_from;
b_new->ev_from = b_old->ev_from;
b_new->done = 1;
return 1;
}
bl = bl->next;
}
}
// No old binding to connect to
return 0;
}
//! Create a new intruder run to generate knowledge from m0 //! Create a new intruder run to generate knowledge from m0
int int
@ -1913,7 +2038,8 @@ bind_goal_new_encrypt (const Binding b)
//! 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, or retrieves it from m0.
* However, it must not already have been created in an intruder run; then it gets bound to that.
*/ */
int int
bind_goal_new_intruder_run (const Binding b) bind_goal_new_intruder_run (const Binding b)
@ -2097,49 +2223,105 @@ bind_goal (const Binding b)
proof_select_goal (b); proof_select_goal (b);
indentDepth++; indentDepth++;
// Prune: if it is an SK type construct, ready // Consider a duplicate goal that we already bound before (C-minimality)
// No regular run will apply SK for you. // if (1 == 0)
//!@todo This still needs a lemma, and a more generic (correct) algorithm!! if (bind_old_goal (b))
know_only = 0;
function = getTermFunction (b->term);
if (function != NULL)
{ {
if (!inKnowledge (sys->know, function)) if (sys->output == PROOF)
{ {
// Prune because we didn't know it before, and it is never subterm-sent indentPrint ();
if (sys->output == PROOF) eprintf ("Goal for term ");
{ termPrint (b->term);
indentPrint (); eprintf (" was bound once before, linking up to #%i, %i.\n",
eprintf ("* Because "); b->run_from, b->ev_from);
termPrint (b->term);
eprintf
(" is never sent from a regular run (STILL NEEDS LEMMA!), we only intruder construct it.\n");
}
know_only = 1;
} }
}
proofDepth++; flag = flag && iterate ();
if (know_only)
{ // Unbind again
// Special case: only from intruder b->done = 0;
flag = flag && bind_goal_old_intruder_run (b); indentDepth--;
flag = flag && bind_goal_new_intruder_run (b); return flag;
} }
else else
{ {
// Normal case // Prune: if it is an SK type construct, ready
{ // No regular run will apply SK for you.
flag = bind_goal_regular_run (b); //!@todo This still needs a lemma, and a more generic (correct) algorithm!!
}
flag = flag && bind_goal_old_intruder_run (b);
flag = flag && bind_goal_new_intruder_run (b);
}
proofDepth--;
indentDepth--; know_only = 0;
return flag; function = getTermFunction (b->term);
if (function != NULL)
{
if (!inKnowledge (sys->know, function))
{
// Prune because we didn't know it before, and it is never subterm-sent
if (sys->output == PROOF)
{
indentPrint ();
eprintf ("* Because ");
termPrint (b->term);
eprintf
(" is never sent from a regular run (STILL NEEDS LEMMA!), we only intruder construct it.\n");
}
know_only = 1;
}
}
// Keylevel lemmas: improves on the previous one
if (!isPossiblySent (b->term))
{
if (sys->output == PROOF)
{
eprintf
("Rejecting a term as a regular bind because key levels are off: ");
termPrint (b->term);
if (know_only)
{
eprintf (" [in accordance with function lemma]");
}
else
{
eprintf (" [stronger than function lemma]");
}
eprintf ("\n");
}
know_only = 1;
}
#ifdef DEBUG
else
{
if (DEBUGL (5) && know_only == 1)
{
eprintf
("Keylevel lemma is weaker than function lemma for term ");
termPrint (b->term);
eprintf ("\n");
}
}
#endif
proofDepth++;
if (know_only)
{
// Special case: only from intruder
flag = flag && bind_goal_old_intruder_run (b);
flag = flag && bind_goal_new_intruder_run (b);
}
else
{
// Normal case
{
flag = bind_goal_regular_run (b);
}
flag = flag && bind_goal_old_intruder_run (b);
flag = flag && bind_goal_new_intruder_run (b);
}
proofDepth--;
indentDepth--;
return flag;
}
} }
else else
{ {
@ -2735,6 +2917,8 @@ arachne ()
max_encryption_level = 0; max_encryption_level = 0;
iterate_role_sends (determine_encrypt_max); iterate_role_sends (determine_encrypt_max);
fixAgentKeylevels ();
#ifdef DEBUG #ifdef DEBUG
if (DEBUGL (1)) if (DEBUGL (1))
{ {