diff --git a/src/compiler.c b/src/compiler.c index 8a9d093..79cb51c 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -836,6 +836,49 @@ commEvent (int event, Tac tc) } } +//! Create hash functions +/** + * Assumption: hfuncs list in same order as tac. + * + * Note: Destroys tc contents, so please don't reuse afterwards. + */ +int +hashfunctions (Tac tcstart) +{ + Termlist hfuncs; + Termlist hinvs; + Tac tc; + + // As long as tc is intact. + levelDeclareConst (tcstart); + hfuncs = tacTermlist (tcstart->t1.tac); + if (level < 2) + knowledgeAddTermlist (sys->know, hfuncs); + + for (tc = tcstart->t1.tac; tc != NULL; tc = tc->next) + { + tc->t1.sym = symbolNextFree (symbolSysConst ("_unhash-")); + } + levelDeclareConst (tcstart); + hinvs = tacTermlist (tcstart->t1.tac); + + while (hfuncs != NULL) + { + if (hinvs == NULL) + { + error + ("Bug in hashfunction generation code. Please contact the authors.\n"); + } + knowledgeAddInverse (sys->know, hfuncs->term, hinvs->term); + hfuncs->term->stype = termlistAdd (NULL, TERM_Function); + hinvs->term->stype = termlistAdd (NULL, TERM_Function); + hfuncs = hfuncs->next; + hinvs = hinvs->next; + } + return true; +} + + int normalDeclaration (Tac tc) { @@ -885,6 +928,9 @@ normalDeclaration (Tac tc) knowledgeAddInverse (sys->know, tacTerm (tc->t1.tac), tacTerm (tc->t2.tac)); break; + case TAC_HASHFUNCTION: + hashfunctions (tc); + break; default: /* abort with false */ return 0; @@ -1295,6 +1341,10 @@ tacTerm (Tac tc) } } +//! Extract termlist from tac +/** + * Note: termlist in same order as tac. This is required for correct working of functions such as 'hashfunctions'. + */ Termlist tacTermlist (Tac tc) { diff --git a/src/parser.y b/src/parser.y index c6469be..d8f51ab 100644 --- a/src/parser.y +++ b/src/parser.y @@ -257,6 +257,13 @@ declaration : secretpref CONST basictermlist typeinfo1 ';' t->t1.tac= $2; $$ = t; } + | HASHFUNCTION basictermlist ';' + { Tac t = tacCreate(TAC_HASHFUNCTION); + t->t1.tac = $2; + t->t2.tac = tacCreate(TAC_UNDEF); + t->t3.tac = NULL; // Not secret: public + $$ = t; + } ; secretpref : /* empty */ diff --git a/src/tac.c b/src/tac.c index 59407b2..306ae56 100644 --- a/src/tac.c +++ b/src/tac.c @@ -330,6 +330,11 @@ tacPrint (Tac t) tacPrint (t->t2.tac); printf (");\n"); break; + case TAC_HASHFUNCTION: + printf ("hashfunction "); + tacPrint (t->t1.tac); + printf (";\n"); + break; case TAC_UNTRUSTED: printf ("untrusted "); tacPrint (t->t1.tac); diff --git a/src/tac.h b/src/tac.h index 6183d16..c2e8301 100644 --- a/src/tac.h +++ b/src/tac.h @@ -47,6 +47,7 @@ enum tactypes TAC_ROLEREF, TAC_SECRET, TAC_INVERSEKEYS, + TAC_HASHFUNCTION, TAC_UNTRUSTED, TAC_COMPROMISED, TAC_USERTYPE