• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..--

array_ref/25-Apr-2025-6436

array_view/25-Apr-2025-14696

ldt/25-Apr-2025-10,2329,660

ldt_np_adv/25-Apr-2025-2,5762,177

ldt_np_adv_ffi/25-Apr-2025-1,341920

ldt_np_jni/25-Apr-2025-1,298724

ldt_tbc/25-Apr-2025-11556

np_adv/25-Apr-2025-21,90416,265

np_adv_dynamic/25-Apr-2025-757506

np_c_ffi/25-Apr-2025-5,0002,231

np_cpp_ffi/25-Apr-2025-5,0263,571

np_ed25519/25-Apr-2025-190100

np_ffi_core/25-Apr-2025-3,7882,567

np_hkdf/25-Apr-2025-4,2824,036

np_java_ffi/25-Apr-2025-4,1362,443

rand_ext/25-Apr-2025-7946

sink/25-Apr-2025-10156

test_helper/25-Apr-2025-9346

test_vector_hkdf/25-Apr-2025-11038

xts_aes/25-Apr-2025-35,19626,652

CMakeLists.txtD25-Apr-20253.1 KiB10992

README.mdD25-Apr-20258.3 KiB270187

README.md

1# What is this?
2
3Implementations of XTS and LDT for Nearby Presence "v0" advertisements.
4
5See the appendix below for more details on XTS and LDT.
6
7## Project structure
8
9*Note all new crates follow the convention of using underscore `_` instead of
10hyphen `-` in crate names
11
12### `ldt`
13
14An implementation
15of [`LDT`](https://luca-giuzzi.unibs.it/corsi/Support/papers-cryptography/1619-2007-NIST-Submission.pdf)
16which can use `xts-aes` as its tweakable block cipher.
17
18### `ldt_tbc`
19
20The Tweakable Block Cipher traits for use in LDT. These traits have
21implementations in the `xts_aes`
22
23### `ldt_np_adv`
24
25Higher-level wrapper around the core LDT algorithm that does key derivation and
26payload validation the way Nearby Presence advertisements need.
27
28### `ldt_np_adv_ffi`
29
30C API for rust library, currently exposes C/C++ clients the needed API's to use
31the NP specific LDT rust implementation.
32For an example of how to integrate with these API's see program
33in `ldt_np_c_sample`
34
35### `ldt_np_c_sample`
36
37Sample c program which provides its own OpenSSL based AES implementation to
38encrypt data through the LDT rust implementation
39An example of how to interface with the `ldt_np_adv_ffi` API's
40
41### `np_hkdf`
42
43The Key Derivation functions used for creating keys used by nearby presence from
44a key_seed
45
46### `xts_aes`
47
48An implementation
49of [`XTS-AES`](https://luca-giuzzi.unibs.it/corsi/Support/papers-cryptography/1619-2007-NIST-Submission.pdf)
50
51## Setup for MacOS local development
52
53Dependencies:
54
55```
56brew install protobuf rapidjson google-benchmark
57```
58
59We depend on OpenSSL of version at least 3.0.5 being installed on your machine
60to build the fuzzers, for macOS run:
61
62The in-box version of Clang which comes from XCode developer tools does not have
63a fuzzer runtime so we will have to use our own
64
65```
66brew install llvm
67```
68
69then to override the default version it needs to come before it in $PATH. first
70find your path:
71
72```
73$(brew --prefix llvm)/bin
74```
75
76then add this to the beginning of your path
77
78```
79echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> ~/.bash_profile
80export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
81```
82
83verify success with:
84
85```
86clang --version
87```
88
89it should display the path to the homebrew version and not the xcode version.
90
91Some other dependencies you may need include:
92
93```
94brew install ninja bindgen
95```
96
97## Examples
98
99Examples use [clap](https://docs.rs/clap/latest/clap/) for nice CLIs, so try
100running with `--help` to see all args.
101
102*Note:* the examples are in the `ldt` crate, so `cd` into that first.
103
104### `ldt_prp`
105
106Confirm that LDT is, in fact, behaving as a PRP. That is, flipping one bit in
107the ciphertext is on average going to flip half of the bits in the decrypted
108plaintext, and that a change to the first `n` bytes of plaintext is increasingly
109likely to be detected as `n` increases.
110
111```
112cargo run --release --example ldt_prp -- \
113    --trials 1000000 \
114    --check-leading-bytes 16
115```
116
117### `ldt_benchmark`
118
119For interactive exploration of LDT performance looking for a needle in a
120haystack of ciphertexts.
121
122```
123cargo run --release --example ldt_benchmark -- \
124    --trials 500 \
125    --keys 1000
126```
127
128### `ldt_np_c_sample`
129
130From the root directory run the following commands to build and run the C
131sample.
132
133```
134mkdir -p cmake-build && cd cmake-build
135cmake ..
136make
137./ldt_np_c_sample/sample
138```
139
140### `ldt_np_c_sample/tests`
141
142Test cases for the ldt_np_adv_ffi C API which are built alongside the sample,
143use the following commands to run the tests, from root of repo:
144
145```
146mkdir -p cmake-build && cd cmake-build
147cmake .. -DENABLE_TESTS=TRUE
148make
149cd ldt_np_c_sample/tests && ctest
150```
151
152you can then view the output of the tests
153in `ldt_np_c_sample/tests/Testing/Temporary/LastTest.log`
154
155To run the benchmarks:
156
157`ldt_np_c_sample/tests/benchmarks`
158
159## Fuzzing
160
161To build all the fuzzers, run `scripts/build-fuzzers.sh`.
162
163### Rust
164
165Crates with fuzzers: `ldt`, `ldt_np_adv`, `xts_aes`
166
167- `cd` to a crate's directory
168- `cargo fuzz list` to list available fuzzers
169- `cargo fuzz run [fuzzer name]` to run a fuzzer
170
171### C
172
173Build cmake project with `-DENABLE_FUZZ=true`<br>
174Fuzz targets will be output to the build dir for:<br>
175
176- `ldt_np_adv_ffi_fuzz`<br>
177- `np_cpp_ffi/fuzz`
178    - To run `fuzzer_np_cpp_deserialize`
179      use: `./fuzzer_np_cpp_deserialize -max_len=255 corpus`
180    - The `corpus` directory provides seed data to help the fuzzer generate
181      more relevant data to input
182
183## Cross-compilation for Android
184
185- Add the 64bit ARM target to the stable and nightly toolchains:
186    - `rustup target add aarch64-linux-android`
187    - `rustup target add aarch64-linux-android --toolchain nightly`
188
189- Install the v22 NDK that still links against `libgcc` the way rust's stdlib
190  expects.
191    - Newer NDKs use `libunwind` instead, which can be used just fine if you
192      build your own rust stdlib, but for our purposes there's no problem with
193      just using NDK 22
194    - `./sdkmanager --install platform-tools 'ndk;22.0.7026061'`
195
196- Configure the linker used for the ARMv8 Android target to be the NDK's linker.
197    - `export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$ANDROID_HOME/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang`
198    - `export PKG_CONFIG_SYSROOT_DIR=$ANDROID_HOME/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot`
199
200- See if everything builds, using the nightly toolchain for the moment to
201  convince the `aes` crate to use intrinsics on aarch64
202    - `cargo +nightly build --workspace --all-targets --target aarch64-linux-android`
203    - `cargo +nightly bench --workspace --no-run --target aarch64-linux-android`
204
205- Prepare a place for the benchmark to be on the phone
206
207    - `adb shell`
208    - then
209    - `mkdir -p /data/local/tmp/np && cd /data/local/tmp/np`
210    - Leave the shell on the phone open so you can use it to run the benchmark.
211
212- Find the benchmark binary in the build products
213
214    - Use whatever directory you configured as the `target-dir` in
215      `.cargo/config.toml` initially, and look for the file without the
216      trailing `.d`.
217    - `find TARGET_DIR -name 'ldt_scan*' | grep android`
218    - Copy the file to the phone
219    - `adb push FILE_FOUND_ABOVE /data/local/tmp/np/`
220
221- In your `adb shell`, run the benchmark
222
223    - `./ldt_scan-... --bench`
224
225### Building min-sized release cross-compiled for Android
226
227- Copy and paste the following into your `~/.cargo/config.toml`, replacing with
228  a path to your NDK and Host OS
229
230```
231[target.aarch64-linux-android]
232# Replace this with a path to your ndk version and the prebuilt toolchain for your Host OS
233linker = "Library/Android/sdk/ndk/23.2.8568313/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang"
234```
235
236- then run:
237  `cargo +nightly build -Z build-std=core,alloc -Z build-std-features=panic_immediate_abort --target aarch64-linux-android --profile release-min-size`
238
239## Appendix
240
241### XTS
242
243XTS-AES has a NIST
244spec: [The XTS-AES Tweakable Block Cipher - An Extract from IEEE Std 1619-2007](https://luca-giuzzi.unibs.it/corsi/Support/papers-cryptography/1619-2007-NIST-Submission.pdf)
245
246XTS is a scheme for turning a block cipher (AES in this case) into a _tweakable_
247block cipher. Tweakable block ciphers incorporate a _tweak_ which is cheaper to
248change than the key, with the assumption being that the tweak will change with
249each block or sequence of blocks. XTS-AES in particular is used in disk
250encryption, where the sector number or the like might be incorporated into the
251tweak to prevent the same data in different places on the disk being encrypted
252into the same ciphertext.
253
254### LDT
255
256LDT is the current state of the art in length
257doublers: [Efficient Length Doubling From Tweakable Block Ciphers](https://eprint.iacr.org/2017/841.pdf)
258. It builds on top of a tweakable block cipher, which is why we also have an XTS
259implementation.
260
261A length doubler is a way of adapting a block cipher to act as a secure PRP (
262pseudo random permutation) on data of lengths in `[block size, 2 * block size)`.
263For comparison, block ciphers act as PRPs on one block at a time rather than the
264whole message. Wide block modes would also work, but have higher overhead.
265
266We use a length doubler in Nearby Presence so that changing any ciphertext bit
267should flip each bit in the decrypted plaintext with 50% probability for each
268bit, making it possible to detect changes anywhere because it is very unlikely
269for none of the bit flips to affect the metadata key (which has a known digest).
270