- 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;
}
//! 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
/**
*@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
/**
* From old to new. Sets the new length to new.
@ -689,7 +783,8 @@ 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.
*/
int ranks_to_lines(int *ranks, const int nodes)
int
ranks_to_lines (int *ranks, const int nodes)
{
int ranksdone, baseline;
@ -1748,6 +1843,36 @@ select_goal ()
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
int
@ -1913,7 +2038,8 @@ bind_goal_new_encrypt (const Binding b)
//! 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
bind_goal_new_intruder_run (const Binding b)
@ -2097,6 +2223,28 @@ bind_goal (const Binding b)
proof_select_goal (b);
indentDepth++;
// Consider a duplicate goal that we already bound before (C-minimality)
// if (1 == 0)
if (bind_old_goal (b))
{
if (sys->output == PROOF)
{
indentPrint ();
eprintf ("Goal for term ");
termPrint (b->term);
eprintf (" was bound once before, linking up to #%i, %i.\n",
b->run_from, b->ev_from);
}
flag = flag && iterate ();
// Unbind again
b->done = 0;
indentDepth--;
return flag;
}
else
{
// Prune: if it is an SK type construct, ready
// No regular run will apply SK for you.
//!@todo This still needs a lemma, and a more generic (correct) algorithm!!
@ -2120,6 +2268,39 @@ bind_goal (const Binding b)
}
}
// 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)
{
@ -2141,6 +2322,7 @@ bind_goal (const Binding b)
indentDepth--;
return flag;
}
}
else
{
return 1;
@ -2735,6 +2917,8 @@ arachne ()
max_encryption_level = 0;
iterate_role_sends (determine_encrypt_max);
fixAgentKeylevels ();
#ifdef DEBUG
if (DEBUGL (1))
{