mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-11-24 06:25:50 +00:00
Merge 89e05c5aa9a6558d30e435351b4fc5e558a2c830 into 3d6374fc086ea03ed282f17facac7a9447632793
This commit is contained in:
commit
27024ffb19
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false # if tests for one version fail, continue with the rest
|
||||
matrix:
|
||||
node-version: [18.x, 20.x, 22.x, 24.x]
|
||||
node-version: [20.x, 22.x, 24.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
name: Node ${{ matrix.node-version }}
|
||||
|
||||
34
package-lock.json
generated
34
package-lock.json
generated
@ -10,9 +10,9 @@
|
||||
"license": "LGPL-3.0+",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.37.0",
|
||||
"@noble/ciphers": "^1.3.0",
|
||||
"@noble/curves": "^1.9.7",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
"@noble/ciphers": "^2.0.1",
|
||||
"@noble/curves": "^2.0.1",
|
||||
"@noble/hashes": "^2.0.1",
|
||||
"@openpgp/jsdoc": "^3.6.11",
|
||||
"@openpgp/seek-bzip": "^1.0.5-git",
|
||||
"@openpgp/tweetnacl": "^1.0.4-2",
|
||||
@ -56,7 +56,7 @@
|
||||
"web-streams-polyfill": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.0.0"
|
||||
"node": ">= 20.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@ -1028,42 +1028,42 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/ciphers": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz",
|
||||
"integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.0.1.tgz",
|
||||
"integrity": "sha512-xHK3XHPUW8DTAobU+G0XT+/w+JLM7/8k1UFdB5xg/zTFPnFCobhftzw8wl4Lw2aq/Rvir5pxfZV5fEazmeCJ2g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"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/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"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": "^14.21.3 || >=16"
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"license": "LGPL-3.0+",
|
||||
"homepage": "https://openpgpjs.org/",
|
||||
"engines": {
|
||||
"node": ">= 18.0.0"
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"keywords": [
|
||||
"crypto",
|
||||
@ -64,9 +64,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.37.0",
|
||||
"@noble/ciphers": "^1.3.0",
|
||||
"@noble/curves": "^1.9.7",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
"@noble/ciphers": "^2.0.1",
|
||||
"@noble/curves": "^2.0.1",
|
||||
"@noble/hashes": "^2.0.1",
|
||||
"@openpgp/jsdoc": "^3.6.11",
|
||||
"@openpgp/seek-bzip": "^1.0.5-git",
|
||||
"@openpgp/tweetnacl": "^1.0.4-2",
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
* @module crypto/aes_kw
|
||||
*/
|
||||
|
||||
import { aeskw as nobleAesKW } from '@noble/ciphers/aes';
|
||||
import { aeskw as nobleAesKW } from '@noble/ciphers/aes.js';
|
||||
import { getCipherParams } from './cipher';
|
||||
import util from '../util';
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
* @module crypto/mode/cfb
|
||||
*/
|
||||
|
||||
import { cfb as nobleAesCfb, unsafe as nobleAesHelpers } from '@noble/ciphers/aes';
|
||||
import { cfb as nobleAesCfb, unsafe as nobleAesHelpers } from '@noble/ciphers/aes.js';
|
||||
|
||||
import { transform as streamTransform } from '@openpgp/web-stream-tools';
|
||||
import util from '../../util';
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
* @module crypto/mode/eax
|
||||
*/
|
||||
|
||||
import { ctr as nobleAesCtr } from '@noble/ciphers/aes';
|
||||
import { ctr as nobleAesCtr } from '@noble/ciphers/aes.js';
|
||||
import CMAC from '../cmac';
|
||||
import util from '../../util';
|
||||
import enums from '../../enums';
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
* @module crypto/mode/gcm
|
||||
*/
|
||||
|
||||
import { gcm as nobleAesGcm } from '@noble/ciphers/aes';
|
||||
import { gcm as nobleAesGcm } from '@noble/ciphers/aes.js';
|
||||
import util from '../../util';
|
||||
import enums from '../../enums';
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
* @module crypto/mode/ocb
|
||||
*/
|
||||
|
||||
import { cbc as nobleAesCbc } from '@noble/ciphers/aes';
|
||||
import { cbc as nobleAesCbc } from '@noble/ciphers/aes.js';
|
||||
import { getCipherParams } from '../cipher';
|
||||
import util from '../../util';
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
* @module crypto/cmac
|
||||
*/
|
||||
|
||||
import { cbc as nobleAesCbc } from '@noble/ciphers/aes';
|
||||
import { cbc as nobleAesCbc } from '@noble/ciphers/aes.js';
|
||||
import util from '../util';
|
||||
|
||||
const webCrypto = util.getWebCrypto();
|
||||
|
||||
@ -1,77 +0,0 @@
|
||||
// Copied from https://github.com/paulmillr/noble-hashes/blob/main/test/misc/md5.ts
|
||||
|
||||
import { HashMD } from '@noble/hashes/_md';
|
||||
import { rotl, wrapConstructor } from '@noble/hashes/utils';
|
||||
|
||||
// Per-round constants
|
||||
const K = Array.from({ length: 64 }, (_, i) => Math.floor(2 ** 32 * Math.abs(Math.sin(i + 1))));
|
||||
// Choice: a ? b : c
|
||||
const Chi = (a: number, b: number, c: number) => (a & b) ^ (~a & c);
|
||||
// Initial state (same as sha1, but 4 u32 instead of 5)
|
||||
const IV = /* @__PURE__ */ new Uint32Array([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]);
|
||||
// Temporary buffer, not used to store anything between runs
|
||||
// Named this way for SHA1 compat
|
||||
const MD5_W = /* @__PURE__ */ new Uint32Array(16);
|
||||
class MD5 extends HashMD<MD5> {
|
||||
private A = IV[0] | 0;
|
||||
private B = IV[1] | 0;
|
||||
private C = IV[2] | 0;
|
||||
private D = IV[3] | 0;
|
||||
constructor() {
|
||||
super(64, 16, 8, true);
|
||||
}
|
||||
protected get(): [number, number, number, number] {
|
||||
const { A, B, C, D } = this;
|
||||
return [A, B, C, D];
|
||||
}
|
||||
protected set(A: number, B: number, C: number, D: number) {
|
||||
this.A = A | 0;
|
||||
this.B = B | 0;
|
||||
this.C = C | 0;
|
||||
this.D = D | 0;
|
||||
}
|
||||
protected process(view: DataView, offset: number): void {
|
||||
for (let i = 0; i < 16; i++, offset += 4) MD5_W[i] = view.getUint32(offset, true);
|
||||
// Compression function main loop, 64 rounds
|
||||
let { A, B, C, D } = this;
|
||||
for (let i = 0; i < 64; i++) {
|
||||
let F, g, s;
|
||||
if (i < 16) {
|
||||
F = Chi(B, C, D);
|
||||
g = i;
|
||||
s = [7, 12, 17, 22];
|
||||
} else if (i < 32) {
|
||||
F = Chi(D, B, C);
|
||||
g = (5 * i + 1) % 16;
|
||||
s = [5, 9, 14, 20];
|
||||
} else if (i < 48) {
|
||||
F = B ^ C ^ D;
|
||||
g = (3 * i + 5) % 16;
|
||||
s = [4, 11, 16, 23];
|
||||
} else {
|
||||
F = C ^ (B | ~D);
|
||||
g = (7 * i) % 16;
|
||||
s = [6, 10, 15, 21];
|
||||
}
|
||||
F = F + A + K[i] + MD5_W[g];
|
||||
A = D;
|
||||
D = C;
|
||||
C = B;
|
||||
B = B + rotl(F, s[i % 4]);
|
||||
}
|
||||
// Add the compressed chunk to the current hash value
|
||||
A = (A + this.A) | 0;
|
||||
B = (B + this.B) | 0;
|
||||
C = (C + this.C) | 0;
|
||||
D = (D + this.D) | 0;
|
||||
this.set(A, B, C, D);
|
||||
}
|
||||
protected roundClean() {
|
||||
MD5_W.fill(0);
|
||||
}
|
||||
destroy() {
|
||||
this.set(0, 0, 0, 0);
|
||||
this.buffer.fill(0);
|
||||
}
|
||||
}
|
||||
export const md5 = /* @__PURE__ */ wrapConstructor(() => new MD5());
|
||||
@ -4,12 +4,9 @@
|
||||
* which share a lot of code anyway.
|
||||
*/
|
||||
|
||||
import { sha1 } from '@noble/hashes/sha1';
|
||||
import { sha224, sha256 } from '@noble/hashes/sha256';
|
||||
import { sha384, sha512 } from '@noble/hashes/sha512';
|
||||
import { sha3_256, sha3_512 } from '@noble/hashes/sha3';
|
||||
import { ripemd160 } from '@noble/hashes/ripemd160';
|
||||
import { md5 } from './md5';
|
||||
import { sha224, sha256, sha384, sha512 } from '@noble/hashes/sha2.js';
|
||||
import { sha3_256, sha3_512 } from '@noble/hashes/sha3.js';
|
||||
import { md5, ripemd160, sha1 } from '@noble/hashes/legacy.js';
|
||||
|
||||
export const nobleHashes = new Map(Object.entries({
|
||||
md5,
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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));
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user