aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <me@fwei.tk>2018-07-08 14:51:34 -0400
committerFranklin Wei <me@fwei.tk>2018-07-08 14:51:34 -0400
commit945f11f3f70ead44cff2ac76faf68f328a968abc (patch)
tree2b54422f0150c1de8df6ffa5910b77f6d5881372
parent3e7b74359f56c0518abcd420e85a5e3e778e8fd1 (diff)
downloadcsaa-945f11f3f70ead44cff2ac76faf68f328a968abc.zip
csaa-945f11f3f70ead44cff2ac76faf68f328a968abc.tar.gz
csaa-945f11f3f70ead44cff2ac76faf68f328a968abc.tar.bz2
csaa-945f11f3f70ead44cff2ac76faf68f328a968abc.tar.xz
Refactor and optimize
-rw-r--r--crypto.c19
-rw-r--r--crypto.h3
-rw-r--r--iomt.c169
-rw-r--r--iomt.h2
-rw-r--r--service_provider.c43
-rw-r--r--sqlinit.c236
-rw-r--r--sqlinit.txt20
-rwxr-xr-xtabulate.sh11
-rwxr-xr-xtestall.sh21
-rwxr-xr-xtestcreate.sh2
-rwxr-xr-xtestdummy.sh24
-rwxr-xr-xtestmain.sh25
-rwxr-xr-xtestmodify.sh6
-rwxr-xr-xtestmodifyenc.sh5
-rwxr-xr-xtestretrieve.sh5
-rw-r--r--trusted_module.c3
16 files changed, 389 insertions, 205 deletions
diff --git a/crypto.c b/crypto.c
index c8e2df7..777d617 100644
--- a/crypto.c
+++ b/crypto.c
@@ -41,12 +41,7 @@ hash_t sha256(const void *data, size_t datalen)
bool is_zero(hash_t u)
{
- /* constant-time comparison */
- volatile char c = 0;
- for(int i = 0; i < 32; ++i)
- c |= u.hash[i];
-
- return c == 0;
+ return !memcmp(u.hash, hash_null.hash, sizeof(u.hash));
}
void dump_hash(hash_t u)
@@ -484,6 +479,18 @@ void warn(const char *fmt, ...)
fprintf(stderr, "\033[31;1mWARNING\033[0m: %s\n", buf);
}
+void begin_transaction(void *db)
+{
+ sqlite3 *handle = db;
+ sqlite3_exec(handle, "BEGIN;", 0, 0, 0);
+}
+
+void commit_transaction(void *db)
+{
+ sqlite3 *handle = db;
+ sqlite3_exec(handle, "COMMIT;", 0, 0, 0);
+}
+
void crypto_test(void)
{
#if 1
diff --git a/crypto.h b/crypto.h
index 2a6a0e0..e06b282 100644
--- a/crypto.h
+++ b/crypto.h
@@ -90,6 +90,9 @@ hash_t generate_nonce(void);
hash_t derive_key(const char *passphrase, hash_t nonce);
hash_t calc_kf(hash_t encryption_key, uint64_t file_idx);
+void begin_transaction(void *db);
+void commit_transaction(void *db);
+
void warn(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
/* self-test */
diff --git a/iomt.c b/iomt.c
index d54102f..10774ea 100644
--- a/iomt.c
+++ b/iomt.c
@@ -17,9 +17,8 @@ hash_t hash_node(const struct iomt_node node)
return hash_null;
}
-static void reset_and_bind(const struct iomt *tree, sqlite3_stmt *st)
+static void bind_placeholders(const struct iomt *tree, sqlite3_stmt *st)
{
- sqlite3_reset(st);
if(tree->db.key1_name)
{
sqlite3_bind_int(st, 1, tree->db.key1_val);
@@ -30,6 +29,12 @@ static void reset_and_bind(const struct iomt *tree, sqlite3_stmt *st)
}
}
+static void reset_and_bind(const struct iomt *tree, sqlite3_stmt *st)
+{
+ sqlite3_reset(st);
+ bind_placeholders(tree, st);
+}
+
/* internal nodes only */
hash_t iomt_getnode(const struct iomt *tree, uint64_t idx)
{
@@ -190,6 +195,9 @@ hash_t *merkle_complement(const struct iomt *tree, uint64_t leafidx, int **order
* be called once, namely when the service provider is created. */
void iomt_fill(struct iomt *tree)
{
+ if(!tree->in_memory)
+ begin_transaction(tree->db.db);
+
for(uint64_t i = 0; i < tree->mt_leafcount; ++i)
{
uint64_t mt_idx = ((uint64_t)1 << tree->mt_logleaves) - 1 + i;
@@ -208,6 +216,9 @@ void iomt_fill(struct iomt *tree)
0));
}
}
+
+ if(!tree->in_memory)
+ commit_transaction(tree->db.db);
}
/* A bit of a hack: our complement calculation returns the *indices*
@@ -218,6 +229,8 @@ void iomt_fill(struct iomt *tree)
* to modify each function to take the array of all nodes in the tree
* in addition to the complement indices, but this function will serve
* as a shim in the meantime. */
+
+/* TODO: database query? */
hash_t *lookup_nodes(const struct iomt *tree, const uint64_t *indices, int n)
{
hash_t *ret = calloc(n, sizeof(hash_t));
@@ -228,8 +241,14 @@ hash_t *lookup_nodes(const struct iomt *tree, const uint64_t *indices, int n)
void restore_nodes(struct iomt *tree, const uint64_t *indices, const hash_t *values, int n)
{
+ if(!tree->in_memory)
+ begin_transaction(tree->db.db);
+
for(int i = 0; i < n; ++i)
iomt_setnode(tree, indices[i], values[i]);
+
+ if(!tree->in_memory)
+ commit_transaction(tree->db.db);
}
/* Update mt_nodes to reflect a change to a leaf node's
@@ -245,6 +264,9 @@ void merkle_update(struct iomt *tree, uint64_t leafidx, hash_t newval, hash_t **
uint64_t idx = ((uint64_t)1 << tree->mt_logleaves) - 1 + leafidx;
+ if(!tree->in_memory)
+ begin_transaction(tree->db.db);
+
iomt_setnode(tree, idx, newval);
for(int i = 0; i < tree->mt_logleaves; ++i)
{
@@ -255,12 +277,16 @@ void merkle_update(struct iomt *tree, uint64_t leafidx, hash_t newval, hash_t **
idx = bintree_parent(idx);
+ /* TODO: optimize */
/* save old value */
if(old_dep)
(*old_dep)[i] = iomt_getnode(tree, idx);
iomt_setnode(tree, idx, parent);
}
+
+ if(!tree->in_memory)
+ commit_transaction(tree->db.db);
}
hash_t iomt_getroot(const struct iomt *tree)
@@ -271,7 +297,6 @@ hash_t iomt_getroot(const struct iomt *tree)
}
/* find a node with given idx */
-/* TODO: replace with database update */
struct iomt_node iomt_find_leaf(const struct iomt *tree, uint64_t idx, uint64_t *leafidx)
{
if(tree->in_memory)
@@ -451,6 +476,7 @@ struct iomt *iomt_new(int logleaves)
}
/* Assumes `buf' is large enough */
+/* */
static void generate_and_clauses(const struct iomt *tree, char *buf)
{
buf[0] = '\0';
@@ -461,6 +487,25 @@ static void generate_and_clauses(const struct iomt *tree, char *buf)
buf += sprintf(buf, " AND %s = ?2", tree->db.key2_name);
}
+static void generate_where_clause(const struct iomt *tree, char *buf)
+{
+ buf[0] = '\0';
+
+ if(tree->db.key1_name || tree->db.key2_name)
+ {
+ buf += sprintf(buf, " WHERE ");
+ if(tree->db.key1_name)
+ buf += sprintf(buf, "%s = ?1", tree->db.key1_name);
+ if(tree->db.key2_name)
+ {
+ if(tree->db.key1_name)
+ buf += sprintf(buf, " AND ");
+
+ buf += sprintf(buf, "%s = ?2", tree->db.key1_name);
+ }
+ }
+}
+
/* returns one of the following:
"" - no keys
", key1" - key1 only
@@ -572,6 +617,73 @@ struct iomt *iomt_new_from_db(void *db,
return tree;
}
+static void iomt_copy_from_db(struct iomt *newtree, const struct iomt *oldtree)
+{
+ /* Write nodes which are not null (others are assumed to be
+ * zero), with database query. */
+
+ assert(!oldtree->in_memory);
+
+ /* PROBLEM: the database could have nodes or leaves whose indexes
+ * are too large for this logleaves level (from when the tree is
+ * shrunk) */
+
+ char and_clauses[1000];
+ generate_and_clauses(oldtree, and_clauses);
+
+ char sql[1000];
+ sprintf(sql, "SELECT LeafIdx, Idx, NextIdx, Val FROM %s WHERE LeafIdx < ?3%s;",
+ oldtree->db.leaves_table,
+ and_clauses);
+
+ sqlite3_stmt *st;
+ sqlite3_prepare_v2(oldtree->db.db, sql, -1, &st, 0);
+ bind_placeholders(oldtree, st);
+
+ sqlite3_bind_int64(st, 3, newtree->mt_leafcount);
+
+ int rc;
+ do {
+ rc = sqlite3_step(st);
+
+ if(rc == SQLITE_ROW)
+ {
+ struct iomt_node node;
+
+ node.idx = sqlite3_column_int64(st, 1);
+ node.next_idx = sqlite3_column_int64(st, 2);
+ memcpy(&node.val, sqlite3_column_blob(st, 3), sizeof(node.val));
+
+ iomt_setleaf(newtree, sqlite3_column_int64(st, 0), node);
+ }
+ } while(rc == SQLITE_ROW);
+
+ sqlite3_finalize(st);
+
+ sprintf(sql, "SELECT NodeIdx, Val FROM %s WHERE NodeIdx < ?3%s;",
+ oldtree->db.nodes_table,
+ and_clauses);
+
+ sqlite3_prepare_v2(oldtree->db.db, sql, -1, &st, 0);
+ bind_placeholders(oldtree, st);
+
+ sqlite3_bind_int64(st, 3, 2 * newtree->mt_leafcount - 1);
+
+ do {
+ rc = sqlite3_step(st);
+
+ if(rc == SQLITE_ROW)
+ {
+ hash_t val;
+ memcpy(&val, sqlite3_column_blob(st, 1), sizeof(val));
+
+ iomt_setnode(newtree, sqlite3_column_int64(st, 0), val);
+ }
+ } while(rc == SQLITE_ROW);
+
+ sqlite3_finalize(st);
+}
+
/* make a copy of the IOMT with database backing (there will be no
* pointer semantics between the two trees when this function
* returns) */
@@ -586,12 +698,32 @@ struct iomt *iomt_dup_in_db(void *db,
key2_name, key2_val,
oldtree->mt_logleaves);
+ /* TODO: make a single DB query for all the leaves/nodes, then insert from there */
+ /* This is extremely slow. */
+ begin_transaction(newtree->db.db);
+
/* copy nodes, leaves (we do not recalculate the tree) */
- for(uint64_t i = 0; i < newtree->mt_leafcount; ++i)
- iomt_setleaf(newtree, i, iomt_getleaf(oldtree, i));
- for(uint64_t i = 0; i < 2 * newtree->mt_leafcount - 1; ++i)
- iomt_setnode(newtree, i, iomt_getnode(oldtree, i));
+ if(!oldtree->in_memory)
+ {
+ iomt_copy_from_db(newtree, oldtree);
+ }
+ else
+ {
+ /* Loop over all nodes, but only write the nonzero ones (to
+ * save time) */
+ for(uint64_t i = 0; i < oldtree->mt_leafcount; ++i)
+ if(oldtree->mem.mt_leaves[i].idx != 0)
+ iomt_setleaf(newtree, i, oldtree->mem.mt_leaves[i]);
+
+ for(uint64_t i = 0; i < 2 * oldtree->mt_leafcount - 1; ++i)
+ {
+ if(!is_zero(oldtree->mem.mt_nodes[i]))
+ iomt_setnode(newtree, i, oldtree->mem.mt_nodes[i]);
+ }
+ }
+
+ commit_transaction(newtree->db.db);
return newtree;
}
@@ -618,12 +750,7 @@ struct iomt *iomt_dup(const struct iomt *oldtree)
}
else
{
- /* copy nodes, leaves (we do not recalculate the tree) */
- for(uint64_t i = 0; i < newtree->mt_leafcount; ++i)
- iomt_setleaf(newtree, i, iomt_getleaf(oldtree, i));
-
- for(uint64_t i = 0; i < 2 * newtree->mt_leafcount - 1; ++i)
- iomt_setnode(newtree, i, iomt_getnode(oldtree, i));
+ iomt_copy_from_db(newtree, oldtree);
}
return newtree;
@@ -662,6 +789,7 @@ void iomt_serialize(const struct iomt *tree,
write_fn(userdata, tree->mem.mt_leaves, sizeof(struct iomt_node) * tree->mt_leafcount);
else
{
+ /* TODO: replace with database query */
for(uint64_t i = 0; i < tree->mt_leafcount; ++i)
{
struct iomt_node node = iomt_getleaf(tree, i);
@@ -768,6 +896,14 @@ struct iomt *iomt_from_lines(const char *filename)
return tree;
}
+void print_leaf(struct iomt_node node)
+{
+ printf("(%lu, %s, %lu)",
+ node.idx,
+ hash_format(node.val, 4).str,
+ node.next_idx);
+}
+
void iomt_dump(const struct iomt *tree)
{
if(tree)
@@ -775,11 +911,8 @@ void iomt_dump(const struct iomt *tree)
for(uint64_t i = 0; i < tree->mt_leafcount; ++i)
{
struct iomt_node node = iomt_getleaf(tree, i);
- printf("(%lu, %s, %lu)%s",
- node.idx,
- hash_format(node.val, 4).str,
- node.next_idx,
- (i == tree->mt_leafcount - 1) ? "\n" : ", ");
+ print_leaf(node);
+ printf("%s", (i == tree->mt_leafcount - 1) ? "\n" : ", ");
}
}
else
diff --git a/iomt.h b/iomt.h
index 7a00cb4..1c0c0f7 100644
--- a/iomt.h
+++ b/iomt.h
@@ -106,6 +106,8 @@ struct iomt *iomt_deserialize(int (*read_fn)(void *userdata, void *buf, size_t l
void *userdata);
void iomt_fill(struct iomt *tree);
+
+void print_leaf(struct iomt_node node);
void iomt_dump(const struct iomt *tree);
hash_t iomt_getroot(const struct iomt *tree);
diff --git a/service_provider.c b/service_provider.c
index 3bca02f..45fc4b0 100644
--- a/service_provider.c
+++ b/service_provider.c
@@ -240,18 +240,6 @@ void *db_init(const char *filename, bool overwrite, bool *need_init)
return db;
}
-void begin_transaction(void *db)
-{
- sqlite3 *handle = db;
- sqlite3_exec(handle, "BEGIN;", 0, 0, 0);
-}
-
-void commit_transaction(void *db)
-{
- sqlite3 *handle = db;
- sqlite3_exec(handle, "COMMIT;", 0, 0, 0);
-}
-
int count_placeholders(void *db)
{
sqlite3 *handle = db;
@@ -397,6 +385,8 @@ void sp_free(struct service_provider *sp)
}
}
+/* TODO: pre-compile these statements */
+
/* linear search for record given idx */
static struct file_record *lookup_record(struct service_provider *sp, uint64_t idx)
{
@@ -433,10 +423,6 @@ static struct file_record *lookup_record(struct service_provider *sp, uint64_t i
return NULL;
}
-/* Should we insert sorted (for O(logn) lookup), or just at the end to
- * avoid copying (O(n) lookup, O(1) insertion)? Eventually this will
- * be replaced with a SQL backend. We do not check to ensure that
- * there are no duplicate file indices; that is up to the caller. */
static void insert_record(struct service_provider *sp, const struct file_record *rec)
{
//printf("Inserting record %lu\n", rec->idx);
@@ -538,7 +524,9 @@ static struct file_version *lookup_version(struct service_provider *sp,
sqlite3 *handle = sp->db;
if(!version)
- version = count_versions(sp, file_idx);
+ {
+ return NULL;
+ }
const char *sql = "SELECT * FROM Versions WHERE FileIdx = ?1 AND Version = ?2;";
@@ -638,7 +626,7 @@ struct tm_cert sp_request(struct service_provider *sp,
iomt_free(rec->acl);
- /* copy the ACL into our database tables */
+ /* copy the ACL into our database tables (extremely slow) */
rec->acl = iomt_dup_in_db(sp->db,
"ACLNodes", "ACLLeaves",
"FileIdx", fr.fr.idx,
@@ -793,6 +781,8 @@ struct tm_request sp_createfile(struct service_provider *sp,
sp->n_placeholders++;
}
+ printf("Allocated leaf index %lu\n", i);
+
int *file_orders;
hash_t *file_comp = merkle_complement(sp->iomt, i, &file_orders);
@@ -1019,6 +1009,9 @@ struct version_info sp_fileinfo(struct service_provider *sp,
user_id,
&rv2_hmac);
+ if(!version)
+ version = rec->version;
+
struct file_version *ver = lookup_version(sp, rec->idx, version);
if(acl_out)
@@ -1038,7 +1031,7 @@ struct version_info sp_fileinfo(struct service_provider *sp,
return ret;
}
-/* This file retrieves the file given by file_idx for a given
+/* This function retrieves the file given by file_idx for a given
* user. *encrypted_secret will be set to the encryption key XOR'd
* with HMAC(kf, K). kf will be returned via the *kf pointer. The
* returned value is dynamically allocated and must be freed by the
@@ -1057,16 +1050,18 @@ void *sp_retrieve_file(struct service_provider *sp,
{
struct file_record *rec = lookup_record(sp, file_idx);
- if(!rec || !count_versions(sp, file_idx))
+ if(!rec || !rec->version)
{
/* Newly created file, no contents. We don't bother to set
- * *encrypted_secret or *len. Or, file does not exist. */
+ * *encrypted_secret or *len. Or, file does not exist. No
+ * authenticated denial; the client can use sp_fileinfo() to
+ * verify this for themselves. */
*len = 0;
return NULL;
}
if(!version)
- version = count_versions(sp, file_idx);
+ version = rec->version;
struct file_version *ver = lookup_version(sp, file_idx, version);
@@ -1172,7 +1167,7 @@ static void sp_handle_client(struct service_provider *sp, int cl)
}
case MODIFY_FILE:
{
- printf("Client: modify file\n");
+ printf("Client: modify file %lu\n", user_req.modify_file.file_idx);
struct iomt *buildcode = iomt_deserialize(read_from_fd, &cl);
struct iomt *composefile = iomt_deserialize(read_from_fd, &cl);
size_t filelen;
@@ -1206,7 +1201,7 @@ static void sp_handle_client(struct service_provider *sp, int cl)
}
case RETRIEVE_INFO:
{
- printf("Client: retrieve info\n");
+ printf("Client: retrieve info %lu\n", user_req.retrieve.file_idx);
struct iomt *acl = NULL;
struct version_info verinfo = sp_fileinfo(sp,
user_req.user_id,
diff --git a/sqlinit.c b/sqlinit.c
index 247a24c..2bb269a 100644
--- a/sqlinit.c
+++ b/sqlinit.c
@@ -32,88 +32,129 @@ unsigned char sqlinit_txt[] = {
0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x46,
0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x28,
0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52,
+ 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59,
0x2c, 0x0a, 0x56, 0x65, 0x72, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45,
0x52, 0x2c, 0x0a, 0x43, 0x74, 0x72, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47,
0x45, 0x52, 0x2c, 0x0a, 0x43, 0x65, 0x72, 0x74, 0x20, 0x42, 0x4c, 0x4f,
0x42, 0x2c, 0x0a, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x42, 0x4c, 0x4f, 0x42,
0x2c, 0x0a, 0x41, 0x43, 0x4c, 0x5f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x61,
- 0x76, 0x65, 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c,
- 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59,
- 0x20, 0x28, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43,
- 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20,
- 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54,
- 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73,
- 0x20, 0x28, 0x0a, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x20, 0x49,
- 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x49, 0x64, 0x78, 0x20,
- 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4e, 0x65, 0x78,
- 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52,
- 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a,
- 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20,
- 0x28, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b,
- 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42,
- 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58,
- 0x49, 0x53, 0x54, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64,
- 0x65, 0x73, 0x20, 0x28, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78,
- 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61,
- 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d,
- 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x4e, 0x6f, 0x64,
- 0x65, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52,
- 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49,
- 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53,
- 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x0a,
- 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45,
- 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4b, 0x46,
- 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79,
- 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20,
- 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x43, 0x65, 0x72, 0x74, 0x20, 0x42,
- 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x42, 0x4c,
- 0x4f, 0x42, 0x2c, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x63, 0x6f, 0x64,
- 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20,
- 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x43, 0x6f, 0x6d,
- 0x70, 0x6f, 0x73, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x6f, 0x67,
+ 0x76, 0x65, 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x0a,
+ 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54,
+ 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20,
+ 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4c,
+ 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x4c, 0x65, 0x61, 0x66,
+ 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20,
+ 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x2c,
+ 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52,
+ 0x2c, 0x0a, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e,
+ 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42,
+ 0x4c, 0x4f, 0x42, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41,
+ 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20,
+ 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x46,
+ 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x4e,
+ 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47,
+ 0x45, 0x52, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b,
+ 0x45, 0x59, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42,
+ 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20,
+ 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54,
+ 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49,
+ 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a,
+ 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45,
+ 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4b, 0x46, 0x20, 0x42, 0x4c, 0x4f, 0x42,
+ 0x2c, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f,
+ 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c,
+ 0x0a, 0x43, 0x65, 0x72, 0x74, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a,
+ 0x48, 0x4d, 0x41, 0x43, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x42,
+ 0x75, 0x69, 0x6c, 0x64, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67,
0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47,
- 0x45, 0x52, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20,
- 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78,
- 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x2c, 0x0a,
- 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20,
- 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45,
- 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c,
- 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78,
- 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45,
- 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f,
- 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x41, 0x43, 0x4c,
- 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c,
- 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52,
- 0x2c, 0x0a, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e,
- 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49,
- 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4e, 0x65, 0x78, 0x74,
- 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c,
- 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50,
+ 0x45, 0x52, 0x2c, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x66,
+ 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x76, 0x65,
+ 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x50,
0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28,
- 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4c, 0x65, 0x61,
- 0x66, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49,
+ 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49,
0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65,
0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e,
0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f,
0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a,
0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c,
0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49,
- 0x53, 0x54, 0x53, 0x20, 0x41, 0x43, 0x4c, 0x4e, 0x6f, 0x64, 0x65, 0x73,
- 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49,
- 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4e, 0x6f, 0x64, 0x65,
+ 0x53, 0x54, 0x53, 0x20, 0x41, 0x43, 0x4c, 0x4c, 0x65, 0x61, 0x76, 0x65,
+ 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20,
+ 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4c, 0x65, 0x61,
+ 0x66, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52,
+ 0x2c, 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45,
+ 0x52, 0x2c, 0x0a, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x78, 0x20, 0x49,
+ 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20,
+ 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52,
+ 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49,
+ 0x64, 0x78, 0x2c, 0x20, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x29,
+ 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45,
+ 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20,
+ 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46,
+ 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49,
+ 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41,
+ 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20,
+ 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x41,
+ 0x43, 0x4c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69,
+ 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45,
+ 0x52, 0x2c, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49,
+ 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20,
+ 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52,
+ 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49,
+ 0x64, 0x78, 0x2c, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x29,
+ 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45,
+ 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20,
+ 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46,
+ 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49,
+ 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41,
+ 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20,
+ 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x42,
+ 0x43, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69,
+ 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45,
+ 0x52, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49,
+ 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4c, 0x65, 0x61, 0x66,
0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c,
- 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50,
- 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28,
- 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4e, 0x6f, 0x64,
- 0x65, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49,
- 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65,
- 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e,
- 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f,
- 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a,
+ 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52,
+ 0x2c, 0x0a, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e,
+ 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42,
+ 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59,
+ 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64,
+ 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x20,
+ 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f,
+ 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46,
+ 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45,
+ 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52,
+ 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, 0x29, 0x2c,
+ 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59,
+ 0x20, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x52,
+ 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41,
+ 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20,
+ 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x42,
+ 0x43, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c,
+ 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52,
+ 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e,
+ 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42,
+ 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78,
+ 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x50, 0x52,
+ 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46,
+ 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78,
+ 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b,
+ 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29,
+ 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20,
+ 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28,
+ 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47,
+ 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43,
+ 0x45, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28,
+ 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a,
0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c,
0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49,
- 0x53, 0x54, 0x53, 0x20, 0x42, 0x43, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73,
+ 0x53, 0x54, 0x53, 0x20, 0x43, 0x46, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73,
0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49,
0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c,
@@ -136,7 +177,7 @@ unsigned char sqlinit_txt[] = {
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a,
0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c,
0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49,
- 0x53, 0x54, 0x53, 0x20, 0x42, 0x43, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20,
+ 0x53, 0x54, 0x53, 0x20, 0x43, 0x46, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20,
0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e,
0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a,
@@ -155,48 +196,21 @@ unsigned char sqlinit_txt[] = {
0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x73, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45,
- 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f,
- 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x43, 0x46, 0x4c,
- 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65,
- 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c,
- 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54,
- 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64,
- 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x49,
- 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a,
- 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45,
- 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f,
- 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b,
- 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c,
- 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x4c, 0x65,
- 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45,
- 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c,
- 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45,
- 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63,
- 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46,
- 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28,
- 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x52, 0x45, 0x46,
- 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45,
- 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f,
- 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x43, 0x46, 0x4e,
- 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49,
- 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a,
- 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45,
- 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f,
- 0x42, 0x2c, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49,
- 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d,
- 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c,
- 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x2c, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x29, 0x2c,
- 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59,
- 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52,
- 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69,
- 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64,
- 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20,
- 0x4b, 0x45, 0x59, 0x20, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53,
- 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x00
+ 0x20, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x49, 0x64, 0x78, 0x31, 0x20,
+ 0x4f, 0x4e, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28,
+ 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x3b, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54,
+ 0x45, 0x20, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x49, 0x64, 0x78, 0x32,
+ 0x20, 0x4f, 0x4e, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x61, 0x76,
+ 0x65, 0x73, 0x28, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4e, 0x65, 0x78, 0x74,
+ 0x49, 0x64, 0x78, 0x29, 0x3b, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45,
+ 0x20, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x49, 0x64, 0x78, 0x33, 0x20,
+ 0x4f, 0x4e, 0x20, 0x41, 0x43, 0x4c, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73,
+ 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4c, 0x65,
+ 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, 0x3b, 0x0a, 0x43, 0x52, 0x45, 0x41,
+ 0x54, 0x45, 0x20, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x49, 0x64, 0x78,
+ 0x34, 0x20, 0x4f, 0x4e, 0x20, 0x41, 0x43, 0x4c, 0x4e, 0x6f, 0x64, 0x65,
+ 0x73, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4e,
+ 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x29, 0x3b, 0x0a, 0x00
};
-unsigned int sqlinit_txt_len = 2386;
+unsigned int sqlinit_txt_len = 2553;
diff --git a/sqlinit.txt b/sqlinit.txt
index 72634ea..b8e34ec 100644
--- a/sqlinit.txt
+++ b/sqlinit.txt
@@ -12,27 +12,24 @@ DROP TABLE IF EXISTS CFLeaves;
DROP TABLE IF EXISTS CFNodes;
CREATE TABLE IF NOT EXISTS FileRecords (
-Idx INTEGER,
+Idx INTEGER PRIMARY KEY,
Ver INTEGER,
Ctr INTEGER,
Cert BLOB,
HMAC BLOB,
-ACL_logleaves INTEGER,
-PRIMARY KEY (Idx)
+ACL_logleaves INTEGER
);
CREATE TABLE IF NOT EXISTS FileLeaves (
-LeafIdx INTEGER,
+LeafIdx INTEGER PRIMARY KEY,
Idx INTEGER,
NextIdx INTEGER,
-Val BLOB,
-PRIMARY KEY (LeafIdx)
+Val BLOB
);
CREATE TABLE IF NOT EXISTS FileNodes (
-NodeIdx INTEGER,
-Val BLOB,
-PRIMARY KEY (NodeIdx)
+NodeIdx INTEGER PRIMARY KEY,
+Val BLOB
);
CREATE TABLE IF NOT EXISTS Versions (
@@ -109,3 +106,8 @@ PRIMARY KEY (FileIdx, Version, NodeIdx),
FOREIGN KEY (FileIdx) REFERENCES FileRecords(Idx),
FOREIGN KEY (Version) REFERENCES Versions(Version)
);
+
+CREATE INDEX Idx1 ON Versions(FileIdx, Version);
+CREATE INDEX Idx2 ON FileLeaves(Idx, NextIdx);
+CREATE INDEX Idx3 ON ACLLeaves(FileIdx, LeafIdx);
+CREATE INDEX Idx4 ON ACLNodes(FileIdx, NodeIdx);
diff --git a/tabulate.sh b/tabulate.sh
index 3db27e5..4d10f73 100755
--- a/tabulate.sh
+++ b/tabulate.sh
@@ -1,2 +1,11 @@
#!/bin/bash
-for i in `seq 10 62`; do for j in `seq 1 1`; do echo -n "$i $j "; cat run_"$i"_"$j".txt | awk '/Elapsed/ || /Maximum/ || /User time/ || /System time/' | awk 'BEGIN{line=0}{if(line%4<=1)printf($4" ");if(line %4==2)printf($8" ");if(line%4==3)printf($6" ");}{line+=1}END{printf("\n");}'; done; done
+for i in `seq 10 62`
+do
+ rm -f run_"$i".txt
+ for j in `seq 1 40`
+ do
+ echo -n "$i $j " >> run_"$i".txt
+ cat run_"$i"_"$j".txt | awk '/Elapsed/ || /Maximum/ || /User time/ || /System time/' | awk 'BEGIN{line=0}{if(line%4<=1)printf($4" ");if(line %4==2)printf($8" ");if(line%4==3)printf($6" ");}{line+=1}END{printf("\n");}' >> run_"$i".txt
+ done
+
+done
diff --git a/testall.sh b/testall.sh
index dfc9972..b637241 100755
--- a/testall.sh
+++ b/testall.sh
@@ -1,18 +1,23 @@
#!/bin/bash
-if [[ $# -ne 1 ]]
+if [[ $# -ne 2 ]]
then
- echo "Usage: "$0" LOGLEAVES"
+ echo "Usage: "$0" LOGLEAVES RUNS"
exit 1
fi
+
+runs=$2
+
echo "Initializing..."
+rm files -rf
+
./server $1 csaa.db --overwrite > /dev/null &
pid=$!
-sleep 1
-/usr/bin/time -v ./testcreate.sh ./client
-/usr/bin/time -v ./testmodify.sh ./client
-/usr/bin/time -v ./testretrieve.sh ./client
-/usr/bin/time -v ./testmodifyenc.sh ./client
+sleep .2
+/usr/bin/time -v ./testcreate.sh ./client $runs
+/usr/bin/time -v ./testmodify.sh ./client $runs
+/usr/bin/time -v ./testretrieve.sh ./client $runs
+/usr/bin/time -v ./testmodifyenc.sh ./client $runs
echo "Encrypted retrieve: "
-/usr/bin/time -v ./testretrieve.sh ./client
+/usr/bin/time -v ./testretrieve.sh ./client $runs
kill -SIGINT $!
diff --git a/testcreate.sh b/testcreate.sh
index dd4e875..3e3ca21 100755
--- a/testcreate.sh
+++ b/testcreate.sh
@@ -1,6 +1,6 @@
#!/bin/bash
echo "Create:"
-for i in $(seq 1 100)
+for i in $(seq 1 $2)
do
$1 -u 1 -k a create > /dev/null
if [[ $? -ne 0 ]]
diff --git a/testdummy.sh b/testdummy.sh
index 7050655..a10d621 100755
--- a/testdummy.sh
+++ b/testdummy.sh
@@ -1,11 +1,19 @@
#!/bin/bash
-echo "Initializing..."
-rm csaa.db
-sqlite3 csaa.db < sqlinit.txt
-./dummy_server 10 csaa.db > /dev/null &
+if [[ $# -ne 2 ]]
+then
+ echo "Usage: "$0" LOGLEAVES RUNS"
+ exit 1
+fi
+
+runs=$2
+
+echo "Initializing dummy..."
+rm files -rf
+
+./dummy_server $1 csaa.db --overwrite > /dev/null &
pid=$!
-sleep 1
-/usr/bin/time -v ./testcreate.sh ./dummy_client
-/usr/bin/time -v ./testmodify.sh ./dummy_client
-/usr/bin/time -v ./testretrieve.sh ./dummy_client
+sleep .2
+/usr/bin/time -v ./testcreate.sh ./dummy_client $runs
+/usr/bin/time -v ./testmodify.sh ./dummy_client $runs
+/usr/bin/time -v ./testretrieve.sh ./dummy_client $runs
kill -SIGINT $!
diff --git a/testmain.sh b/testmain.sh
index 1bb6fc7..dacfb8f 100755
--- a/testmain.sh
+++ b/testmain.sh
@@ -1,19 +1,22 @@
#!/bin/bash
mkdir -p results
+trials=5
-for i in `seq 1 1`
-do
- ./testdummy.sh 2> results/dummy_$i.txt
- sleep 1
-done
-
-for i in `seq 8 62`
+for i in `seq 8 30`
do
echo "logleaves "$i
- for j in `seq 1 1`
+
+ runs=$(echo '2^'"$i" | bc)
+
+ echo "Doing "$trials"x"$runs" operations"
+ for j in $(seq 1 $trials)
do
- ./testall.sh $i 2> results/run_"$i"_"$j".txt
- # give time to close
- sleep 1
+
+ ./testall.sh $i $runs 2> results/run_"$i"_"$j".txt
+ sleep .2
+
+ # dummy
+ ./testdummy.sh $i $runs 2> results/dummy_"$i"_"$j".txt
+ sleep .2
done
done
diff --git a/testmodify.sh b/testmodify.sh
index 86a78d1..bd20dc7 100755
--- a/testmodify.sh
+++ b/testmodify.sh
@@ -1,9 +1,9 @@
#!/bin/bash
+# modify files 1 - $2, creating a new version with fixed contents
echo "Modify:"
-$1 -u 1 -k a create > /dev/null
-for i in $(seq 1 100)
+for i in $(seq 1 $2)
do
- $1 -u 1 -k a modifyfile -f 1 -i container1/hello-world.tar > /dev/null
+ $1 -u 1 -k a modifyfile -f $i -i container1/hello-world.tar > /dev/null
if [[ $? -ne 0 ]]
then
echo "Request failed!"
diff --git a/testmodifyenc.sh b/testmodifyenc.sh
index 96457ba..5c182cc 100755
--- a/testmodifyenc.sh
+++ b/testmodifyenc.sh
@@ -1,9 +1,8 @@
#!/bin/bash
echo "Modify (encrypted):"
-$1 -u 1 -k a create > /dev/null
-for i in $(seq 1 100)
+for i in $(seq 1 $2)
do
- $1 -u 1 -k a modifyfile -e -f 1 -i container1/hello-world.tar > /dev/null
+ $1 -u 1 -k a modifyfile -e -f $i -i container1/hello-world.tar > /dev/null
if [[ $? -ne 0 ]]
then
echo "Request failed!"
diff --git a/testretrieve.sh b/testretrieve.sh
index 566c48b..ed1bbf8 100755
--- a/testretrieve.sh
+++ b/testretrieve.sh
@@ -1,8 +1,9 @@
#!/bin/bash
+# retrieve files 1 - $2, outputting to `out'
echo "Retrieve:"
-for i in $(seq 1 100)
+for i in $(seq 1 $2)
do
- $1 -u 1 -k a retrievefile -f 1 -o out > /dev/null
+ $1 -u 1 -k a retrievefile -f $i -o out > /dev/null
if [[ $? -ne 0 ]]
then
echo "Request failed!"
diff --git a/trusted_module.c b/trusted_module.c
index c59beb1..c579316 100644
--- a/trusted_module.c
+++ b/trusted_module.c
@@ -90,6 +90,8 @@ void tm_savestate(const struct trusted_module *tm, const char *filename)
}
fwrite(&tm->root, sizeof(tm->root), 1, f);
+
+ printf("Saving state, root=%s\n", hash_format(tm->root, 4).str);
}
struct trusted_module *tm_new_from_savedstate(const char *filename)
@@ -114,6 +116,7 @@ struct trusted_module *tm_new_from_savedstate(const char *filename)
}
fread(&tm->root, sizeof(tm->root), 1, f);
+ printf("Loading state, root=%s\n", hash_format(tm->root, 4).str);
return tm;
}