Skip to content

Commit

Permalink
WIP tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aewag committed Sep 17, 2024
1 parent 17819d1 commit e4fed40
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 70 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/lms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,49 @@ jobs:
package: ${{ github.workflow }}
target: ${{ matrix.target }}
features: ${{ matrix.features }}

# Demo scripts
demo-lms:
needs: set-msrv
strategy:
matrix:
rust:
- stable
features:
- default

runs-on: ubuntu-latest
defaults:
run:
# Cross mounts only current package, i.e. by default it ignores workspace's Cargo.toml
working-directory: .
steps:
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- run: sh scripts/lms-demo.sh

# Demo scripts
demo-sst:
needs: set-msrv
strategy:
matrix:
rust:
- stable
features:
- default

runs-on: ubuntu-latest
defaults:
run:
# Cross mounts only current package, i.e. by default it ignores workspace's Cargo.toml
working-directory: .
steps:
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- run: sh scripts/sst-demo.sh
58 changes: 2 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,62 +12,8 @@ This implementation is binary compatible with the reference implementation found
This crate does not require the standard library (i.e. no_std capable) and can be easily used for bare-metal programming.

## Demo
A demo application is located in the `examples` folder to demonstrate the use of the library.
This demo application can be used in the console as follows:

```
# Key generation
# Generates `mykey.prv`, `mykey.pub` with merkle tree height 10 and winternitz parameter 2
cargo run --release --example lms-demo -- genkey mykey 10/2 --seed 0123456701234567012345670123456701234567012345670123456701234567
# Signing
# Generates `message.txt.sig`
cargo run --release --example lms-demo -- sign mykey message.txt
# Signing (fast_verification)
# Generates `message.txt_mut`, `message.txt_mut.sig`
HBS_LMS_MAX_HASH_OPTIMIZATIONS=1000 HBS_LMS_THREADS=2 cargo run --release --example lms-demo \
--features fast_verify -- sign_mut mykey message.txt
# Verification
# Verifies `message.txt` with `message.txt.sig` against `mykey.pub`
cargo run --release --example lms-demo -- verify mykey message.txt
```

The SST extension can be used as follows:

```
# Key generation: prepare
# Generates intermediate node, generates or reads the tree identifier (init_tree_ident 1/0), and uses "mykey" as filename base.
# One dedicated signing entity has to create the common L-0 tree identifier (--init_tree_ident=1) before other signing entities
# can generate their subtrees.
#
# The following example uses two HSS levels, first with tree height = 10 / Winternitz = 8, second with 5 / 2.
# First, a signing entity (here: 1 of 8) creates the tree identifier
cargo run --release --example sst-demo -- prepare_keygen mykey 10/8,5/2 --ssts=1/8 --auxsize=2048 \
--seed=c912a74bc8c5fc1b2a73b96e6ce1eb2317dc9aa49806b30e --init_tree_ident
# The signing instance index is 3 of total 8, and this signing entity will use the tree identifier and use another secret seed.
# This will use "mykey.5.prv" and "mykey.5.aux" for private key and aux data, and "mykey_treeident.bin" to write the tree identifier
seq 2 8 | xargs -i{} cargo run --release --example sst-demo -- prepare_keygen mykey 10/8,5/2 --ssts={}/8 --auxsize=2048 \
--seed=1eb2317dc9aa49806b30e578436d0f659b1f5c912a74bc8c
# Key generation: finalize
# After all signing entities have created their intermediate node values, the public key can be generated.
# This will use mykey.5.pub to write the public key for signing entity index 5.
cargo run --release --example sst-demo -- finalize_keygen mykey 5
# Signing
# Generates `message.txt.sig` using mykey.5.prv
cargo run --release --example sst-demo -- sign mykey.5 message.txt
# Verification
# Verifies `message.txt` with `message.txt.sig` against `mykey.5.pub`
cargo run --release --example sst-demo -- verify mykey.5 message.txt
# Verification can as well performed with lms-demo
# Verifies `message.txt` with `message.txt.sig` against `mykey.5.pub`
cargo run --release --example lms-demo -- verify mykey.5 message.txt
```
Two demo applications are located in the `examples` folder to demonstrate the use of the library.
The examples are the [lms-demo](scripts/lms-demo.sh) and the [sst-demo](scripts/sst-demo.sh).

## Naming conventions wrt to the IETF RFC
The naming in the RFC is done by using a single character.
Expand Down
44 changes: 30 additions & 14 deletions benches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,13 @@ mod tests {
signing_key
}

fn generate_verifying_key_and_signature() -> (VerifyingKey<Sha256_256>, Signature) {
fn generate_verifying_key_and_signature(
hss_parameter: &[HssParameter<Sha256_256>],
) -> (VerifyingKey<Sha256_256>, Signature) {
let mut seed = Seed::default();
OsRng.fill_bytes(seed.as_mut_slice());
let (mut signing_key, verifying_key) = keygen::<Sha256_256>(
&[HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
)],
&seed,
None,
)
.unwrap();
let (mut signing_key, verifying_key) =
keygen::<Sha256_256>(&hss_parameter, &seed, None).unwrap();

let signature = signing_key.try_sign(&MESSAGE).unwrap();

Expand Down Expand Up @@ -209,17 +204,38 @@ mod tests {
}

#[bench]
fn verify(b: &mut Bencher) {
let (verifying_key, signature) = generate_verifying_key_and_signature();
fn verify_h5w2(b: &mut Bencher) {
let hss_parameter = [HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
)];
let (verifying_key, signature) = generate_verifying_key_and_signature(&hss_parameter);

b.iter(|| {
let _ = verifying_key.verify(&MESSAGE, &signature).is_ok();
});
}

#[bench]
fn verify_h5w2_h5w2(b: &mut Bencher) {
let hss_parameter = [
HssParameter::new(LmotsAlgorithm::LmotsW2, LmsAlgorithm::LmsH5),
HssParameter::new(LmotsAlgorithm::LmotsW2, LmsAlgorithm::LmsH5),
];
let (verifying_key, signature) = generate_verifying_key_and_signature(&hss_parameter);

b.iter(|| {
let _ = verifying_key.verify(&MESSAGE, &signature).is_ok();
});
}

#[bench]
fn verify_reference(b: &mut Bencher) {
let (verifying_key, signature) = generate_verifying_key_and_signature();
fn verify_reference_h5w2(b: &mut Bencher) {
let hss_parameter = [HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
)];
let (verifying_key, signature) = generate_verifying_key_and_signature(&hss_parameter);
let ref_signature = VerifierSignature::from_ref(signature.as_ref()).unwrap();

b.iter(|| {
Expand Down
24 changes: 24 additions & 0 deletions scripts/lms-demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
touch message.txt

random="$(dd if=/dev/urandom bs=24 count=1 status=none | hexdump -v -e '/1 "%02X"'; echo)"

# Key generation
# Generates `mykey.prv`, `mykey.pub` with merkle tree height 10 and winternitz parameter 2
cargo run --release --example lms-demo -- genkey mykey 5/4,5/4 --seed $random &&

# Signing
# Generates `message.txt.sig`
cargo run --release --example lms-demo -- sign mykey message.txt &&

# Verification
# Verifies `message.txt` with `message.txt.sig` against `mykey.pub`
cargo run --release --example lms-demo -- verify mykey message.txt &&

# # Signing (fast_verification)
# # Generates `message.txt_mut`, `message.txt_mut.sig`
# HBS_LMS_MAX_HASH_OPTIMIZATIONS=1000 HBS_LMS_THREADS=1 cargo run --release --example lms-demo \
# --features fast_verify -- sign_mut mykey message.txt &&

# Verification
# Verifies `message.txt` with `message.txt.sig` against `mykey.pub`
cargo run --release --example lms-demo -- verify mykey message.txt
39 changes: 39 additions & 0 deletions scripts/sst-demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
MAX_SE_IDX=8

touch message.txt

random="$(dd if=/dev/urandom bs=24 count=1 status=none | hexdump -v -e '/1 "%02X"'; echo)"

# Key generation: prepare
# Generates intermediate node, generates or reads the tree identifier (init_tree_ident 1/0), and uses "mykey" as filename base.
# One dedicated signing entity has to create the common L-0 tree identifier (--init_tree_ident=1) before other signing entities
# can generate their subtrees.
#
# The following example uses two HSS levels, first with tree height = 10 / Winternitz = 8, second with 5 / 2.
# First, a signing entity (here: 1 of 8) creates the tree identifier
cargo run --release --example sst-demo -- prepare_keygen mykey 10/4 --ssts=1/$MAX_SE_IDX \
--auxsize=2048 --seed $random --init_tree_ident

for se_idx in $(seq 2 $MAX_SE_IDX);
do
random="$(dd if=/dev/urandom bs=24 count=1 status=none | hexdump -v -e '/1 "%02X"'; echo)"

# Create signing entities with index 2 to 8, will use same tree identifier but another secret seed.
# This will use "mykey.X.prv" and "mykey.X.aux" for private key and aux data, and "mykey.X_treeident.bin" to write the tree identifier
cargo run --release --example sst-demo -- prepare_keygen mykey 10/4 --ssts=$se_idx/$MAX_SE_IDX \
--auxsize=2048 --seed $random
done

# Key generation: finalize
# After all signing entities have created their intermediate node values, the public key can be generated.
# This will use mykey.5.pub to write the public key for signing entity index 5.
cargo run --release --example sst-demo -- finalize_keygen mykey 5 &&

# Signing
# Generates `message.txt.sig` using mykey.5.prv
cargo run --release --example sst-demo -- sign mykey.5 message.txt &&

# Verification
# Verifies `message.txt` with `message.txt.sig` against `mykey.5.pub`
cargo run --release --example sst-demo -- verify mykey.5 message.txt &&
cargo run --release --example lms-demo -- verify mykey.5 message.txt

0 comments on commit e4fed40

Please sign in to comment.