Skip to content

Commit

Permalink
Replace @noble/ed25519 and @noble/secp256k1 with @noble/curves (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Mrtenz authored Oct 9, 2023
1 parent f2b0ecf commit 9619c3e
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 71 deletions.
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,10 @@
"test:watch": "jest --watch"
},
"dependencies": {
"@metamask/scure-bip39": "^2.1.0",
"@metamask/scure-bip39": "^2.1.1",
"@metamask/utils": "^8.1.0",
"@noble/ed25519": "^1.6.0",
"@noble/hashes": "^1.0.0",
"@noble/secp256k1": "^1.5.5",
"@noble/curves": "^1.2.0",
"@noble/hashes": "^1.3.2",
"@scure/base": "^1.0.0"
},
"devDependencies": {
Expand Down
5 changes: 1 addition & 4 deletions src/curves/curve.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { utils } from '@noble/secp256k1';

import * as ed25519 from './ed25519';
import * as secp256k1 from './secp256k1';

Expand Down Expand Up @@ -38,5 +36,4 @@ export function getCurveByName(curveName: SupportedCurve): Curve {
return curves[curveName];
}

// As long as both parameters are specified, this function is the same for all curves.
export const { mod } = utils;
export { mod } from '@noble/curves/abstract/modular';
8 changes: 4 additions & 4 deletions src/curves/ed25519.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ describe('ed25519', () => {
'returns the 0-padded public key for a private key',
async ({ keys }) => {
for (const { privateKey, publicKey } of keys) {
expect(bytesToHex(await getPublicKey(hexToBytes(privateKey)))).toBe(
expect(bytesToHex(getPublicKey(hexToBytes(privateKey)))).toBe(
publicKey,
);

expect(
bytesToHex(await getPublicKey(hexToBytes(privateKey), true)),
).toBe(publicKey);
expect(bytesToHex(getPublicKey(hexToBytes(privateKey), true))).toBe(
publicKey,
);
}
},
);
Expand Down
11 changes: 5 additions & 6 deletions src/curves/ed25519.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { concatBytes, stringToBytes } from '@metamask/utils';
import { getPublicKey as getEd25519PublicKey } from '@noble/ed25519';

export { CURVE as curve } from '@noble/ed25519';
import { ed25519 } from '@noble/curves/ed25519';

export const curve = ed25519.CURVE;
export const name = 'ed25519';

// Secret is defined in SLIP-10:
Expand All @@ -18,11 +17,11 @@ export const deriveUnhardenedKeys = false;

export const publicKeyLength = 33;

export const getPublicKey = async (
export const getPublicKey = (
privateKey: Uint8Array,
_compressed?: boolean,
): Promise<Uint8Array> => {
const publicKey = await getEd25519PublicKey(privateKey);
): Uint8Array => {
const publicKey = ed25519.getPublicKey(privateKey);
return concatBytes([new Uint8Array([0]), publicKey]);
};

Expand Down
23 changes: 9 additions & 14 deletions src/curves/secp256k1.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { assert, stringToBytes } from '@metamask/utils';
import {
getPublicKey as getSecp256k1PublicKey,
Point,
utils,
} from '@noble/secp256k1';
import { secp256k1 } from '@noble/curves/secp256k1';

import { isValidBytesKey } from '../utils';

export { CURVE as curve } from '@noble/secp256k1';

export const curve = secp256k1.CURVE;
export const name = 'secp256k1';

// Secret is defined in BIP-32 and SLIP-10:
Expand All @@ -21,13 +16,13 @@ export const deriveUnhardenedKeys = true;
export const publicKeyLength = 65;

export const isValidPrivateKey = (privateKey: Uint8Array) => {
return utils.isValidPrivateKey(privateKey);
return secp256k1.utils.isValidPrivateKey(privateKey);
};

export const getPublicKey = (
privateKey: Uint8Array,
compressed?: boolean,
): Uint8Array => getSecp256k1PublicKey(privateKey, compressed);
compressed = false,
): Uint8Array => secp256k1.getPublicKey(privateKey, compressed);

export const publicAdd = (
publicKey: Uint8Array,
Expand All @@ -38,25 +33,25 @@ export const publicAdd = (
'Invalid tweak: Tweak must be a non-zero 32-byte Uint8Array.',
);

const point = Point.fromHex(publicKey);
const point = secp256k1.ProjectivePoint.fromHex(publicKey);

// The returned child key Ki is point(parse256(IL)) + Kpar.
// This multiplies the tweak with the base point of the curve (Gx, Gy).
// https://github.com/bitcoin/bips/blob/274fa400d630ba757bec0c03b35ebe2345197108/bip-0032.mediawiki#public-parent-key--public-child-key
const newPoint = point.add(Point.fromPrivateKey(tweak));
const newPoint = point.add(secp256k1.ProjectivePoint.fromPrivateKey(tweak));
newPoint.assertValidity();

return newPoint.toRawBytes(false);
};

export const compressPublicKey = (publicKey: Uint8Array): Uint8Array => {
const point = Point.fromHex(publicKey);
const point = secp256k1.ProjectivePoint.fromHex(publicKey);
return point.toRawBytes(true);
};

export const decompressPublicKey = (publicKey: Uint8Array): Uint8Array => {
// This calculates a point on the elliptic curve from a compressed public key. We can then use
// this to get the uncompressed version of the public key.
const point = Point.fromHex(publicKey);
const point = secp256k1.ProjectivePoint.fromHex(publicKey);
return point.toRawBytes(false);
};
4 changes: 2 additions & 2 deletions src/derivers/shared.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { hexToBytes } from '@metamask/utils';
import { CURVE } from '@noble/secp256k1';

import fixtures from '../../test/fixtures';
import { secp256k1 } from '../curves';
import { curve } from '../curves/secp256k1';
import { hexStringToBytes } from '../utils';
import { privateAdd } from './shared';

Expand All @@ -27,7 +27,7 @@ describe('privateAdd', () => {
);

it('throws if the tweak is larger than the curve order', () => {
const tweak = hexStringToBytes(CURVE.n.toString(16));
const tweak = hexStringToBytes(curve.n.toString(16));

expect(() => privateAdd(PRIVATE_KEY, tweak, secp256k1)).toThrow(
'Invalid tweak: Tweak is larger than the curve order.',
Expand Down
4 changes: 3 additions & 1 deletion src/derivers/slip10.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ describe('deriveChildKey', () => {

// This should never be the case.
const error = new Error('Unable to derive child key.');
jest.spyOn(ed25519, 'getPublicKey').mockRejectedValueOnce(error);
jest.spyOn(ed25519, 'getPublicKey').mockImplementationOnce(() => {
throw error;
});

await expect(
deriveChildKey({
Expand Down
59 changes: 23 additions & 36 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1055,11 +1055,10 @@ __metadata:
"@metamask/eslint-config-jest": ^12.0.0
"@metamask/eslint-config-nodejs": ^12.0.0
"@metamask/eslint-config-typescript": ^12.0.0
"@metamask/scure-bip39": ^2.1.0
"@metamask/scure-bip39": ^2.1.1
"@metamask/utils": ^8.1.0
"@noble/ed25519": ^1.6.0
"@noble/hashes": ^1.0.0
"@noble/secp256k1": ^1.5.5
"@noble/curves": ^1.2.0
"@noble/hashes": ^1.3.2
"@scure/base": ^1.0.0
"@swc/cli": ^0.1.62
"@swc/core": ^1.3.66
Expand Down Expand Up @@ -1088,13 +1087,13 @@ __metadata:
languageName: unknown
linkType: soft

"@metamask/scure-bip39@npm:^2.1.0":
version: 2.1.0
resolution: "@metamask/scure-bip39@npm:2.1.0"
"@metamask/scure-bip39@npm:^2.1.1":
version: 2.1.1
resolution: "@metamask/scure-bip39@npm:2.1.1"
dependencies:
"@noble/hashes": ~1.1.1
"@scure/base": ~1.1.0
checksum: 13e07f03077472e9b230f702cbba7848ecac752028396647ccdeedd7bc280ceb50ee15203e25603f05c4c6ca5d4dc7277825f7004beb113e1a415adc91f059f9
"@noble/hashes": ~1.3.2
"@scure/base": ~1.1.3
checksum: d03b4d0b3dba0e5c2014038b746ec86cc9c4420b4c6b9a224e3b4ebdb266b9170c968a3ad9693c6f5d1e76ce3c198479e9398bd30f1dc0f0920d7e9401612365
languageName: node
linkType: hard

Expand Down Expand Up @@ -1146,10 +1145,12 @@ __metadata:
languageName: node
linkType: hard

"@noble/ed25519@npm:^1.6.0":
version: 1.7.0
resolution: "@noble/ed25519@npm:1.7.0"
checksum: 9a2cd37885c46d6fec2d5b08f59601894314e8cb984a1b69c616ed079d9b96ebc288706b3fcfb16a6bb175667c15c7ef80042c7d3b5a173d44dc051101364415
"@noble/curves@npm:^1.2.0":
version: 1.2.0
resolution: "@noble/curves@npm:1.2.0"
dependencies:
"@noble/hashes": 1.3.2
checksum: bb798d7a66d8e43789e93bc3c2ddff91a1e19fdb79a99b86cd98f1e5eff0ee2024a2672902c2576ef3577b6f282f3b5c778bebd55761ddbb30e36bf275e83dd0
languageName: node
linkType: hard

Expand All @@ -1160,24 +1161,10 @@ __metadata:
languageName: node
linkType: hard

"@noble/hashes@npm:^1.0.0, @noble/hashes@npm:^1.3.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:~1.3.0":
version: 1.3.1
resolution: "@noble/hashes@npm:1.3.1"
checksum: 7fdefc0f7a0c1ec27acc6ff88841793e3f93ec4ce6b8a6a12bfc0dd70ae6b7c4c82fe305fdfeda1735d5ad4a9eebe761e6693b3d355689c559e91242f4bc95b1
languageName: node
linkType: hard

"@noble/hashes@npm:~1.1.1":
version: 1.1.2
resolution: "@noble/hashes@npm:1.1.2"
checksum: 3c2a8cb7c2e053811032f242155d870c5eb98844d924d69702244d48804cb03b42d4a666c49c2b71164420d8229cb9a6f242b972d50d5bb2f1d673b98b041de2
languageName: node
linkType: hard

"@noble/secp256k1@npm:^1.5.5":
version: 1.7.1
resolution: "@noble/secp256k1@npm:1.7.1"
checksum: d2301f1f7690368d8409a3152450458f27e54df47e3f917292de3de82c298770890c2de7c967d237eff9c95b70af485389a9695f73eb05a43e2bd562d18b18cb
"@noble/hashes@npm:1.3.2, @noble/hashes@npm:^1.3.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.3.2, @noble/hashes@npm:~1.3.0, @noble/hashes@npm:~1.3.2":
version: 1.3.2
resolution: "@noble/hashes@npm:1.3.2"
checksum: fe23536b436539d13f90e4b9be843cc63b1b17666a07634a2b1259dded6f490be3d050249e6af98076ea8f2ea0d56f578773c2197f2aa0eeaa5fba5bc18ba474
languageName: node
linkType: hard

Expand Down Expand Up @@ -1287,10 +1274,10 @@ __metadata:
languageName: node
linkType: hard

"@scure/base@npm:^1.0.0, @scure/base@npm:~1.1.0":
version: 1.1.1
resolution: "@scure/base@npm:1.1.1"
checksum: b4fc810b492693e7e8d0107313ac74c3646970c198bbe26d7332820886fa4f09441991023ec9aa3a2a51246b74409ab5ebae2e8ef148bbc253da79ac49130309
"@scure/base@npm:^1.0.0, @scure/base@npm:~1.1.0, @scure/base@npm:~1.1.3":
version: 1.1.3
resolution: "@scure/base@npm:1.1.3"
checksum: 1606ab8a4db898cb3a1ada16c15437c3bce4e25854fadc8eb03ae93cbbbac1ed90655af4b0be3da37e12056fef11c0374499f69b9e658c9e5b7b3e06353c630c
languageName: node
linkType: hard

Expand Down

0 comments on commit 9619c3e

Please sign in to comment.