From eb50d1e2007ef4dc581f380d683255d8b283a214 Mon Sep 17 00:00:00 2001 From: Patrick Rathje Date: Tue, 31 May 2022 04:20:40 +0200 Subject: [PATCH] bloom eval --- include/bloom.h | 25 ++++++++++ scripts/eval.py | 59 ++++++++++++++--------- src/bloom.c | 48 +++++++++++++++++++ src/main.c | 123 ++++++++++++++++++++++++++++++++++++------------ 4 files changed, 205 insertions(+), 50 deletions(-) create mode 100644 include/bloom.h create mode 100644 src/bloom.c diff --git a/include/bloom.h b/include/bloom.h new file mode 100644 index 0000000..b3f5fa5 --- /dev/null +++ b/include/bloom.h @@ -0,0 +1,25 @@ +#ifndef BLOOM_H +#define BLOOM_H + +#include "record_storage.h" +#include "exposure-notification.h" + +typedef struct { + uint8_t* data; + size_t size; +} bloom_filter_t; + +/** + * Initialize the bloom filter on basis of the already registerred records. + */ +bloom_filter_t* bloom_init(size_t size); + +void bloom_destroy(bloom_filter_t* bloom); + +// TODO lome: maybe only use RPI (should be sufficient) +void bloom_add_record(bloom_filter_t* bloom, ENIntervalIdentifier* rpi); + +// TODO lome: maybe only use RPI (should be sufficient) +bool bloom_probably_has_record(bloom_filter_t* bloom, ENIntervalIdentifier* rpi); + +#endif \ No newline at end of file diff --git a/scripts/eval.py b/scripts/eval.py index 282aef1..2e9a51c 100644 --- a/scripts/eval.py +++ b/scripts/eval.py @@ -31,6 +31,9 @@ def load_plot_defaults(): #mpl.style.use('tableau-colorblind10') +idle_avg = 0.00252 +idle_max = 0.02325 + IDLE_LABEL = 'idle' consumptions = {} durations = {} @@ -99,39 +102,53 @@ add_consumption(IDLE_LABEL, idle_consumption, 1.0, 1.0) # ADVERTISING adv_interval = 0.250 -per_adv_consumption = { - 0: 2.23, - -4: 1.49 , - -8: 1.43, - -16: 1.38, - -20: 1.3, - -40: 1.22, -} +adv_consumptions = [ + 2.45, + 2.47, + 2.41, + 2.35, + 2.47, + 2.39, + 2.45, + 2.47, + 2.49, + 2.45 +] + +adv_max_consumption = [ + 7.66, + 8.31, + 6.96, + 7.3, + 7.77, + 7.6, + 8.55, + 6.94, + 7.14, + 6.85 +] + + + # TODO: Add error bars if possible! # measured_duration # duration # repetitions - - adv_consumption = sum(list(per_adv_consumption.values())) / len(per_adv_consumption.values()) -add_consumption('adv', adv_consumption, 0.01, (24*3600)/0.25) +add_consumption('adv', adv_consumption, 0.004, (24*3600)/0.25) # SCANNING -scan_consumption = 5.440 -add_consumption('scan', scan_consumption, 1.0, 24*60) +scan_consumption = 6.01 +scan_consumption_max = 8.71 +add_consumption('scan', scan_consumption, 2.015, 24*60) crypt_duration = 0.01 -generate_tek_consumption = 2 -derive_tek_consumption = 2 -derive_rpi_consumption = 2 -encrypt_aem_consumption = 2 +crypt_consumption_avg = 3.2 +crypt_consumption_max = 5.96 -add_consumption('generate_tek', generate_tek_consumption, crypt_duration, 1) -add_consumption('derive_tek', derive_tek_consumption, crypt_duration, 1) -add_consumption('derive_rpi', derive_rpi_consumption, crypt_duration, 144) -add_consumption('encrypt_aem', encrypt_aem_consumption, crypt_duration, 144*len(per_adv_consumption.values())) +add_consumption('daily_crypto', crypt_consumption_avg, 0.22, 10) # A table for the timings of the cryptographic fundamentals # One detailed graph as a comparison of the advertisements diff --git a/src/bloom.c b/src/bloom.c new file mode 100644 index 0000000..4006635 --- /dev/null +++ b/src/bloom.c @@ -0,0 +1,48 @@ +#include "bloom.h" + + +// 64 KByte! +static uint8_t bloom_data[1<<16]; + +bloom_filter_t* bloom_init(size_t size) { + bloom_filter_t* bloom = k_calloc(1, sizeof(bloom_filter_t)); + if (!bloom) { + return NULL; + } + bloom->size = sizeof(bloom_data); + bloom->data = bloom_data; + if (!bloom->data) { + bloom->size = 0; + k_free(bloom); + return NULL; + } + return bloom; +} + +void bloom_destroy(bloom_filter_t* bloom) { + if (bloom) { + k_free(bloom); + } +} + +void bloom_add_record(bloom_filter_t* bloom, ENIntervalIdentifier* rpi) { + uint8_t* data = bloom->data; + + for (int i = 0; i < sizeof(*rpi); i += 4) { + uint32_t hash = (rpi->b[i+3] << 24) | (rpi->b[i+2] << 16) | (rpi->b[i+1] << 8) | rpi->b[i]; + hash %= bloom->size * 8; + data[hash / 8] |= 1 << (hash % 8); + } +} + +bool bloom_probably_has_record(bloom_filter_t* bloom, ENIntervalIdentifier* rpi) { + uint8_t* data = bloom->data; + for (int i = 0; i < sizeof(*rpi); i += 4) { + uint32_t hash = (rpi->b[i+3] << 24) | (rpi->b[i+2] << 16) | (rpi->b[i+1] << 8) | rpi->b[i]; + hash %= bloom->size * 8; + if (!(data[hash / 8] & (1 << (hash % 8)))) { + return false; + } + } + return true; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index afff432..29d0103 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,27 @@ #include "tek_storage.h" #include "sync_service.h" #include "tracing.h" +#include "bloom.h" + + +/** + * Fill the bloom filter with all stored records. + */ +void fill_bloom_with_stored_records(bloom_filter_t* bloom) { + // init iterator for filling bloom filter + record_iterator_t iterator; + int rc = ens_records_iterator_init_timerange(&iterator, NULL, NULL); + if (rc) { + printk("init iterator failed0 (err %d)\n", rc); + return; + } + + // fill bloom filter with records + record_t* current; + while ((current = ens_records_iterator_next(&iterator))) { + bloom_add_record(bloom, &(current->rolling_proximity_identifier)); + } +} void main(void) { @@ -29,50 +50,94 @@ void main(void) { return; } - err = record_storage_init(false); + err = record_storage_init(true); if (err) { printk("init record storage failed (err %d)\n", err); return; } + err = tek_storage_init(false); if (err) { printk("init key storage failed (err %d)\n", err); return; } - /* Initialize the Bluetooth Subsystem */ - err = bt_enable(NULL); - if (err) { - printk("Bluetooth init failed (err %d)\n", err); - return; + k_msleep(10000); + + printk("Filling record storage...\n"); + reset_record_storage(); + + tek_t tek; + ENPeriodIdentifierKey pik; + + tek_storage_get_latest_at_ts(&tek, 0); + en_derive_period_identifier_key(&pik, &tek.tek); + + + bloom_filter_t* bf = bloom_init(0); // size not used atm + + /// we now fill the whole flash memory with stupid data + for (int i = 0; i < CONFIG_ENS_MAX_CONTACTS; ++i) { + record_t dummy_record; + en_derive_interval_identifier((ENIntervalIdentifier*)&dummy_record.rolling_proximity_identifier, &pik, i); + dummy_record.timestamp = i; // very clever! ;) + bloom_add_record(bf, &dummy_record.rolling_proximity_identifier); + if (!bloom_probably_has_record(bf, &dummy_record.rolling_proximity_identifier)) { + printk("error! bloom_probably_has_record\n"); + } } + printk("Done...\n"); + k_msleep(2000); - /* Initialize the Tracing Subsystem */ - err = tracing_init(); - if (err) { - printk("Tracing init failed (err %d)\n", err); - return; - } - - /* Initialize the Gatt Subsystem */ - err = sync_service_init(); - if (err) { - printk("Sync Service init failed (err %d)\n", err); - return; - } - - printk("Components initialized! Starting Tracing and Gatt...\n"); - - // We sleep for one second just - k_sleep(K_MSEC(1000)); + printk("Creating bloom filter...\n"); + fill_bloom_with_stored_records(bf); + printk("Done...\n"); + k_msleep(3000); do { - uint32_t tracing_sleep_ms = tracing_run(); - uint32_t sync_sleep_ms = sync_service_run(); + printk("Checking keys...\n"); + for(int k = 0; k < 144; k++) { - uint32_t sleep_ms = MIN(tracing_sleep_ms, sync_sleep_ms); - //printk("Sleeping a bit (%u ms)...\n", sleep_ms); - k_sleep(K_MSEC(sleep_ms)); // TODO: what to put here? + ENIntervalIdentifier rpi; + en_derive_period_identifier_key(&pik, &tek.tek); + // derive all RPIs + for (int j = 0; j < 144; j++) { + + // we assume that at least one out of 144 RPIs was met (this is still a lot actually!) + uint32_t interval = j == 0 ? (CONFIG_ENS_MAX_CONTACTS / 144)*k : (CONFIG_ENS_MAX_CONTACTS+1); + en_derive_interval_identifier(&rpi, &pik, interval); //one of each is actually + + uint32_t num_met = 0; + if (bloom_probably_has_record(bf, &rpi)) { + num_met++; + /* + record_iterator_t iterator; + + time_t start = interval == 0 ? 0 : (interval+(CONFIG_ENS_MAX_CONTACTS-1)) % CONFIG_ENS_MAX_CONTACTS; + time_t end = (interval+(CONFIG_ENS_MAX_CONTACTS+1)) % CONFIG_ENS_MAX_CONTACTS; + + int rc = ens_records_iterator_init_timerange(&iterator, &start, &end); + if (rc) { + // on error, skip this rpi + printk("iterator error! %d\n", rc); + continue; + } + record_t* current; + while ((current = ens_records_iterator_next(&iterator))) { + if (memcmp(&(current->rolling_proximity_identifier), rpi.b, + sizeof(current->rolling_proximity_identifier)) == 0) { + num_met++; + } + } + ens_record_iterator_clear(&iterator);*/ + } + if(j == 0 && num_met == 0) { + printk("Met mismatch! %u\n", num_met); + } + } + + } + k_sleep(K_MSEC(2000)); } while (1); } \ No newline at end of file