diff --git a/lib/cookies/alg_containers.c b/lib/cookies/alg_containers.c
index 1a5767b7a15f84dea5c2a8f0da0a55fd247f5fca..417959ed1a988c1826d37180d0b52ffa4016e803 100644
--- a/lib/cookies/alg_containers.c
+++ b/lib/cookies/alg_containers.c
@@ -23,52 +23,24 @@
 #include "lib/cookies/alg_containers.h"
 #include "lib/cookies/alg_sha.h"
 
-const struct kr_cc_alg_descr kr_cc_algs[] = {
-	{ "FNV-64", &knot_cc_alg_fnv64 },
-	{ "HMAC-SHA256-64", &knot_cc_alg_hmac_sha256_64 },
-	{ NULL, NULL }
+const struct knot_cc_alg *const kr_cc_algs[] = {
+	/* 0 */ &knot_cc_alg_fnv64,
+	/* 1 */ &knot_cc_alg_hmac_sha256_64
 };
 
-const struct kr_cc_alg_descr *kr_cc_alg(const struct kr_cc_alg_descr cc_algs[],
-                                        const char *name)
-{
-	if (!cc_algs || !name) {
-		return NULL;
-	}
-
-	const struct kr_cc_alg_descr *aux_ptr = cc_algs;
-	while (aux_ptr && aux_ptr->alg && aux_ptr->alg->gen_func) {
-		assert(aux_ptr->name);
-		if (strcmp(aux_ptr->name, name) == 0) {
-			return aux_ptr;
-		}
-		++aux_ptr;
-	}
-
-	return NULL;
-}
-
-const struct kr_sc_alg_descr kr_sc_algs[] = {
-	{ "FNV-64", &knot_sc_alg_fnv64 },
-	{ "HMAC-SHA256-64", &knot_sc_alg_hmac_sha256_64 },
-	{ NULL, NULL }
+const knot_lookup_t kr_cc_alg_names[] = {
+	{ 0, "FNV-64" },
+	{ 1, "HMAC-SHA256-64" },
+	{ -1, NULL }
 };
 
-const struct kr_sc_alg_descr *kr_sc_alg(const struct kr_sc_alg_descr sc_algs[],
-                                        const char *name)
-{
-	if (!sc_algs || !name) {
-		return NULL;
-	}
-
-	const struct kr_sc_alg_descr *aux_ptr = sc_algs;
-	while (aux_ptr && aux_ptr->alg && aux_ptr->alg->hash_func) {
-		assert(aux_ptr->name);
-		if (strcmp(aux_ptr->name, name) == 0) {
-			return aux_ptr;
-		}
-		++aux_ptr;
-	}
+const struct knot_sc_alg *const kr_sc_algs[] = {
+	/* 0 */ &knot_sc_alg_fnv64,
+	/* 1 */ &knot_sc_alg_hmac_sha256_64
+};
 
-	return NULL;
-}
+const knot_lookup_t kr_sc_alg_names[] = {
+	{ 0, "FNV-64" },
+	{ 1, "HMAC-SHA256-64" },
+	{ -1, NULL }
+};
diff --git a/lib/cookies/alg_containers.h b/lib/cookies/alg_containers.h
index 1a5aa003859d7790a193900495f5fe6839a94f05..68a50cb52e212d7ea6bbe6126f5a657db79cc7d6 100644
--- a/lib/cookies/alg_containers.h
+++ b/lib/cookies/alg_containers.h
@@ -18,56 +18,25 @@
 
 #include <libknot/cookies/client.h>
 #include <libknot/cookies/server.h>
+#include <libknot/lookup.h>
 
 #include "lib/defines.h"
 
-/** Maximal size of a cookie option. */
-#define KR_COOKIE_OPT_MAX_LEN (KNOT_EDNS_OPTION_HDRLEN + KNOT_OPT_COOKIE_CLNT + KNOT_OPT_COOKIE_SRVR_MAX)
-
-/** Holds description of client cookie hashing algorithms. */
-struct kr_cc_alg_descr {
-	const char *name; /**< Algorithgm name. */
-	const struct knot_cc_alg *alg; /**< Algorithm. */
-};
-
-/**
- * List of available client cookie algorithms.
- *
- * Last element contains all null entries.
- */
+/** Client algorithm identifiers are used as index into this array of pointers. */
 KR_EXPORT
-extern const struct kr_cc_alg_descr kr_cc_algs[];
+extern const struct knot_cc_alg *const kr_cc_algs[];
 
-/**
- * @brief Return pointer to client cookie algorithm with given name.
- * @param cc_algs List of available algorithms.
- * @param name    Algorithm name.
- * @return pointer to algorithm or NULL if not found.
- */
+/** Binds client algorithm identifiers onto names. */
 KR_EXPORT
-const struct kr_cc_alg_descr *kr_cc_alg(const struct kr_cc_alg_descr cc_algs[],
-                                        const char *name);
+extern const knot_lookup_t kr_cc_alg_names[];
 
-/** Holds description of server cookie hashing algorithms. */
-struct kr_sc_alg_descr {
-	const char *name; /**< Algorithm name. */
-	const struct knot_sc_alg *alg; /**< Algorithm. */
-};
-
-/**
- * List of available server cookie algorithms.
- *
- * Last element contains all null entries.
- */
+/** Server algorithm identifiers are used as index into this array of pointers. */
 KR_EXPORT
-extern const struct kr_sc_alg_descr kr_sc_algs[];
+extern const struct knot_sc_alg *const kr_sc_algs[];
 
-/**
- * @brief Return pointer to server cookie algorithm with given name.
- * @param sc_algs List of available algorithms.
- * @param name    Algorithm name.
- * @return pointer to algorithm or NULL if not found.
- */
+/** Binds server algorithm identifiers onto names. */
 KR_EXPORT
-const struct kr_sc_alg_descr *kr_sc_alg(const struct kr_sc_alg_descr sc_algs[],
-                                        const char *name);
+extern const knot_lookup_t kr_sc_alg_names[];
+
+/** Maximal size of a cookie option. */
+#define KR_COOKIE_OPT_MAX_LEN (KNOT_EDNS_OPTION_HDRLEN + KNOT_OPT_COOKIE_CLNT + KNOT_OPT_COOKIE_SRVR_MAX)
diff --git a/lib/cookies/control.c b/lib/cookies/control.c
index f2ae2fca189580d653f2eb151fff0b5d292edf71..96f0b0cfab7b95a23fb9735624c5c692c7fbcdc4 100644
--- a/lib/cookies/control.c
+++ b/lib/cookies/control.c
@@ -17,6 +17,6 @@
 #include "lib/cookies/control.h"
 
 struct kr_cookie_ctx kr_glob_cookie_ctx = {
-	.clnt = { false, { NULL, NULL }, { NULL, NULL}, DFLT_COOKIE_TTL },
-	.srvr = { false, { NULL, NULL }, { NULL, NULL} }
+	.clnt = { false, { NULL, -1 }, { NULL, -1}, DFLT_COOKIE_TTL },
+	.srvr = { false, { NULL, -1 }, { NULL, -1} }
 };
diff --git a/lib/cookies/control.h b/lib/cookies/control.h
index c2842d81c9dbb739aba41eccf4b100674cbd253f..ca546a078575deca495262d88104023495702121 100644
--- a/lib/cookies/control.h
+++ b/lib/cookies/control.h
@@ -37,7 +37,7 @@ struct kr_cookie_secret {
 /** Holds settings that have direct influence on client cookie values. */
 struct kr_clnt_cookie_settings {
 	struct kr_cookie_secret *csec; /*!< Client secret data. */
-	const struct kr_cc_alg_descr *calg; /**< Client cookie algorithm. */
+	int calg_id; /*!< Client cookie algorithm identifier. */
 };
 
 /** Holds settings that control client behaviour. */
@@ -53,7 +53,7 @@ struct kr_clnt_cookie_ctx {
 /** Holds settings that have direct influence on server cookie values. */
 struct kr_srvr_cookie_settings {
 	struct kr_cookie_secret *ssec; /*!< Server secret data. */
-	const struct kr_sc_alg_descr *salg; /**< Server cookie algorithm. */
+	int salg_id; /**< Server cookie algorithm identifier. */
 };
 
 /** Holds settings that control server behaviour. */
diff --git a/lib/cookies/helper.c b/lib/cookies/helper.c
index 5d4c3b869998b7d9e969617b178fe37ebd44b663..e9a3a5ee9a103b9872b18dcca3658aae3b94d819 100644
--- a/lib/cookies/helper.c
+++ b/lib/cookies/helper.c
@@ -125,8 +125,7 @@ int kr_request_put_cookie(const struct kr_clnt_cookie_settings *clnt_cntrl,
 		return kr_ok();
 	}
 
-	if (!clnt_cntrl->csec || !clnt_cntrl->calg ||
-	    !cookie_cache) {
+	if (!clnt_cntrl->csec || (clnt_cntrl->calg_id < 0) || !cookie_cache) {
 		return kr_error(EINVAL);
 	}
 
@@ -141,9 +140,9 @@ int kr_request_put_cookie(const struct kr_clnt_cookie_settings *clnt_cntrl,
 	};
 	uint8_t cc[KNOT_OPT_COOKIE_CLNT];
 	uint16_t cc_len = KNOT_OPT_COOKIE_CLNT;
-	assert(clnt_cntrl->calg && clnt_cntrl->calg->alg &&
-	       clnt_cntrl->calg->alg->gen_func);
-	int ret = clnt_cntrl->calg->alg->gen_func(&input, cc, &cc_len);
+	assert((clnt_cntrl->calg_id >= 0) && kr_cc_algs[clnt_cntrl->calg_id] &&
+	       kr_cc_algs[clnt_cntrl->calg_id]->gen_func);
+	int ret = kr_cc_algs[clnt_cntrl->calg_id]->gen_func(&input, cc, &cc_len);
 	if (ret != kr_ok()) {
 		return ret;
 	}
diff --git a/lib/layer/cookiemonster.c b/lib/layer/cookiemonster.c
index 5f1b98fb9fc085a9dacc172a0a164f68d331dd09..5b408ceb4311894b0442a00fe71b64d707f452e1 100644
--- a/lib/layer/cookiemonster.c
+++ b/lib/layer/cookiemonster.c
@@ -68,7 +68,7 @@ static const struct sockaddr *passed_server_sockaddr(const struct kr_query *qry)
 static const struct sockaddr *guess_server_addr(const struct kr_nsrep *nsrep,
                                                 const uint8_t *cc, uint16_t cc_len,
                                                 const struct kr_cookie_secret *csecr,
-                                                const struct kr_cc_alg_descr *cc_alg)
+                                                const struct knot_cc_alg *cc_alg)
 {
 	assert(nsrep && cc && cc_len && csecr && cc_alg);
 
@@ -88,7 +88,7 @@ static const struct sockaddr *guess_server_addr(const struct kr_nsrep *nsrep,
 		}
 
 		input.srvr_sockaddr = (struct sockaddr *)&nsrep->addr[i];
-		int ret = knot_cc_check(cc, cc_len, &input, cc_alg->alg);
+		int ret = knot_cc_check(cc, cc_len, &input, cc_alg);
 		if (ret == KNOT_EOK) {
 			sockaddr = (struct sockaddr *)&nsrep->addr[i];
 			break;
@@ -127,14 +127,14 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
 			.secret_len = clnt_cntrl->current.csec->size
 		};
 		int ret = knot_cc_check(cc, cc_len, &input,
-		                             clnt_cntrl->current.calg->alg);
+		                        kr_cc_algs[clnt_cntrl->current.calg_id]);
 		bool have_current = (ret == KNOT_EOK);
 		if ((ret != KNOT_EOK) &&
-		    clnt_cntrl->recent.csec && clnt_cntrl->recent.calg) {
+		    clnt_cntrl->recent.csec && (clnt_cntrl->recent.calg_id >= 0)) {
 			input.secret_data = clnt_cntrl->recent.csec->data;
 			input.secret_len = clnt_cntrl->recent.csec->size;
 			ret = knot_cc_check(cc, cc_len, &input,
-			                    clnt_cntrl->recent.calg->alg);
+			                    kr_cc_algs[clnt_cntrl->recent.calg_id]);
 		}
 		if (ret == KNOT_EOK) {
 			*sockaddr = tmp_sockaddr;
@@ -143,10 +143,6 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
 		return (ret == KNOT_EOK) ? kr_ok() : kr_error(EINVAL);
 	}
 
-//	if (!cc || !clnt_cntrl) {
-//		return kr_error(EINVAL);
-//	}
-
 	DEBUG_MSG(NULL, "%s\n",
 	          "guessing response address from ns reputation");
 
@@ -154,14 +150,14 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
 	const struct kr_nsrep *ns = &qry->ns;
 	tmp_sockaddr = guess_server_addr(ns, cc, cc_len,
 	                                 clnt_cntrl->current.csec,
-	                                 clnt_cntrl->current.calg);
+	                                 kr_cc_algs[clnt_cntrl->current.calg_id]);
 	bool have_current = (tmp_sockaddr != NULL);
 	if (!tmp_sockaddr &&
-	    clnt_cntrl->recent.csec && clnt_cntrl->recent.calg) {
+	    clnt_cntrl->recent.csec && (clnt_cntrl->recent.calg_id >= 0)) {
 		/* Try recent client secret to check obtained cookie. */
 		tmp_sockaddr = guess_server_addr(ns, cc, cc_len,
 		                                 clnt_cntrl->recent.csec,
-		                                 clnt_cntrl->recent.calg);
+		                                 kr_cc_algs[clnt_cntrl->recent.calg_id]);
 	}
 	if (tmp_sockaddr) {
 		*sockaddr = tmp_sockaddr;
@@ -410,7 +406,7 @@ static int check_request(knot_layer_t *ctx, void *module_param)
 
 	struct kr_srvr_cookie_ctx *srvr_cntrl = &kr_glob_cookie_ctx.srvr;
 	if (!req->qsource.addr ||
-	    !srvr_cntrl->current.ssec || !srvr_cntrl->current.salg) {
+	    !srvr_cntrl->current.ssec || (srvr_cntrl->current.salg_id < 0)) {
 		DEBUG_MSG(NULL, "%s\n", "missing server cookie context");
 		return KNOT_STATE_FAIL;
 	}
@@ -449,9 +445,9 @@ static int check_request(knot_layer_t *ctx, void *module_param)
 	/* Check server cookie obtained in request. */
 
 	ret = knot_sc_check(NONCE_LEN, &cookies, &srvr_data,
-	                    srvr_cntrl->current.salg->alg);
+	                    kr_sc_algs[srvr_cntrl->current.salg_id]);
 	if (ret == KNOT_EINVAL &&
-	    srvr_cntrl->recent.ssec && srvr_cntrl->recent.salg->alg) {
+	    srvr_cntrl->recent.ssec && (srvr_cntrl->recent.salg_id >= 0)) {
 		/* Try recent algorithm. */
 		struct knot_sc_private recent_srvr_data = {
 			.clnt_sockaddr = req->qsource.addr,
@@ -459,7 +455,7 @@ static int check_request(knot_layer_t *ctx, void *module_param)
 			.secret_len = srvr_cntrl->recent.ssec->size
 		};
 		ret = knot_sc_check(NONCE_LEN, &cookies, &recent_srvr_data,
-		                    srvr_cntrl->recent.salg->alg);
+		                    kr_sc_algs[srvr_cntrl->recent.salg_id]);
 	}
 	if (ret != KNOT_EOK) {
 		/* TODO -- Silently discard? */
@@ -484,7 +480,8 @@ static int check_request(knot_layer_t *ctx, void *module_param)
 answer_add_cookies:
 	/* Add server cookie into response. */
 	ret = kr_answer_write_cookie(&srvr_data, cookies.cc, cookies.cc_len,
-	                             &nonce, srvr_cntrl->current.salg->alg,
+	                             &nonce,
+	                             kr_sc_algs[srvr_cntrl->current.salg_id],
 	                             req->answer);
 	if (ret != kr_ok()) {
 		return_state = KNOT_STATE_FAIL;
diff --git a/lib/resolve.c b/lib/resolve.c
index cc93f2b2a2e41b5ef8f02d66178f3a208c8dbe62..12eefdd4b145fd29c50a9f01f285a57140190367 100644
--- a/lib/resolve.c
+++ b/lib/resolve.c
@@ -429,14 +429,14 @@ static int cookie_answer(const void *clnt_sockaddr,
 	/* Add fres cookie into the answer. */
 	int ret = kr_answer_write_cookie(&srvr_data,
 	                                 cookies->cc, cookies->cc_len, &nonce,
-	                                 srvr_cntrl->current.salg->alg, answer);
+	                                 kr_sc_algs[srvr_cntrl->current.salg_id], answer);
 	if (ret != kr_ok()) {
 		return KNOT_STATE_FAIL;
 	}
 
 	/* Check server cookie only with current settings. */
 	ret = knot_sc_check(NONCE_LEN, cookies, &srvr_data,
-	                    srvr_cntrl->current.salg->alg);
+	                    kr_sc_algs[srvr_cntrl->current.salg_id]);
 	if (ret != KNOT_EOK) {
 		kr_pkt_set_ext_rcode(answer, KNOT_RCODE_BADCOOKIE);
 		return KNOT_STATE_FAIL | KNOT_STATE_DONE;
diff --git a/modules/cookiectl/cookiectl.c b/modules/cookiectl/cookiectl.c
index 55e7cba9212fd806623a1f6a05e76125c05bd527..498ab07b7485fae5340a9efd2701eb215efec0f4 100644
--- a/modules/cookiectl/cookiectl.c
+++ b/modules/cookiectl/cookiectl.c
@@ -145,12 +145,12 @@ static bool apply_client_hash_func(struct kr_cookie_ctx *cntrl,
                                    const JsonNode *node)
 {
 	if (node->tag == JSON_STRING) {
-		const struct kr_cc_alg_descr *cc_alg = kr_cc_alg(kr_cc_algs,
-		                                                 node->string_);
-		if (!cc_alg) {
+		const knot_lookup_t *lookup = knot_lookup_by_name(kr_cc_alg_names,
+		                                                  node->string_);
+		if (!lookup) {
 			return false;
 		}
-		cntrl->clnt.current.calg = cc_alg;
+		cntrl->clnt.current.calg_id = lookup->id;
 		return true;
 	}
 
@@ -161,12 +161,12 @@ static bool apply_server_hash_func(struct kr_cookie_ctx *cntrl,
                                    const JsonNode *node)
 {
 	if (node->tag == JSON_STRING) {
-		const struct kr_sc_alg_descr *sc_alg = kr_sc_alg(kr_sc_algs,
-		                                                 node->string_);
-		if (!sc_alg) {
+		const knot_lookup_t *lookup = knot_lookup_by_name(kr_sc_alg_names,
+		                                                  node->string_);
+		if (!lookup) {
 			return false;
 		}
-		cntrl->srvr.current.salg = sc_alg;
+		cntrl->srvr.current.salg_id = lookup->id;
 		return true;
 	}
 
@@ -249,9 +249,8 @@ static bool read_available_cc_hashes(JsonNode *root)
 		return false;
 	}
 
-	const struct kr_cc_alg_descr *aux_ptr = kr_cc_algs;
-	while (aux_ptr && aux_ptr->alg && aux_ptr->alg->gen_func) {
-		assert(aux_ptr->name);
+	const knot_lookup_t *aux_ptr = kr_cc_alg_names;
+	while (aux_ptr && (aux_ptr->id >= 0) && aux_ptr->name) {
 		JsonNode *element = json_mkstring(aux_ptr->name);
 		if (!element) {
 			goto fail;
@@ -280,9 +279,8 @@ static bool read_available_sc_hashes(JsonNode *root)
 		return false;
 	}
 
-	const struct kr_sc_alg_descr *aux_ptr = kr_sc_algs;
-	while (aux_ptr && aux_ptr->alg && aux_ptr->alg->hash_func) {
-		assert(aux_ptr->name);
+	const knot_lookup_t *aux_ptr = kr_sc_alg_names;
+	while (aux_ptr && (aux_ptr->id >= 0) && aux_ptr->name) {
 		JsonNode *element = json_mkstring(aux_ptr->name);
 		if (!element) {
 			goto fail;
@@ -307,7 +305,7 @@ static bool clnt_settings_equal(const struct kr_clnt_cookie_settings *s1,
 {
 	assert(s1 && s2 && s1->csec && s2->csec);
 
-	if (s1->calg != s2->calg || s1->csec->size != s2->csec->size) {
+	if (s1->calg_id != s2->calg_id || s1->csec->size != s2->csec->size) {
 		return false;
 	}
 
@@ -319,7 +317,7 @@ static bool srvr_settings_equal(const struct kr_srvr_cookie_settings *s1,
 {
 	assert(s1 && s2 && s1->ssec && s2->ssec);
 
-	if (s1->salg != s2->salg || s1->ssec->size != s2->ssec->size) {
+	if (s1->salg_id != s2->salg_id || s1->ssec->size != s2->ssec->size) {
 		return false;
 	}
 
@@ -401,7 +399,8 @@ char *read_config(struct kr_cookie_ctx *ctx)
 		return NULL;
 	}
 
-	char *result = NULL;
+	const knot_lookup_t *lookup;
+	char *result;
 	JsonNode *root_node = json_mkobject();
 
 	json_append_member(root_node, NAME_CLIENT_ENABLED,
@@ -409,9 +408,11 @@ char *read_config(struct kr_cookie_ctx *ctx)
 
 	read_secret(root_node, NAME_CLIENT_SECRET, ctx->clnt.current.csec);
 
-	assert(ctx->clnt.current.calg->name);
-	json_append_member(root_node, NAME_CLIENT_COOKIE_ALG,
-	                   json_mkstring(ctx->clnt.current.calg->name));
+	lookup = knot_lookup_by_id(kr_cc_alg_names, ctx->clnt.current.calg_id);
+	if (lookup) {
+		json_append_member(root_node, NAME_CLIENT_COOKIE_ALG,
+		                   json_mkstring(lookup->name));
+	}
 
 	read_available_cc_hashes(root_node);
 
@@ -423,9 +424,11 @@ char *read_config(struct kr_cookie_ctx *ctx)
 
 	read_secret(root_node, NAME_SERVER_SECRET, ctx->srvr.current.ssec);
 
-	assert(ctx->srvr.current.salg->name);
-	json_append_member(root_node, NAME_SERVER_COOKIE_ALG,
-	                   json_mkstring(ctx->srvr.current.salg->name));
+	lookup = knot_lookup_by_id(kr_sc_alg_names, ctx->srvr.current.salg_id);
+	if (lookup) {
+		json_append_member(root_node, NAME_SERVER_COOKIE_ALG,
+		                   json_mkstring(lookup->name));
+	}
 
 	read_available_sc_hashes(root_node);
 
@@ -470,14 +473,20 @@ int cookiectl_init(struct kr_module *module)
 		return kr_error(ENOMEM);
 	}
 
+	const knot_lookup_t *lookup;
+
 	kr_glob_cookie_ctx.clnt.enabled = false;
 	kr_glob_cookie_ctx.clnt.current.csec = cs;
-	kr_glob_cookie_ctx.clnt.current.calg = kr_cc_alg(kr_cc_algs, "FNV-64");
+	lookup = knot_lookup_by_name(kr_cc_alg_names, "FNV-64");
+	assert(lookup);
+	kr_glob_cookie_ctx.clnt.current.calg_id = lookup->id;
 	kr_glob_cookie_ctx.clnt.cache_ttl = DFLT_COOKIE_TTL;
 
 	kr_glob_cookie_ctx.srvr.enabled = false;
 	kr_glob_cookie_ctx.srvr.current.ssec = ss;
-	kr_glob_cookie_ctx.srvr.current.salg = kr_sc_alg(kr_sc_algs, "FNV-64");
+	lookup = knot_lookup_by_name(kr_sc_alg_names, "FNV-64");
+	assert(lookup);
+	kr_glob_cookie_ctx.srvr.current.salg_id = lookup->id;
 
 	module->data = NULL;