Skip to content

Commit

Permalink
Enforce using SHA3 for ML-DSA signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
larabr committed Nov 14, 2024
1 parent 7b83379 commit 25003ab
Show file tree
Hide file tree
Showing 4 changed files with 740 additions and 778 deletions.
2 changes: 1 addition & 1 deletion src/crypto/public_key/post_quantum/signature/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { generate, sign, verify, validateParams } from './signature';
export { generate, sign, verify, validateParams, getRequiredHashAlgo } from './signature';
export { expandSecretSeed as mldsaExpandSecretSeed } from './ml_dsa';
22 changes: 22 additions & 0 deletions src/crypto/public_key/post_quantum/signature/signature.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ export async function generate(algo) {
}

export async function sign(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey, mldsaSecretKey, dataDigest) {
if (hashAlgo !== getRequiredHashAlgo(signatureAlgo)) {
// The signature hash algo MUST be set to the specified algorithm, see
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
throw new Error('Unexpected hash algorithm for PQC signature');
}

switch (signatureAlgo) {
case enums.publicKey.pqc_mldsa_ed25519: {
const { eccSignature } = await eccdsa.sign(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey, dataDigest);
Expand All @@ -28,6 +34,12 @@ export async function sign(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey,
}

export async function verify(signatureAlgo, hashAlgo, eccPublicKey, mldsaPublicKey, dataDigest, { eccSignature, mldsaSignature }) {
if (hashAlgo !== getRequiredHashAlgo(signatureAlgo)) {
// The signature hash algo MUST be set to the specified algorithm, see
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
throw new Error('Unexpected hash algorithm for PQC signature');
}

switch (signatureAlgo) {
case enums.publicKey.pqc_mldsa_ed25519: {
const eccVerifiedPromise = eccdsa.verify(signatureAlgo, hashAlgo, eccPublicKey, dataDigest, eccSignature);
Expand All @@ -40,6 +52,16 @@ export async function verify(signatureAlgo, hashAlgo, eccPublicKey, mldsaPublicK
}
}

export function getRequiredHashAlgo(signatureAlgo) {
// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
switch (signatureAlgo) {
case enums.publicKey.pqc_mldsa_ed25519:
return enums.hash.sha3_256;
default:
throw new Error('Unsupported signature algorithm');
}
}

export async function validateParams(algo, eccPublicKey, eccSecretKey, mldsaPublicKey, mldsaSeed) {
const eccValidationPromise = eccdsa.validateParams(algo, eccPublicKey, eccSecretKey);
const mldsaValidationPromise = mldsa.validateParams(algo, mldsaPublicKey, mldsaSeed);
Expand Down
6 changes: 6 additions & 0 deletions src/key/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ export async function createBindingSignature(subkey, primaryKey, options, config
* @async
*/
export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), userID = {}, config) {
if (keyPacket.algorithm === enums.publicKey.pqc_mldsa_ed25519) {
// For PQC, the returned hash algo MUST be set to the specified algorithm, see
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
return crypto.publicKey.postQuantum.signature.getRequiredHashAlgo(keyPacket.algorithm);
}

let hashAlgo = config.preferredHashAlgorithm;
let prefAlgo = hashAlgo;
if (key) {
Expand Down
Loading

0 comments on commit 25003ab

Please sign in to comment.