Crates.io | cosmian_findex |
lib.rs | cosmian_findex |
version | 6.0.0 |
source | src |
created_at | 2022-09-28 06:55:55.110618 |
updated_at | 2023-12-08 09:08:53.800637 |
description | Symmetric Searchable Encryption |
homepage | |
repository | https://github.com/Cosmian/findex/ |
max_upload_size | |
id | 675472 |
size | 3,196,307 |
Findex aims to solve the following problem:
How to securely recover the location of an encrypted data matching a given keyword?
It is a cryptographic protocol designed to securely make search queries on an untrusted cloud server. Thanks to its encrypted indexes, large databases can securely be outsourced without compromising usability.
Findex is part of Cosmian Cloudproof Encryption.
Findex allows indexing values by keywords. These values can be locations (UIDs of an encrypted database, URLs, paths, etc.).
Using Findex API one can:
FindexUpsert
trait;FindexSearch
trait;FindexCompact
trait.These traits can be automatically implemented and a macro is provided to help
with the syntax. The default parameters (the ones used by the macro) are
defined in parameters.rs
.
Findex delegates to the user the implementation of callbacks to manipulate the indexes. This makes Findex compatible with any database technology since no database-specific code is part of it. Implementation is done via the
See in_memory_example.rs
for an example of implementation.
To build Findex simply run:
cargo build --release
To test, run:
cargo test --release --all-features
To launch the benchmarks, run:
cargo bench --all-features
Findex relies on two server-side indexes:
Findex indexes are key-value stores whose structure is given in the following tables, with $K_{w_i}$ the ephemeral key associated with a keyword $w_i$, $H_{w_i}$ the hash of $w_i$ and $UID_{last}$ the last UID of the chain of indexed values associated to $w_i$.
Entry Table | |||
---|---|---|---|
key | value | ||
UID | $K_{w_i}$ | $H_{w_i}$ | $UID_{last}$ |
Chain Table | |||
---|---|---|---|
key | value | ||
UID | $\textnormal{block}_1$ | ... | $\textnormal{block}_B$ |
The Chain Table values are serialized as follows (sizes are given in bytes):
flag | Block1 | ... | BlockB | |||
---|---|---|---|---|---|---|
prefix | data | ... | prefix | data | ||
Size (in bytes) | 1 | 1 | 16 | ... | 1 | 16 |
When stored, the values of the indexes are symmetrically encrypted with an AEAD. Our implementation uses a 16-bytes MAC tag and a 12-bytes nonce.
The flag is used to mark the blocks as being addition or deletions. Each bit corresponds to a block, which limits the possible number of blocks inside a single Chain Table value to 8. The prefix is used to write the actual length of the data stored inside a block.
Therefore:
L_{entry~table} = (L_{uid} + C_e + L_{K_{w_i}} + L_{H_{w_i}} + L_{uid}) \cdot N
= 140 \cdot N
L_{chain~table} = \left(L_{uid} + C_e + 1 + B * (1 + L_{block})\right) \sum\limits_{i~\in~[1,N]}\left\lceil \frac{V(w_i)}{B}\right\rceil
= 146 \sum\limits_{i~\in~[1;N]}\left\lceil \frac{V(w_i)}{5}\right\rceil
where:
Naive (locations are indexed for all possible slices):
mar
-> {locations}mart
-> {locations}marti
-> {locations}martin
-> {locations}martine
-> {locations}Mixed:
mar
-> martine
mart
-> martine
marti
-> martine
martin
-> martine
martine
-> {locations}Graph:
mar
-> mart
mart
-> marti
marti
-> martin
martin
-> martine
martine
-> {locations}More client/server interactions are needed for the graph solution: the depth of the graph (4 in this example) compared to 1 for the naive solution and 2 for the mixed solution.
On the other hand, the graph solution optimizes the size of the Chain Table.
Avg locations | #records | size (in KB) | ratio | |||||
---|---|---|---|---|---|---|---|---|
naive | mixed | graph | naive | mixed | graph | mixed / naive | graph / naive | |
1 | 49016 | 53058 | 49316 | 6988 | 7564 | 7031 | 1.08 | 1.01 |
2 | 58253 | 57347 | 53526 | 8305 | 8176 | 7631 | 0.98 | 0.92 |
3 | 71455 | 61817 | 57949 | 10187 | 8813 | 8262 | 0.87 | 0.81 |
4 | 80692 | 66671 | 62785 | 11504 | 9505 | 8951 | 0.83 | 0.78 |
5 | 86048 | 72676 | 69014 | 12268 | 10362 | 9839 | 0.84 | 0.80 |
The benchmarks presented in this section are run on an Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz.
Findex supporting paper can be found the Findex whitepaper.
The developer documentation can be found on doc.rs