Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dist state mgmt #90

Open
wants to merge 43 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
16bdf8d
Fix typos in README and verify.rs
sschwarzmann Nov 14, 2023
769c951
rustc: fix compile error for PhantomData::default()
sschwarzmann Nov 15, 2023
9dee570
lms.yml: remove mips cross toolchain
sschwarzmann Nov 15, 2023
cb96433
lms.yml: add branch "dist_state_mgmt" for CI
sschwarzmann Nov 15, 2023
be0a82e
lms.yml: replace deprecated command "set-output"
sschwarzmann Nov 15, 2023
fca11a8
lms.yml: revert last change; use checkout@v4
sschwarzmann Nov 15, 2023
f9071da
lms.yml: 2nd try: replace deprecated "set-output"
sschwarzmann Nov 15, 2023
92601d5
CI *.yml: replace deprecated actions-rs
sschwarzmann Nov 15, 2023
44d3802
Add module "sst" (SingleSubTree) and example
sschwarzmann Nov 21, 2023
8b2e5ec
Setup code structure/API
sschwarzmann Dec 12, 2023
c09bd0f
Import code from lms-demo.rs into sst_demo.rs
sschwarzmann Dec 17, 2023
6aa7261
sst: Add some helper file & function incl. tests
sschwarzmann Dec 17, 2023
cb57ebf
sst: adapt parameters for "top part height"
sschwarzmann Dec 19, 2023
c227dba
sst: in demo use loop, move logic to sst:gen_key
sschwarzmann Dec 20, 2023
41937cd
sst: sst_demo: remove key_gen() loop
sschwarzmann Dec 20, 2023
402d1b7
sst: demo: use available constant; add argument
sschwarzmann Dec 21, 2023
8f61a6d
sst: LMS: Extend LmsPrivateKey
sschwarzmann Dec 21, 2023
3ef5b36
sst: LMS: Initialze LmsPrivateKey with SST bounds
sschwarzmann Dec 22, 2023
40fc3b7
sst: demo: read arguments for HSS and SST
sschwarzmann Dec 22, 2023
2ab2b57
sst: extend priv. key data types & tests for SSTS
sschwarzmann Jan 4, 2024
1cbb1cd
sst: impl., store & read sst ext. to/from file
sschwarzmann Jan 6, 2024
f4c3531
sst: calc. and save intermediate SST node value
sschwarzmann Jan 9, 2024
c165fba
sst: calc. public key via signing entity nodes
sschwarzmann Jan 14, 2024
bc1a178
sst: use constant, tag unused symbols (_)
sschwarzmann Jan 14, 2024
96fcb47
sst: apply rustfmt; use SI idx for filenames
sschwarzmann Jan 14, 2024
53ab935
sst: extend two-step key generation
sschwarzmann Jan 16, 2024
020abc9
sst: clean up and simplify key gen steps 1+2
sschwarzmann Jan 17, 2024
93a1c08
sst: Complete and fix public keygen with AUX data
sschwarzmann Jan 19, 2024
31a2852
sst: fix SST ext. var names & sst_demo filenames
sschwarzmann Jan 26, 2024
afeda44
sst: Add script for key generation
sschwarzmann Jan 26, 2024
6da4df1
sst: change parameters for py-script and sst_demo
sschwarzmann Jan 26, 2024
6aded99
sst: py-script: fix auxsize; use functions
sschwarzmann Jan 26, 2024
29aa774
sst: improve and fix AUX data
sschwarzmann Jan 29, 2024
c6aa5ab
sst: fix two errors: TreeIdent, UsedLeafs
sschwarzmann Jan 30, 2024
7c0c9e7
sst: Py: format via black; use f-strings
sschwarzmann Feb 1, 2024
ce4dae8
sst: code cleanup
sschwarzmann Feb 1, 2024
5169aa4
sst: code cleanup: simplify, remove redundancies
sschwarzmann Feb 1, 2024
072c7cb
sst: fix keygen and signing (TreeIdentifier)
sschwarzmann Feb 6, 2024
a22f410
sst: clean up sst_demo and python-demo script
sschwarzmann Apr 24, 2024
c3b251e
sst: Improve naming, API, README; remove comments
sschwarzmann Apr 24, 2024
5b01dd1
sst: Cleanup (fmt, py-black, clippy); adapt README
sschwarzmann May 31, 2024
42f1ea3
sst: rename variable; add comments
sschwarzmann May 31, 2024
dcfe4f7
Add config files cross-build environment
sschwarzmann Jun 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .github/actions/cross-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ inputs:
runs:
using: "composite"
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@v1
with:
profile: minimal
toolchain: ${{ inputs.rust }}
target: ${{ inputs.target }}
override: true
targets: ${{ inputs.target }}
- uses: RustCrypto/actions/cross-install@master
- run: |
# cd ${{ inputs.package }} Not needed, as only a single crate is located in this repository
Expand Down
44 changes: 17 additions & 27 deletions .github/workflows/lms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
pull_request:
branches: [ master ]
push:
branches: [ master ]
branches: [ master, dist_state_mgmt ]

env:
MSRV: 1.57.0
Expand All @@ -15,37 +15,33 @@ jobs:
rustfmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
components: rustfmt
profile: minimal
override: true
- run: |
cargo fmt --version
cargo fmt --all -- --check

clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
components: clippy
profile: minimal
override: true
- run: |
cargo clippy --version
cargo clippy --lib --bins --tests --examples --all-features -- -D warnings

check-for-todos:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- run: make check-for-todos
continue-on-error: true

Expand All @@ -54,7 +50,7 @@ jobs:
outputs:
msrv: ${{ steps.msrv.outputs.msrv }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- name: Install msrv
run: cargo install cargo-msrv
Expand All @@ -68,9 +64,9 @@ jobs:
outputs:
msrv: ${{ steps.msrv.outputs.msrv }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- id: msrv
run: echo "::set-output name=msrv::$(grep rust-version Cargo.toml | cut -d'"' -f2-2)"
run: echo "msrv=$(grep rust-version Cargo.toml | cut -d'"' -f2-2)" >> $GITHUB_OUTPUT

build:
needs: set-msrv
Expand All @@ -84,14 +80,12 @@ jobs:
- thumbv7em-none-eabi
- wasm32-unknown-unknown
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
targets: ${{ matrix.target }}
- run: cargo build --no-default-features --target ${{ matrix.target }}

test:
Expand All @@ -103,13 +97,11 @@ jobs:
- ${{needs.set-msrv.outputs.msrv}}
- stable
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
- run: cargo test
- run: cargo test -- --include-ignored
- run: cargo test --features fast_verify
Expand All @@ -119,11 +111,10 @@ jobs:
needs: set-msrv
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@v1
with:
profile: minimal
toolchain: nightly
- run: rustup run nightly cargo bench

Expand All @@ -137,7 +128,6 @@ jobs:
- stable
target:
- aarch64-unknown-linux-gnu
- mips-unknown-linux-gnu
features:
- default

Expand All @@ -147,7 +137,7 @@ jobs:
# Cross mounts only current package, i.e. by default it ignores workspace's Cargo.toml
working-directory: .
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: ./.github/actions/cross-tests
with:
rust: ${{ matrix.rust }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/security-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
name: Security Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- name: Cache cargo bin
uses: actions/cache@v1
with:
Expand Down
34 changes: 22 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,32 @@ A demo application is located in the `examples` folder to demonstrate the use of
This demo application can be used in the console as follows:

```
# Key generation
# Generates `mykey.priv`, `mykey.pub` with merkle tree height 10 and winternitz parameter 2
cargo run --release --example lms-demo -- genkey mykey 10/2 --seed 0123456701234567012345670123456701234567012345670123456701234567
# 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=c912a74bc8c5fc1b2a73b96e6ce1eb2317dc9aa49806b30e578436d0f659b1f5 --init_tree_ident=1
# 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
cargo run --release --example sst_demo -- prepare_keygen mykey 10/8,5/2 --ssts=3/8 --auxsize=2048 \
--seed=1eb2317dc9aa49806b30e578436d0f659b1f5c912a74bc8c5fc1b2a73b96e6ce --init_tree_ident=0

# 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 3.
cargo run --release --example sst_demo -- finalize_keygen mykey 3

# 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
# 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.pub`
cargo run --release --example lms-demo -- verify mykey message.txt
# Verifies `message.txt` with `message.txt.sig` against `mykey.5.pub`
cargo run --release --example sst_demo -- verify mykey.5 message.txt
```

## Naming conventions wrt to the IETF RFC
Expand Down
95 changes: 65 additions & 30 deletions benches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ extern crate test;
mod tests {
use rand::{rngs::OsRng, RngCore};
use test::Bencher;
use tinyvec::ArrayVec;

use hbs_lms::SstsParameter;
use hbs_lms::{keygen, HssParameter, LmotsAlgorithm, LmsAlgorithm, Seed, Sha256_256};
use hbs_lms::{
signature::{SignerMut, Verifier},
Expand All @@ -23,23 +25,33 @@ mod tests {
let mut seed = Seed::default();
OsRng.fill_bytes(seed.as_mut_slice());

let (signing_key, _) = keygen::<Sha256_256>(hss_parameter, &seed, aux_data).unwrap();
let mut vec_hss_params: ArrayVec<[_; hbs_lms::REF_IMPL_MAX_ALLOWED_HSS_LEVELS]> =
Default::default();
for i in 0..hss_parameter.len() {
vec_hss_params.push(hss_parameter[i]);
}

let sst_param = SstsParameter::<Sha256_256>::new(vec_hss_params, 0, 0);

let (signing_key, _) = keygen::<Sha256_256>(&sst_param, &seed, aux_data).unwrap();

signing_key
}

fn generate_verifying_key_and_signature() -> (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 vec_hss_params: ArrayVec<[_; hbs_lms::REF_IMPL_MAX_ALLOWED_HSS_LEVELS]> =
Default::default();
vec_hss_params.push(HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
));
let sst_param = SstsParameter::<Sha256_256>::new(vec_hss_params, 0, 0);

let (mut signing_key, verifying_key) =
keygen::<Sha256_256>(&sst_param, &seed, None).unwrap();

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

Expand All @@ -50,61 +62,84 @@ mod tests {
fn keygen_h5w2(b: &mut Bencher) {
let mut seed = Seed::default();
OsRng.fill_bytes(seed.as_mut_slice());
let hss_parameter = [HssParameter::new(
let mut vec_hss_params: ArrayVec<[_; hbs_lms::REF_IMPL_MAX_ALLOWED_HSS_LEVELS]> =
Default::default();
vec_hss_params.push(HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
)];
));
let sst_param = SstsParameter::<Sha256_256>::new(vec_hss_params, 0, 0);

b.iter(|| {
let _ = keygen::<Sha256_256>(&hss_parameter, &seed, None);
let _ = keygen::<Sha256_256>(&sst_param, &seed, None);
});
}

#[bench]
fn keygen_with_aux_h5w2(b: &mut Bencher) {
let mut seed = Seed::default();
OsRng.fill_bytes(seed.as_mut_slice());
let hss_parameter = [HssParameter::new(

let mut vec_hss_params: ArrayVec<[_; hbs_lms::REF_IMPL_MAX_ALLOWED_HSS_LEVELS]> =
Default::default();
vec_hss_params.push(HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
)];
));
let sst_param = SstsParameter::<Sha256_256>::new(vec_hss_params, 0, 0);

b.iter(|| {
let mut aux_data = vec![0u8; 100_000];
let aux_slice: &mut &mut [u8] = &mut &mut aux_data[..];

let _ = keygen::<Sha256_256>(&hss_parameter, &seed, Some(aux_slice));
let _ = keygen::<Sha256_256>(&sst_param, &seed, Some(aux_slice));
});
}

#[bench]
fn keygen_h5w2_h5w2(b: &mut Bencher) {
let mut seed = Seed::default();
OsRng.fill_bytes(seed.as_mut_slice());
let hss_parameter = [
HssParameter::new(LmotsAlgorithm::LmotsW2, LmsAlgorithm::LmsH5),
HssParameter::new(LmotsAlgorithm::LmotsW2, LmsAlgorithm::LmsH5),
];

let mut vec_hss_params: ArrayVec<[_; hbs_lms::REF_IMPL_MAX_ALLOWED_HSS_LEVELS]> =
Default::default();
vec_hss_params.push(HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
));
vec_hss_params.push(HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
));
let sst_param = SstsParameter::<Sha256_256>::new(vec_hss_params, 0, 0);

b.iter(|| {
let _ = keygen::<Sha256_256>(&hss_parameter, &seed, None);
let _ = keygen::<Sha256_256>(&sst_param, &seed, None);
});
}

#[bench]
fn keygen_with_aux_h5w2_h5w2(b: &mut Bencher) {
let mut seed = Seed::default();
OsRng.fill_bytes(seed.as_mut_slice());
let hss_parameter = [
HssParameter::new(LmotsAlgorithm::LmotsW2, LmsAlgorithm::LmsH5),
HssParameter::new(LmotsAlgorithm::LmotsW2, LmsAlgorithm::LmsH5),
];

let mut vec_hss_params: ArrayVec<[_; hbs_lms::REF_IMPL_MAX_ALLOWED_HSS_LEVELS]> =
Default::default();
vec_hss_params.push(HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
));
vec_hss_params.push(HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
));
let sst_param = SstsParameter::<Sha256_256>::new(vec_hss_params, 0, 0);

b.iter(|| {
let mut aux_data = vec![0u8; 100_000];
let aux_slice: &mut &mut [u8] = &mut &mut aux_data[..];

let _ = keygen::<Sha256_256>(&hss_parameter, &seed, Some(aux_slice));
let _ = keygen::<Sha256_256>(&sst_param, &seed, Some(aux_slice));
});
}

Expand Down Expand Up @@ -135,7 +170,7 @@ mod tests {
b.iter(|| {
let mut signing_key = signing_key.clone();
signing_key
.try_sign_with_aux(&MESSAGE, Some(aux_slice))
.try_sign_with_aux(&MESSAGE, Some(aux_slice), None)
.unwrap()
});
}
Expand All @@ -153,7 +188,7 @@ mod tests {
b.iter(|| {
let mut signing_key = signing_key.clone();
signing_key
.try_sign_with_aux(&MESSAGE, Some(aux_slice))
.try_sign_with_aux(&MESSAGE, Some(aux_slice), None)
.unwrap()
});
}
Expand All @@ -171,7 +206,7 @@ mod tests {
b.iter(|| {
let mut signing_key = signing_key.clone();
signing_key
.try_sign_with_aux(&MESSAGE, Some(aux_slice))
.try_sign_with_aux(&MESSAGE, Some(aux_slice), None)
.unwrap()
});
}
Expand Down Expand Up @@ -203,7 +238,7 @@ mod tests {
b.iter(|| {
let mut signing_key = signing_key.clone();
signing_key
.try_sign_with_aux(&MESSAGE, Some(aux_slice))
.try_sign_with_aux(&MESSAGE, Some(aux_slice), None)
.unwrap()
});
}
Expand Down
Loading