Skip to content

Commit

Permalink
Update project documentation
Browse files Browse the repository at this point in the history
Signed-off-by: Anjan Roy <[email protected]>
  • Loading branch information
itzmeanjan committed Nov 19, 2024
1 parent 8b538a8 commit be226a4
Showing 1 changed file with 22 additions and 25 deletions.
47 changes: 22 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ For testing functional correctness of this implementation and conformance with M
> Known Answer Test (KAT) files living in [this](./kats/) directory are generated by following (reproducible) steps, described in https://gist.github.com/itzmeanjan/c8f5bc9640d0f0bdd2437dfe364d7710.
```bash
# You can switch to non-default compiler, by setting variable `CXX` i.e. invoke like `$ CXX=clang++ make -j`.
#
make -j # Run tests without any sort of sanitizers
make debug_asan_test -j # Run tests with AddressSanitizer enabled, with `-O1`
make release_asan_test -j # Run tests with AddressSanitizer enabled, with `-O3 -march=native`
make debug_ubsan_test -j # Run tests with UndefinedBehaviourSanitizer enabled, with `-O1`
make release_ubsan_test -j # Run tests with UndefinedBehaviourSanitizer enabled, with `-O3 -march=native`
make test -j # Run tests without any sort of sanitizers, with default C++ compiler.
CXX=clang++ make test -j # Switch to non-default compiler, by setting variable `CXX`.

make debug_asan_test -j # Run tests with AddressSanitizer enabled, with `-O1`.
make release_asan_test -j # Run tests with AddressSanitizer enabled, with `-O3 -march=native`.
make debug_ubsan_test -j # Run tests with UndefinedBehaviourSanitizer enabled, with `-O1`.
make release_ubsan_test -j # Run tests with UndefinedBehaviourSanitizer enabled, with `-O3 -march=native`.
```

```bash
Expand All @@ -81,6 +81,9 @@ PASSED TESTS (15/15):
156 ms: build/test/test.out ML_KEM.ArithmeticOverZq
```

> [!NOTE]
> There is a help menu, which introduces you to all available commands; just run `make` from the root directory of this project.
## Benchmarking

For benchmarking ML-KEM public functions such as keygen, encaps and decaps, for various suggested parameter sets, you have to issue.
Expand Down Expand Up @@ -256,12 +259,10 @@ ml_kem_768/encap_max 169 us 168 us 10 6.037
```bash
cd

# Multi-step cloning and importing of submodules
git clone https://github.com/itzmeanjan/ml-kem.git && pushd ml-kem && git submodule update --init && popd
# Or do single step cloning and importing of submodules
# Single step cloning and importing of submodules
git clone https://github.com/itzmeanjan/ml-kem.git --recurse-submodules
# Or clone and then run tests, which will automatically bring in dependencies
git clone https://github.com/itzmeanjan/ml-kem.git && pushd ml-kem && make -j && popd
git clone https://github.com/itzmeanjan/ml-kem.git && pushd ml-kem && make test -j && popd
```

- Write your program while including proper header files ( based on which variant of ML-KEM you want to use, see [include](./include/ml_kem/) directory ), which includes declarations ( and definitions ) of all required ML-KEM routines and constants ( such as byte length of public/ private key, cipher text etc. ).
Expand All @@ -270,6 +271,7 @@ git clone https://github.com/itzmeanjan/ml-kem.git && pushd ml-kem && make -j &&
// main.cpp

#include "ml_kem/ml_kem_512.hpp"
#include "randomshake/randomshake.hpp"
#include <algorithm>
#include <array>
#include <cassert>
Expand All @@ -289,14 +291,11 @@ main()
std::array<uint8_t, ml_kem_512::SHARED_SECRET_BYTE_LEN> sender_key{};
std::array<uint8_t, ml_kem_512::SHARED_SECRET_BYTE_LEN> receiver_key{};

// Be careful !
//
// Read API documentation in include/ml_kem/internals/rng/prng.hpp
ml_kem_prng::prng_t<128> prng;
randomshake::randomshake_t<128> csprng;

prng.read(d);
prng.read(z);
prng.read(m);
csprng.generate(d);
csprng.generate(z);
csprng.generate(m);

ml_kem_512::keygen(d, z, pkey, skey);
assert(ml_kem_512::encapsulate(m, pkey, cipher, sender_key)); // Key Encapsulation might fail, if input public key is malformed
Expand All @@ -307,16 +306,17 @@ main()
}
```

- When compiling your program, let your compiler know where it can find `ml-kem`, `sha3` and `subtle` headers, which includes their definitions ( all of them are header-only libraries ) too.
- When compiling your program, let your compiler know where it can find `ml-kem`, `sha3`, `RandomShake` and `subtle` headers, which includes their definitions ( all of them are header-only libraries ) too.

```bash
# Assuming `ml-kem` was cloned just under $HOME

ML_KEM_HEADERS=~/ml-kem/include
SHA3_HEADERS=~/ml-kem/sha3/include
RANDOMSHAKE_HEADERS=~/ml-kem/RandomShake/include
SUBTLE_HEADERS=~/ml-kem/subtle/include

g++ -std=c++20 -Wall -Wextra -Wpedantic -O3 -march=native -I $ML_KEM_HEADERS -I $SHA3_HEADERS -I $SUBTLE_HEADERS main.cpp
g++ -std=c++20 -Wall -Wextra -Wpedantic -O3 -march=native -I $ML_KEM_HEADERS -I $SHA3_HEADERS $RANDOMSHAKE_HEADERS -I $SUBTLE_HEADERS main.cpp
```

ML-KEM Variant | Namespace | Header
Expand Down Expand Up @@ -379,10 +379,10 @@ main()
}
```

See example [program](./examples/ml_kem_768.cpp), where I show how to use ML-KEM-768 API.
See example [program](./examples/ml_kem_768.cpp), where I show how to use ML-KEM-768 API. Issue following command to build and execute example.

```bash
g++ -std=c++20 -Wall -Wextra -Wpedantic -O3 -march=native -I ./include -I ./sha3/include -I ./subtle/include/ examples/ml_kem_768.cpp && ./a.out
make example -j
```

```bash
Expand All @@ -394,8 +394,5 @@ Cipher : 618d4938da6a966795627c52fea714ae433de7faefdbbe3339cfd3fcce66c8c
Shared secret : e6a9fc79df8a91733c7f385bc66602a526b54bbf78ed2ac11029a42a2a56f515
```

> [!CAUTION]
> Before you consider using Psuedo Random Number Generator which comes with this library implementation, I strongly advice you to go through [include/ml_kem/internals/rng/prng.hpp](./include/ml_kem/internals/rng/prng.hpp).
> [!NOTE]
> Looking at API documentation, in header files, can give you good idea of how to use ML-KEM API. Note, this library doesn't expose any raw pointer based interface, rather everything is wrapped under statically defined `std::span` - which one can easily create from `std::{array, vector}`. I opt for using statically defined `std::span` based function interfaces because we always know, at compile-time, how many bytes the seeds/ keys/ cipher-texts/ shared-secrets are, for various different ML-KEM parameters. This gives much better type safety and compile-time error reporting.

0 comments on commit be226a4

Please sign in to comment.