Skip to content

Commit

Permalink
Add module-level comments
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmillr committed Jan 2, 2025
1 parent 2cffdf5 commit 15447e3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 56 deletions.
16 changes: 9 additions & 7 deletions src/ml-dsa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import {
concatBytes,
} from './utils.js';

/*
Lattice-based digital signature algorithm. See
[official site](https://www.pq-crystals.org/dilithium/index.shtml),
[repo](https://github.com/pq-crystals/dilithium).
Dilithium has similar internals to Kyber, but their keys and params are different.
*/
/**
* Module Lattice-based Digital Signature Algorithm (ML-DSA). A.k.a. CRYSTALS-Dilithium.
* FIPS-204 is implemented.
*
* Has similar internals to ML-KEM, but their keys and params are different.
* Check out [official site](https://www.pq-crystals.org/dilithium/index.shtml),
* [repo](https://github.com/pq-crystals/dilithium).
* @module
*/

// Constants
const N = 256;
Expand Down
42 changes: 21 additions & 21 deletions src/ml-kem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,27 @@ import {
vecCoder,
} from './utils.js';

/*
Lattice-based key encapsulation mechanism.
See [official site](https://www.pq-crystals.org/kyber/resources.shtml),
[repo](https://github.com/pq-crystals/kyber),
[spec](https://datatracker.ietf.org/doc/draft-cfrg-schwabe-kyber/).
Key encapsulation is similar to DH / ECDH (think X25519), with important differences:
- We can't verify if it was "Bob" who've sent the shared secret.
In ECDH, it's always verified
- Kyber is probabalistic and relies on quality of randomness (CSPRNG).
ECDH doesn't (to this extent).
- Kyber decapsulation never throws an error, even when shared secret was
encrypted by a different public key. It will just return a different
shared secret
There are some concerns with regards to security: see
[djb blog](https://blog.cr.yp.to/20231003-countcorrectly.html) and
[mailing list](https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/W2VOzy0wz_E).
*/
/**
* Module Lattice-based Key Encapsulation Mechanism (ML-KEM). A.k.a. CRYSTALS-Kyber.
* FIPS-203 is implemented.
*
* Key encapsulation is similar to DH / ECDH (think X25519), with important differences:
* * Unlike in ECDH, we can't verify if it was "Bob" who've sent the shared secret
* * Unlike ECDH, it is probabalistic and relies on quality of randomness (CSPRNG).
* * Decapsulation never throws an error, even when shared secret was
* encrypted by a different public key. It will just return a different shared secret.
*
* There are some concerns with regards to security: see
* [djb blog](https://blog.cr.yp.to/20231003-countcorrectly.html) and
* [mailing list](https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/W2VOzy0wz_E).
*
* Has similar internals to ML-DSA, but their keys and params are different.
*
* Check out [official site](https://www.pq-crystals.org/kyber/resources.shtml),
* [repo](https://github.com/pq-crystals/kyber),
* [spec](https://datatracker.ietf.org/doc/draft-cfrg-schwabe-kyber/).
* @module
*/

const N = 256; // Kyber (not FIPS-203) supports different lengths, but all std modes were using 256
const Q = 3329; // 13*(2**8)+1, modulo prime
Expand Down
53 changes: 25 additions & 28 deletions src/slh-dsa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,31 @@ import {
vecCoder,
} from './utils.js';

/*
Hash-based digital signature algorithm. See [official site](https://sphincs.org).
We implement spec v3.1 with latest FIPS-205 changes.
It's compatible with the latest version in the [official repo](https://github.com/sphincs/sphincsplus).
*/

/*
WOTS: One-time signatures (can be forged if same key used twice)
FORS: Forest of Random Subsets
Hashes are like signatures. You take private key, hash it, and share the result pubKey.
After that you can verify it was yours by also sharing the private key.
However, it will only work once: after pre-image was disclosed, it can't be used again.
It also doesn't sign the message: can be interceptd and message can be replaced.
How to solve "one-time" hashing? Instead of hash(k), we can provide merkle tree root hash:
h(h(h(0) || h(1)) || h(h(2) || h(3))))
Now, we have the same pubKey output of hash, but disclosing one path in tree doesn't
invalidate the others, since they are still unknown. By choosing path which is related
to the message, we can "sign" it.
There is a limitation: only a fixed amount of signatures can be made,
a merkle tree with depth: 8 would mean 2**8 (256) paths aka 256 distinct messages.
Attaching a different tree to each node will solve forgeries, but the key would still degrade.
*/
/**
* StateLess Hash-based Digital Signature Standard (SLH-DSA). A.k.a. Sphincs+.
* FIPS-205 (spec v3.1) is implemented.
*
* Hashes function similarly to signatures. You hash a private key to get a public key,
* which can be used to verify the private key. However, this only works once since
* disclosing the pre-image invalidates the key.
*
* To address the "one-time" limitation, we can use a Merkle tree root hash:
* h(h(h(0) || h(1)) || h(h(2) || h(3))))
*
* This allows us to have the same public key output from the hash, but disclosing one
* path in the tree doesn't invalidate the others. By choosing a path related to the
* message, we can "sign" it.
*
* Limitation: Only a fixed number of signatures can be made. For instance, a Merkle tree
* with depth 8 allows 256 distinct messages. Using different trees for each node can
* prevent forgeries, but the key will still degrade over time.
*
* WOTS: One-time signatures (can be forged if same key used twice).
* FORS: Forest of Random Subsets
*
* Check out [official site](https://sphincs.org) & [repo](https://github.com/sphincs/sphincsplus).
* @module
*/

/**
* * N: Security parameter (in bytes). W: Winternitz parameter
Expand Down

0 comments on commit 15447e3

Please sign in to comment.