Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
103 changes: 69 additions & 34 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Rust
name: Rust

on:
workflow_dispatch:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
branches: [ "main" ]
branches: ["main"]

env:
CARGO_TERM_COLOR: always
Expand Down Expand Up @@ -37,39 +37,74 @@ jobs:
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
components: rustfmt, clippy
- run: ${{ matrix.deps }}
- run: cargo build --target ${{ matrix.target }} --release --all-features
- name: Check Code Format
run: cargo fmt --all -- --check
- name: Code Lint
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Build
run: cargo build --target ${{ matrix.target }} --release --all-features

wasm_builds:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.73.0 # MSRV
- stable
target:
- wasm32-wasi
- wasm32-unknown-unknown
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
- run: cargo build --target ${{ matrix.target }} --features wasm
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.85.0 # MSRV
- stable
target:
- wasm32-wasi
- wasm32-unknown-unknown
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
- run: cargo build --target ${{ matrix.target }} --features wasm

test:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.73.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
- run: cargo test --verbose --release
- run: cargo test --all-features # debug build
- run: cargo test --release --all-features --all-targets
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.85.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
- run: cargo test --verbose --release
- run: cargo test --all-features # debug build
- run: cargo test --release --all-features --all-targets

msrv:
name: Verify MSRV (1.85)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust Toolchain (1.85)
uses: dtolnay/rust-toolchain@1.85.0

- name: Check
run: cargo check --all-features

audit:
name: Security Audit
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust Toolchain
uses: dtolnay/rust-toolchain@stable

- name: Install cargo-audit
run: cargo install cargo-audit

- name: Run cargo audit
run: cargo audit
142 changes: 141 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,136 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.8] - 2026-07-17

### Security
- Replaced the vulnerable `rsa = "0.10.0-rc.18"` crate (RUSTSEC-2023-0071,
Marvin Attack: timing side-channel key recovery) with
`sad-rsa = "0.2.3"`, a hardened fork that implements implicit rejection
to mitigate the Marvin Attack. `sad-rsa` is API-compatible with `rsa`.
All `::rsa::` references updated to `::sad_rsa::` in `src/views/rsa.rs`
and `src/mk.rs`.
- Removed unmaintained `serde_cbor` dependency (RUSTSEC-2021-0127). Replaced
with `ciborium` in both production code (`src/keysplit.rs`,
`src/views/threshold_marker.rs`) and test code (`src/serde/mod.rs`).
- Dropped `ssh-key` `crypto` feature on native target (was
`["alloc", "crypto", "ed25519"]`, now
`["alloc", "ecdsa", "ed25519", "p256", "p384", "p521"]` — matching the
wasm target). This removed the transitive `rsa` dependency via `ssh-key`;
`rsa`/`sad-rsa` is now only a direct dependency.
- Added `ByteBufVisitor` to `src/serde/de.rs` — `Nonce` and `Multikey`
non-human-readable `Deserialize` paths now use `deserialize_byte_buf`
with a visitor that accepts borrowed and owned bytes (compatible with
`serde_test`, `serde_cbor`, and `ciborium`).
- Updated `src/views/bls12381.rs` to use `new_from_bls_signature_with_codec`/
`new_from_bls_signature_share_with_codec` (fixing deprecation warnings from
`multi-sig`'s deprecated constructors).

### Changed
- `src/keysplit.rs`: Added `cbor_to_vec`/`cbor_from_slice` helpers; replaced
`serde_cbor::` calls with `ciborium` equivalents.
- `src/views/threshold_marker.rs`: Replaced `serde_cbor::` calls with
`ciborium::from_reader`/`into_writer`.

### Dependencies
- `rsa = "0.10.0-rc.18"` → `sad-rsa = "0.2.3"` (both with `features = ["sha2"]`)
- Removed `serde_cbor = "0.11"` from `[dependencies]` and `[dev-dependencies]`
- Added `ciborium = "0.2"` to `[dependencies]`
- `ssh-key` (native target): dropped `crypto` feature, added `p256`/`p384`/`p521`

### Documentation
- Updated `SECURITY.md`: removed "Known Vulnerability: `rsa`" section, added
"RSA Implementation: `sad-rsa`" section documenting the Marvin Attack
mitigation. Removed `rsa` from RC dependencies list.

## [1.0.7] - 2026-07-16

### Security
- Added `MAX_DECODED_SIZE = 16 MiB` total decoded-size cap to
`Multikey::try_decode_from` (tracks consumed bytes across the attribute
decode loop, returns `Error::InputTooLarge`). Per-attribute payloads are
also individually capped by `Varbytes::MAX_DECODED_SIZE` via `multi_util`.
Mitigates CWE-400.
- Added `impl ConstantTimeEq for Multikey` — compares the canonical wire
encoding in constant time. Use `mk.ct_eq(&other)` in timing-sensitive
contexts instead of `PartialEq`.
- Documented comment field zeroization decision (R6): the `comment` field is
a plain `String` (not zeroized); key material in `attributes` is wrapped in
`Zeroizing<Vec<u8>>`.

### Changed
- Upgraded to Edition 2024 (`edition = "2024"`, `rust-version = "1.85"`).
- Renamed test helper `gen` → `gen_key` in `src/keysplit.rs` (12 call sites)
to avoid the `gen` reserved keyword in Edition 2024.
- Added `[lints.clippy]` (pedantic/nursery/cargo at warn) and
`[lints.rust] unsafe_code = "deny"` with targeted `#![allow(...)]` for
stylistic lints.
- Added `Error::InputTooLarge { claimed, max }` error variant.
- Exported `MAX_DECODED_SIZE` from crate root.
- Major dependency upgrades: `aes-gcm` 0.10→0.11, `bcrypt-pbkdf` 0.10→0.11,
`chacha20` 0.9→0.10, `chacha20poly1305` 0.10→0.11, `hkdf` 0.12→0.13,
`ml-kem` 0.2→0.3, `poly1305` 0.8→0.9, `sha2` 0.10→0.11.
- Fixed AEAD fallback for legacy ChaCha20-encrypted keys.
- Added `AlgorithmName`/`KeyType` attributes and fixed builder
`try_from_multikey`.

### CI
- Expanded CI from build+test to include: fmt check, clippy `-D warnings`,
MSRV (1.85) check, and cargo audit job. Updated MSRV from 1.73.0 to 1.85.0.

### Documentation
- Added `SECURITY.md` documenting std-only status, RC dependencies, comment
zeroization, decoded-size caps, and constant-time comparison.

### Tests
- Added `test_too_many_attributes_rejected` and `test_valid_roundtrip_with_caps`.

## [1.0.6] - 2026-07-14

### Fixed
- Fixed AEAD fallback for legacy ChaCha20-encrypted keys (added
`legacy_chacha20_fallback` feature, disabled by default — AEAD failure is
a hard error so unauthenticated ciphertext is never returned as valid).
- Added security tests for AEAD fallback behavior.

## [1.0.5] - 2026-07-14

### Added
- Added `AlgorithmName`/`KeyType` attributes to `AttrId`.
- Fixed builder `try_from_multikey` and added algorithm name/key type
attribute support.

### Fixed
- Fixed builder `try_from_multikey` conversion.

## [1.0.4] - 2026-07-14

### Fixed
- Fixed codec values in signature views.

## [1.0.3] - 2026-07-14

### Added
- Added threshold hardening: `ThresholdKeyView` trait, DKG metadata support,
threshold marker module (`threshold_meta.rs`), encrypted threshold
parameters with ChaCha20-Poly1305 AEAD.
- Added `AttrId` variants for threshold disclosure and metadata.
- Updated `README.md` with comprehensive documentation.

### Changed
- Bumped version for threshold hardening release.

## [1.0.2] - 2026-07-13

### Changed
- Updated dependencies to published crates.io versions.

## [1.0.1] - 2026-07-13

### Fixed
- Fixed codec name references after multicodec table sync.
- Bumped `p521` dependency.

## [1.0.0] - 2026-07-13

### Changed
Expand All @@ -22,4 +152,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `frodokem_helper.rs` module (inlined from former bs-frodokem wrapper)
- Added comprehensive test suite (edge cases, proptest, security)
- Major dependency updates: ed25519-dalek 3, blsful 4, elliptic-curve 0.14, vsss-rs 6, ssh-key 0.7
- Initial published release on crates.io as `multi-key`
- Initial published release on crates.io as `multi-key`

[1.0.8]: https://github.com/cryptidtech/multi-key/compare/v1.0.7...v1.0.8
[1.0.7]: https://github.com/cryptidtech/multi-key/compare/v1.0.6...v1.0.7
[1.0.6]: https://github.com/cryptidtech/multi-key/releases/tag/v1.0.6
[1.0.5]: https://github.com/cryptidtech/multi-key/releases/tag/v1.0.5
[1.0.4]: https://github.com/cryptidtech/multi-key/releases/tag/v1.0.4
[1.0.3]: https://github.com/cryptidtech/multi-key/releases/tag/v1.0.3
[1.0.2]: https://github.com/cryptidtech/multi-key/releases/tag/v1.0.2
[1.0.1]: https://github.com/cryptidtech/multi-key/releases/tag/v1.0.1
[1.0.0]: https://github.com/cryptidtech/multi-key/releases/tag/v1.0.0
19 changes: 13 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[package]
name = "multi-key"
version = "1.0.7"
edition = "2021"
version = "1.0.8"
edition = "2024"
rust-version = "1.85"
authors = ["Dave Grantham <dwg@linuxprogrammer.org>"]
description = "Multikey self-describing cryptographic key data"
repository = "https://github.com/cryptidtech/multi-key.git"
Expand Down Expand Up @@ -62,10 +63,9 @@ rand_core = "0.10"
# 0.6 (fn-dsa exposes its own RngCore/CryptoRng traits); keep a 0.6 OsRng for
# those sites while the curve stack above uses rand_core 0.10.
rand_core_06 = { package = "rand_core", version = "0.6", features = ["getrandom"] }
rsa = { version = "0.10.0-rc.18", features = ["sha2"] }
sad-rsa = { version = "0.2.3", features = ["sha2"] }
sec1 = "0.8"
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"], optional = true }
serde_cbor = "0.11"
sha2 = "0.11"
signature = "3"
slh-dsa = "0.2.0-rc.5"
Expand All @@ -85,16 +85,23 @@ ssh-key = { version = "0.7.0-rc.11", default-features = false, features = ["allo

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
blsful = { version = "4.0.0-rc1", default-features = false, features = ["blst"] }
ssh-key = { version = "0.7.0-rc.11", features = ["alloc", "crypto", "ed25519"] }
ssh-key = { version = "0.7.0-rc.11", default-features = false, features = ["alloc", "ecdsa", "ed25519", "p256", "p384", "p521"] }

[dev-dependencies]
criterion = { version = "0.8", features = ["html_reports"] }
proptest = "1.4"
serde_cbor = "0.11"
serde_json = "1.0"
serde_test = "1.0"

[[bench]]
name = "multikey_bench"
harness = false
path = "benches/multikey_bench.rs"

[lints.clippy]
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
cargo = { level = "warn", priority = -1 }

[lints.rust]
unsafe_code = "deny"
Loading
Loading