https://github.com/trailofbits/lms-rust
A Rust implementation of LMS and LM-OTS. See RustCrypto for living code.
https://github.com/trailofbits/lms-rust
cryptography digital-signature hash-based-signatures pqc
Last synced: 9 months ago
JSON representation
A Rust implementation of LMS and LM-OTS. See RustCrypto for living code.
- Host: GitHub
- URL: https://github.com/trailofbits/lms-rust
- Owner: trailofbits
- License: apache-2.0
- Archived: true
- Created: 2024-01-30T19:37:14.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-03-13T16:03:39.000Z (10 months ago)
- Last Synced: 2025-03-28T12:51:15.745Z (10 months ago)
- Topics: cryptography, digital-signature, hash-based-signatures, pqc
- Language: Rust
- Homepage: https://crates.io/crates/lms-signature
- Size: 1.35 MB
- Stars: 7
- Watchers: 11
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# Leighton-Micali Hash-Based Signatures
> [!IMPORTANT]
> This implementation is [now part of RustCrypto]. Users should avoid any
> direct use of this repository and instead use [lms-signature] from RustCrypto.
[now part of RustCrypto]: https://github.com/RustCrypto/signatures/tree/master/lms
[lms-signature]: https://crates.io/crates/lms-signature
This repository contains implementations of [Leighton-Micali Hash-Based
Signatures (RFC 8554)](https://datatracker.ietf.org/doc/html/rfc8554).
## Security Notice
LMS signatures are stateful: Users must take care to never sign more than one
message with the same internal LM-OTS private key. To avoid catastrophe, state
must be maintained across multiple invocations of the signing algorithm.
When using our LMS implementations, the internal counter (`q`) will be
incremented before each signature is returned.
If the LMS private key is persisted to storage, you **MUST** update the
persistent storage after each signature is generated and before it is released
to the rest of the application. Failure to adhere to this requirement is a
security vulnerability in your application.
For a stateless hash-based signature algorithm, see
[SPHINCS+](https://sphincs.org).
NOTE: this project has not been externally audited, but the entire codebase
was internally reviewed by cryptographers at Trail of Bits.
## Installation
```terminal
cargo install
```
## Usage
Our implementation uses strongly typed private and public key types.
```rust
let mut rng = thread_rng();
let mut seckey = lms::lms::PrivateKey::new::>(&mut rng);
let pubkey = seckey.public(); // of type lms::lms::PublicKey
let sig = seckey.try_sign_with_rng(&mut rng, "example".as_bytes()).unwrap();
let sig_valid = pubkey.verify("example".as_bytes(), &sig).is_ok();
```
We can generate LMOTS signatures in the same way using `lms::ots::PrivateKey`
instead.
### Key Management
We do not require much from the user in terms of key management. Any internal
state changing operation uses mutable reference to update the internal state.
When persisting private keys to long term storage, users must be very careful
that **the same private key is never read from disk twice**. This would create
two private keys in the same state and thus when they are both used to sign a
message, the LMOTS private keys will have been reused, which is considered **not
good**.
## License
All crates licensed under either of
* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
* [MIT license](http://opensource.org/licenses/MIT)
at your option.
## Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.