Slightly better check of attributes.  Now, mem_list_next can actually stop when the searched for key doesn't have it's attributes within the range of the checked key.
diff --git a/crypto/store/store.h b/crypto/store/store.h
index c1cbb39..e82aa3e 100644
--- a/crypto/store/store.h
+++ b/crypto/store/store.h
@@ -411,6 +411,9 @@
 /* Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values
    in each contained attribute. */
 int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Check if the set of attributes in a is within the range of attributes
+   set in b. */
+int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
 /* Check if the set of attributes in a are also set in b. */
 int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
 /* Same as STORE_ATTR_INFO_in(), but also checks the attribute values. */
diff --git a/crypto/store/str_lib.c b/crypto/store/str_lib.c
index ab3fd42..a8bd531 100644
--- a/crypto/store/str_lib.c
+++ b/crypto/store/str_lib.c
@@ -1536,21 +1536,94 @@
 	return 0;
 	}
 
+static int attr_info_compare_compute_range(
+	unsigned char *abits, unsigned char *bbits,
+	unsigned int *alowp, unsigned int *ahighp,
+	unsigned int *blowp, unsigned int *bhighp)
+	{
+	unsigned int alow = (unsigned int)-1, ahigh = 0;
+	unsigned int blow = (unsigned int)-1, bhigh = 0;
+	int i, res = 0;
+
+	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
+		{
+		if (res == 0)
+			{
+			if (*abits < *bbits) res = -1;
+			if (*abits > *bbits) res = 1;
+			}
+		if (*abits)
+			{
+			if (alow == (unsigned int)-1)
+				{
+				alow = i * 8;
+				if (!(*abits & 0x01)) alow++;
+				if (!(*abits & 0x02)) alow++;
+				if (!(*abits & 0x04)) alow++;
+				if (!(*abits & 0x08)) alow++;
+				if (!(*abits & 0x10)) alow++;
+				if (!(*abits & 0x20)) alow++;
+				if (!(*abits & 0x40)) alow++;
+				}
+			ahigh = i * 8 + 7;
+			if (!(*abits & 0x80)) ahigh++;
+			if (!(*abits & 0x40)) ahigh++;
+			if (!(*abits & 0x20)) ahigh++;
+			if (!(*abits & 0x10)) ahigh++;
+			if (!(*abits & 0x08)) ahigh++;
+			if (!(*abits & 0x04)) ahigh++;
+			if (!(*abits & 0x02)) ahigh++;
+			}
+		if (*bbits)
+			{
+			if (blow == (unsigned int)-1)
+				{
+				blow = i * 8;
+				if (!(*bbits & 0x01)) blow++;
+				if (!(*bbits & 0x02)) blow++;
+				if (!(*bbits & 0x04)) blow++;
+				if (!(*bbits & 0x08)) blow++;
+				if (!(*bbits & 0x10)) blow++;
+				if (!(*bbits & 0x20)) blow++;
+				if (!(*bbits & 0x40)) blow++;
+				}
+			bhigh = i * 8 + 7;
+			if (!(*bbits & 0x80)) bhigh++;
+			if (!(*bbits & 0x40)) bhigh++;
+			if (!(*bbits & 0x20)) bhigh++;
+			if (!(*bbits & 0x10)) bhigh++;
+			if (!(*bbits & 0x08)) bhigh++;
+			if (!(*bbits & 0x04)) bhigh++;
+			if (!(*bbits & 0x02)) bhigh++;
+			}
+		}
+	if (ahigh + alow < bhigh + blow) res = -1;
+	if (ahigh + alow > bhigh + blow) res = 1;
+	if (alowp) *alowp = alow;
+	if (ahighp) *ahighp = ahigh;
+	if (blowp) *blowp = blow;
+	if (bhighp) *bhighp = bhigh;
+	return res;
+	}
+
 int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
 	{
-	unsigned char *abits, *bbits;
-	int i;
-
 	if (a == b) return 0;
 	if (!a) return -1;
 	if (!b) return 1;
-	abits = a->set;
-	bbits = b->set;
-	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
-		{
-		if (*abits < *bbits) return -1;
-		if (*abits > *bbits) return 1;
-		}
+	return attr_info_compare_compute_range(a->set, b->set, 0, 0, 0, 0);
+	}
+int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
+	{
+	unsigned int alow, ahigh, blow, bhigh;
+
+	if (a == b) return 1;
+	if (!a) return 0;
+	if (!b) return 0;
+	attr_info_compare_compute_range(a->set, b->set,
+		&alow, &ahigh, &blow, &bhigh);
+	if (alow >= blow && ahigh <= bhigh)
+		return 1;
 	return 0;
 	}
 int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
@@ -1565,7 +1638,7 @@
 	bbits = b->set;
 	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
 		{
-		if (*abits && *bbits != *abits)
+		if (*abits && (*bbits & *abits) != *abits)
 			return 0;
 		}
 	return 1;
diff --git a/crypto/store/str_mem.c b/crypto/store/str_mem.c
index 7480de0..25d789a 100644
--- a/crypto/store/str_mem.c
+++ b/crypto/store/str_mem.c
@@ -206,7 +206,7 @@
 	return 0;
 	}
 
-/* The list functions may be the hardest to nuderstand.  Basically,
+/* The list functions may be the hardest to understand.  Basically,
    mem_list_start compiles a stack of attribute info elements, and
    puts that stack into the context to be returned.  mem_list_next
    will then find the first matching element in the store, and then
@@ -305,6 +305,8 @@
 			context->search_index);
 	for(srch = context->search_index;
 	    srch < sk_num(store->data)
+		    && STORE_ATTR_INFO_in_range(key.attr_info,
+			    (STORE_ATTR_INFO *)sk_value(store->data, srch))
 		    && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
 				 (STORE_ATTR_INFO *)sk_value(store->data, srch)));
 	    srch++)