diff --git a/src/common/common-hash.js b/src/common/common-hash.js index 72f6779cc..560e503fb 100644 --- a/src/common/common-hash.js +++ b/src/common/common-hash.js @@ -20,16 +20,35 @@ var factory = function (Util, Crypto, Keys) { }; Hash.generateSignPair = function () { + // Generate classical Ed25519 keypair var ed = Crypto.CryptoAgility.signKeyPair(); var makeSafe = function (key) { return Crypto.b64RemoveSlashes(key).replace(/=+$/g, ''); }; - return { + + var result = { validateKey: Hash.encodeBase64(ed.publicKey), signKey: Hash.encodeBase64(ed.secretKey), safeValidateKey: makeSafe(Hash.encodeBase64(ed.publicKey)), safeSignKey: makeSafe(Hash.encodeBase64(ed.secretKey)), }; + + // Add post-quantum DSA keypair if available + if (Crypto.PQC && Crypto.PQC.ml_dsa && Crypto.PQC.ml_dsa.ml_dsa44) { + try { + // Derive a deterministic seed from the Ed25519 secret key + var dsaSeed = Crypto.Nacl.hash(ed.secretKey).subarray(0, 32); + var dsaPair = Crypto.CryptoAgility.generateDsaKeypair(dsaSeed); + result.dsaPublic = Hash.encodeBase64(dsaPair.publicKey); + result.dsaPrivate = Hash.encodeBase64(dsaPair.secretKey); + result.safeDsaPublic = makeSafe(Hash.encodeBase64(dsaPair.publicKey)); + result.safeDsaPrivate = makeSafe(Hash.encodeBase64(dsaPair.secretKey)); + } catch (err) { + console.error("Failed to generate post-quantum DSA keys:", err); + } + } + + return result; }; Hash.getSignPublicFromPrivate = function (edPrivateSafeStr) { diff --git a/src/common/outer/login-block.js b/src/common/outer/login-block.js index 2b0d01a90..7201a83fc 100644 --- a/src/common/outer/login-block.js +++ b/src/common/outer/login-block.js @@ -53,7 +53,7 @@ const factory = (Util, ApiConfig = {}, ServerCommand, Nacl, Crypto) => { var pqSeed = Nacl.hash(seed).subarray(0, 32); // Generate post-quantum keypair using the 32-byte hash - pqSignPair = Crypto.PQC.ml_dsa.ml_dsa44.internal.keygen(pqSeed); + pqSignPair = Crypto.CryptoAgility.generateDsaKeypair(pqSeed); } catch (err) { console.error("Failed to generate post-quantum keys:", err); pqSignPair = null; diff --git a/src/worker/components/invitation.js b/src/worker/components/invitation.js index 515ce5def..da671542b 100644 --- a/src/worker/components/invitation.js +++ b/src/worker/components/invitation.js @@ -12,8 +12,8 @@ var factory = function (Util, Cred, Nacl, Crypto) { Invite.generateKeys = function () { var ed = Crypto.CryptoAgility.signKeyPair(); var curve = Crypto.CryptoAgility.curveKeyPair(); - var kem = Crypto.PQC.ml_kem.ml_kem512.keygen(); - var dsa = Crypto.PQC.ml_dsa.ml_dsa44.keygen(); + var kem = Crypto.CryptoAgility.generateKemKeypair(); + var dsa = Crypto.CryptoAgility.generateDsaKeypair(); return { edPublic: encode64(ed.publicKey), edPrivate: encode64(ed.secretKey), @@ -28,7 +28,7 @@ var factory = function (Util, Cred, Nacl, Crypto) { Invite.generateSignPair = function () { var ed = Crypto.CryptoAgility.signKeyPair(); - var dsa = Crypto.PQC.ml_dsa.ml_dsa44.keygen(); + var dsa = Crypto.CryptoAgility.generateKemKeypair(); return { validateKey: encode64(ed.publicKey), signKey: encode64(ed.secretKey), diff --git a/src/worker/modules/support.js b/src/worker/modules/support.js index 8885c3024..89cb3a440 100644 --- a/src/worker/modules/support.js +++ b/src/worker/modules/support.js @@ -62,7 +62,7 @@ const factory = (Util, Hash, Realtime, Pinpad, Crypt, myCurve: ctx.store.proxy.curvePrivate, theirPublic: data.curvePublic || supportKey, // old tickets may use deprecated key myKem: ctx.store.proxy.kemPublic, - theirKem: data.kemPublic, // || supportKemKey, // Needed for PQC, currently making messages unreadable + theirKem: data.kemPublic || supportKemKey, // Needed for PQC, currently making messages unreadable notifKey: supportKey }); }); @@ -1037,7 +1037,7 @@ const factory = (Util, Hash, Realtime, Pinpad, Crypt, let edPublic = proxy.edPublic; const keyPair = Crypto.CryptoAgility.curveKeyPair(); - const kemPair = Crypto.PQC.ml_kem.ml_kem512.keygen(); + const kemPair = Crypto.CryptoAgility.generateKemKeypair(); const newKeyPub = Util.encodeBase64(keyPair.publicKey); const newKey = Util.encodeBase64(keyPair.secretKey); const newKemPublic = Util.encodeBase64(kemPair.publicKey); diff --git a/src/worker/modules/team.js b/src/worker/modules/team.js index 53621506b..746b7ac71 100644 --- a/src/worker/modules/team.js +++ b/src/worker/modules/team.js @@ -664,8 +664,8 @@ const factory = (Util, Hash, Constants, Realtime, ProxyManager, var keyPair = Crypto.CryptoAgility.signKeyPair(); // ed25519 var curvePair = Crypto.CryptoAgility.curveKeyPair(); // Curve25519 - var kemPair = Crypto.PQC.ml_kem.ml_kem512.keygen(); - var dsaPair = Crypto.PQC.ml_dsa.ml_dsa44.keygen(); + var kemPair = Crypto.CryptoAgility.generateKemKeypair(); + var dsaPair = Crypto.CryptoAgility.generateKemKeypair(); var rosterSeed = Crypto.Team.createSeed(); var rosterKeys = Crypto.Team.deriveMemberKeys(rosterSeed, { diff --git a/www/common/common-login.js b/www/common/common-login.js index 1fdaee852..1e37264e2 100644 --- a/www/common/common-login.js +++ b/www/common/common-login.js @@ -46,7 +46,7 @@ define([ // KEM keys (post-quantum) var kemSeed = dispense(64); // 64 bytes for post-quantum KEM keys if (Crypto.PQC && Crypto.PQC.ml_kem && Crypto.PQC.ml_kem.ml_kem512) { - var pqKemPair = Crypto.PQC.ml_kem.ml_kem512.keygen(new Uint8Array(kemSeed)); + var pqKemPair = Crypto.CryptoAgility.generateKemKeypair(new Uint8Array(kemSeed)); opt.kemPrivate = Util.encodeBase64(pqKemPair.secretKey); opt.kemPublic = Util.encodeBase64(pqKemPair.publicKey); } else {