From 06cf027d4e03da2ce885394069c9ed87dad3cc7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Oct 2025 15:48:14 +0000 Subject: [PATCH] Bump @noble/curves to v2 --- package-lock.json | 25 ++++-- package.json | 2 +- .../elliptic/brainpool/brainpoolP256r1.ts | 23 ----- .../elliptic/brainpool/brainpoolP384r1.ts | 23 ----- .../elliptic/brainpool/brainpoolP512r1.ts | 23 ----- src/crypto/public_key/elliptic/ecdsa.js | 25 +++--- .../public_key/elliptic/noble_curves.js | 12 +-- test/crypto/brainpool_rfc7027.js | 83 ------------------- test/crypto/index.js | 2 - 9 files changed, 36 insertions(+), 182 deletions(-) delete mode 100644 src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts delete mode 100644 src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts delete mode 100644 src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts delete mode 100644 test/crypto/brainpool_rfc7027.js diff --git a/package-lock.json b/package-lock.json index 72322814..912facf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "devDependencies": { "@eslint/js": "^9.37.0", "@noble/ciphers": "^1.3.0", - "@noble/curves": "^1.9.7", + "@noble/curves": "^2.0.1", "@noble/hashes": "^1.8.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", @@ -1041,16 +1041,29 @@ } }, "node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.0.1.tgz", + "integrity": "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "1.8.0" + "@noble/hashes": "2.0.1" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", + "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" diff --git a/package.json b/package.json index faddef68..8dc52723 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@eslint/js": "^9.37.0", "@noble/ciphers": "^1.3.0", - "@noble/curves": "^1.9.7", + "@noble/curves": "^2.0.1", "@noble/hashes": "^1.8.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts deleted file mode 100644 index a1d25067..00000000 --- a/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createCurve } from '@noble/curves/_shortw_utils'; -import { sha256 } from '@noble/hashes/sha256'; -import { Field } from '@noble/curves/abstract/modular'; - -// brainpoolP256r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.4 - -const Fp = Field(BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377')); -const CURVE_A = Fp.create(BigInt('0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9')); -const CURVE_B = BigInt('0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6'); - -// prettier-ignore -export const brainpoolP256r1 = createCurve({ - a: CURVE_A, // Equation params: a, b - b: CURVE_B, - Fp, - // Curve order (q), total count of valid points in the field - n: BigInt('0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7'), - // Base (generator) point (x, y) - Gx: BigInt('0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262'), - Gy: BigInt('0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997'), - h: BigInt(1), - lowS: false -} as const, sha256); diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts deleted file mode 100644 index 0ba5dc52..00000000 --- a/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createCurve } from '@noble/curves/_shortw_utils'; -import { sha384 } from '@noble/hashes/sha512'; -import { Field } from '@noble/curves/abstract/modular'; - -// brainpoolP384 r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.6 - -const Fp = Field(BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53')); -const CURVE_A = Fp.create(BigInt('0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f8aa5814a503ad4eb04a8c7dd22ce2826')); -const CURVE_B = BigInt('0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d57cb4390295dbc9943ab78696fa504c11'); - -// prettier-ignore -export const brainpoolP384r1 = createCurve({ - a: CURVE_A, // Equation params: a, b - b: CURVE_B, - Fp, - // Curve order (q), total count of valid points in the field - n: BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7cf3ab6af6b7fc3103b883202e9046565'), - // Base (generator) point (x, y) - Gx: BigInt('0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8e826e03436d646aaef87b2e247d4af1e'), - Gy: BigInt('0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff99129280e4646217791811142820341263c5315'), - h: BigInt(1), - lowS: false -} as const, sha384); diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts deleted file mode 100644 index a4866bac..00000000 --- a/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createCurve } from '@noble/curves/_shortw_utils'; -import { sha512 } from '@noble/hashes/sha512'; -import { Field } from '@noble/curves/abstract/modular'; - -// brainpoolP512r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.7 - -const Fp = Field(BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3')); -const CURVE_A = Fp.create(BigInt('0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca')); -const CURVE_B = BigInt('0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723'); - -// prettier-ignore -export const brainpoolP512r1 = createCurve({ - a: CURVE_A, // Equation params: a, b - b: CURVE_B, - Fp, - // Curve order (q), total count of valid points in the field - n: BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069'), - // Base (generator) point (x, y) - Gx: BigInt('0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098eff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822'), - Gy: BigInt('0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892'), - h: BigInt(1), - lowS: false -} as const, sha512); diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index ab98d618..4c5f318f 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -25,7 +25,6 @@ import util from '../../../util'; import { getRandomBytes } from '../../random'; import { computeDigest } from '../../hash'; import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves, checkPublicPointEnconding } from './oid_curves'; -import { bigIntToUint8Array } from '../../biginteger'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -72,10 +71,10 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdsa, curve.name); // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch - const signature = nobleCurve.sign(hashed, privateKey, { lowS: false }); + const signature = nobleCurve.sign(hashed, privateKey, { lowS: false, prehash: false }); return { - r: bigIntToUint8Array(signature.r, 'be', curve.payloadSize), - s: bigIntToUint8Array(signature.s, 'be', curve.payloadSize) + r: signature.slice(0, curve.payloadSize), + s: signature.slice(curve.payloadSize, curve.payloadSize << 1) }; } @@ -183,7 +182,7 @@ export async function validateParams(oid, Q, d) { async function jsVerify(curve, signature, hashed, publicKey) { const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdsa, curve.name); // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch - return nobleCurve.verify(util.concatUint8Array([signature.r, signature.s]), hashed, publicKey, { lowS: false }); + return nobleCurve.verify(util.concatUint8Array([signature.r, signature.s]), hashed, publicKey, { lowS: false, prehash: false }); } async function webSign(curve, hashAlgo, message, keyPair) { @@ -254,11 +253,11 @@ function nodeSign(curve, hashAlgo, message, privateKey) { privateKey: nodeBuffer.from(privateKey) }); - const sign = nodeCrypto.createSign(enums.read(enums.hash, hashAlgo)); - sign.write(message); - sign.end(); + const signInstance = nodeCrypto.createSign(enums.read(enums.hash, hashAlgo)); + signInstance.write(message); + signInstance.end(); - const signature = new Uint8Array(sign.sign({ key: derPrivateKey, format: 'der', type: 'sec1', dsaEncoding: 'ieee-p1363' })); + const signature = new Uint8Array(signInstance.sign({ key: derPrivateKey, format: 'der', type: 'sec1', dsaEncoding: 'ieee-p1363' })); const len = curve.payloadSize; return { @@ -275,14 +274,14 @@ function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) { publicKey: nodeBuffer.from(publicKey) }); - const verify = nodeCrypto.createVerify(enums.read(enums.hash, hashAlgo)); - verify.write(message); - verify.end(); + const verifyInstance = nodeCrypto.createVerify(enums.read(enums.hash, hashAlgo)); + verifyInstance.write(message); + verifyInstance.end(); const signature = util.concatUint8Array([r, s]); try { - return verify.verify({ key: derPublicKey, format: 'der', type: 'spki', dsaEncoding: 'ieee-p1363' }, signature); + return verifyInstance.verify({ key: derPublicKey, format: 'der', type: 'spki', dsaEncoding: 'ieee-p1363' }, signature); } catch { return false; } diff --git a/src/crypto/public_key/elliptic/noble_curves.js b/src/crypto/public_key/elliptic/noble_curves.js index acfac17e..c503ca63 100644 --- a/src/crypto/public_key/elliptic/noble_curves.js +++ b/src/crypto/public_key/elliptic/noble_curves.js @@ -4,14 +4,10 @@ * which share a lot of code anyway. */ -import { p256 as nistP256 } from '@noble/curves/p256'; -import { p384 as nistP384 } from '@noble/curves/p384'; -import { p521 as nistP521 } from '@noble/curves/p521'; -import { x448, ed448 } from '@noble/curves/ed448'; -import { secp256k1 } from '@noble/curves/secp256k1'; -import { brainpoolP256r1 } from './brainpool/brainpoolP256r1'; -import { brainpoolP384r1 } from './brainpool/brainpoolP384r1'; -import { brainpoolP512r1 } from './brainpool/brainpoolP512r1'; +import { p256 as nistP256, p384 as nistP384, p521 as nistP521 } from '@noble/curves/nist.js'; +import { x448, ed448 } from '@noble/curves/ed448.js'; +import { secp256k1 } from '@noble/curves/secp256k1.js'; +import { brainpoolP256r1, brainpoolP384r1, brainpoolP512r1 } from '@noble/curves/misc.js'; export const nobleCurves = new Map(Object.entries({ nistP256, diff --git a/test/crypto/brainpool_rfc7027.js b/test/crypto/brainpool_rfc7027.js deleted file mode 100644 index b28ff9cb..00000000 --- a/test/crypto/brainpool_rfc7027.js +++ /dev/null @@ -1,83 +0,0 @@ -import { expect } from 'chai'; - -import { brainpoolP256r1 } from '../../src/crypto/public_key/elliptic/brainpool/brainpoolP256r1'; -import { brainpoolP384r1 } from '../../src/crypto/public_key/elliptic/brainpool/brainpoolP384r1'; -import { brainpoolP512r1 } from '../../src/crypto/public_key/elliptic/brainpool/brainpoolP512r1'; -import util from '../../src/util'; - -const rfc7027 = [ - { - 'curve': 'brainpoolP256r1', - 'dA': '81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D', - 'QAx': '44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE5', - 'QAy': '8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC', - 'dB': '55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D76BD3', - 'QBx': '8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B', - 'QBy': '990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A', - 'Zx': '89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B', - 'Zy': '49C27868F4ECA2179BFD7D59B1E3BF34C1DBDE61AE12931648F43E59632504DE' - }, - { - 'curve': 'brainpoolP384r1', - 'dA': '1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042', - 'QAx': '68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF068', - 'QAy': '55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59', - 'dB': '032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F74E01F8BA5E0324309DB6A9831497ABAC96670', - 'QBx': '4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4', - 'QBy': '62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48', - 'Zx': '0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42', - 'Zy': '0DF213417EBE4D8E40A5F76F66C56470C489A3478D146DECF6DF0D94BAE9E598157290F8756066975F1DB34B2324B7BD' - }, - { - 'curve': 'brainpoolP512r1', - 'dA': '16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422', - 'QAx': '0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD', - 'QAy': '72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7', - 'dB': '230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429', - 'QBx': '9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F', - 'QBy': '2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA', - 'Zx': 'A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F', - 'Zy': '7DB71C3DEF63212841C463E881BDCF055523BD368240E6C3143BD8DEF8B3B3223B95E0F53082FF5E412F4222537A43DF1C6D25729DDB51620A832BE6A26680A2' - } -]; - -const hexToBigint = hex => BigInt(`0x${hex}`); - -// prettier-ignore -const BRAINPOOL = { - brainpoolP256r1, - brainpoolP384r1, - brainpoolP512r1 -}; - -export default () => describe('Brainpool curves (RFC7027)', () => { - it('Field orders', () => { - const vectors = { - brainpoolP256r1: BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377'), - brainpoolP384r1: BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53'), - brainpoolP512r1: BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3') - }; - for (const n of Object.keys(vectors)) { expect(BRAINPOOL[n].CURVE.Fp.ORDER).to.deep.equal(vectors[n]); } - }); - - for (const v of rfc7027) { - it(v.curve, () => { - const curve = BRAINPOOL[v.curve]; - const secKeyA = util.hexToUint8Array(v.dA); - const pubKeyA = curve.getPublicKey(secKeyA); - const pubPointA = curve.ProjectivePoint.fromHex(pubKeyA); - expect(pubPointA.x).to.equal(hexToBigint(v.QAx)); - expect(pubPointA.y).to.equal(hexToBigint(v.QAy)); - const secKeyB = hexToBigint(v.dB); - const pubKeyB = curve.getPublicKey(secKeyB); - const pubPointB = curve.ProjectivePoint.fromHex(pubKeyB); - expect(pubPointB.x).to.equal(hexToBigint(v.QBx)); - expect(pubPointB.y).to.equal(hexToBigint(v.QBy)); - const shared = curve.getSharedSecret(secKeyA, pubKeyB); - const sharedPoint = curve.ProjectivePoint.fromHex(shared); - expect(sharedPoint.x).to.equal(hexToBigint(v.Zx)); - expect(sharedPoint.y).to.equal(hexToBigint(v.Zy)); - expect(shared).to.deep.equal(curve.getSharedSecret(secKeyB, pubKeyA)); - }); - } -}); diff --git a/test/crypto/index.js b/test/crypto/index.js index 5e7567ff..b222b964 100644 --- a/test/crypto/index.js +++ b/test/crypto/index.js @@ -3,7 +3,6 @@ import testCipher from './cipher'; import testHash from './hash'; import testCrypto from './crypto'; import testElliptic from './ecdsa_eddsa'; -import testBrainpoolRFC7027 from './brainpool_rfc7027'; import testECDH from './ecdh'; import testPKCS5 from './pkcs5'; import testAESKW from './aes_kw'; @@ -20,7 +19,6 @@ export default () => describe('Crypto', function () { testHash(); testCrypto(); testElliptic(); - testBrainpoolRFC7027(); testECDH(); testPKCS5(); testAESKW();