Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/util-crypto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@polkadot/x-bigint": "13.5.7",
"@polkadot/x-randomvalues": "13.5.7",
"@scure/base": "^1.1.7",
"@scure/sr25519": "^0.2.0",
"tslib": "^2.8.0"
},
"peerDependencies": {
Expand Down
5 changes: 1 addition & 4 deletions packages/util-crypto/src/sr25519/agreement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@
import type { Keypair } from '../types.js';

import { u8aToHex } from '@polkadot/util';
import { waitReady } from '@polkadot/wasm-crypto';

import { sr25519Agreement, sr25519PairFromSeed } from './index.js';

describe('agreement', (): void => {
let pairA: Keypair;
let pairB: Keypair;

beforeEach(async (): Promise<void> => {
await waitReady();

beforeEach((): void => {
pairA = sr25519PairFromSeed('0x98b3d305d5a5eace562387e47e59badd4d77e3f72cabfb10a60f8a197059f0a8');
pairB = sr25519PairFromSeed('0x9732eea001851ff862d949a1699c9971f3a26edbede2ad7922cbbe9a0701f366');
});
Expand Down
5 changes: 3 additions & 2 deletions packages/util-crypto/src/sr25519/agreement.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { getSharedSecret } from '@scure/sr25519';

import { u8aToU8a } from '@polkadot/util';
import { sr25519Agree } from '@polkadot/wasm-crypto';

/**
* @name sr25519Agreement
Expand All @@ -18,5 +19,5 @@ export function sr25519Agreement (secretKey: string | Uint8Array, publicKey: str
throw new Error(`Invalid secretKey, received ${secretKeyU8a.length} bytes, expected 64`);
}

return sr25519Agree(publicKeyU8a, secretKeyU8a);
return getSharedSecret(secretKeyU8a, publicKeyU8a);
}
12 changes: 6 additions & 6 deletions packages/util-crypto/src/sr25519/derive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@

import type { Keypair } from '../types.js';

import { isU8a } from '@polkadot/util';
import * as sr25519 from '@scure/sr25519';

import { sr25519PairFromU8a } from './pair/fromU8a.js';
import { sr25519KeypairToU8a } from './pair/toU8a.js';
import { isU8a } from '@polkadot/util';

export function createDeriveFn (derive: (pair: Uint8Array, cc: Uint8Array) => Uint8Array): (keypair: Keypair, chainCode: Uint8Array) => Keypair {
return (keypair: Keypair, chainCode: Uint8Array): Keypair => {
if (!isU8a(chainCode) || chainCode.length !== 32) {
throw new Error('Invalid chainCode passed to derive');
}

return sr25519PairFromU8a(
derive(sr25519KeypairToU8a(keypair), chainCode)
);
const secretKey = derive(keypair.secretKey, chainCode);
const publicKey = sr25519.getPublicKey(secretKey);

return { publicKey, secretKey };
};
}
5 changes: 3 additions & 2 deletions packages/util-crypto/src/sr25519/deriveHard.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { sr25519DeriveKeypairHard } from '@polkadot/wasm-crypto';
import * as sr25519 from '@scure/sr25519';

import { createDeriveFn } from './derive.js';

export const sr25519DeriveHard = /*#__PURE__*/ createDeriveFn(sr25519DeriveKeypairHard);
// eslint-disable-next-line @typescript-eslint/unbound-method
export const sr25519DeriveHard = /*#__PURE__*/ createDeriveFn(sr25519.HDKD.secretHard);
5 changes: 3 additions & 2 deletions packages/util-crypto/src/sr25519/derivePublic.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

import * as sr25519 from '@scure/sr25519';

import { isU8a, u8aToU8a } from '@polkadot/util';
import { sr25519DerivePublicSoft } from '@polkadot/wasm-crypto';

export function sr25519DerivePublic (publicKey: string | Uint8Array, chainCode: Uint8Array): Uint8Array {
const publicKeyU8a = u8aToU8a(publicKey);
Expand All @@ -13,5 +14,5 @@ export function sr25519DerivePublic (publicKey: string | Uint8Array, chainCode:
throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`);
}

return sr25519DerivePublicSoft(publicKeyU8a, chainCode);
return sr25519.HDKD.publicSoft(publicKeyU8a, chainCode);
}
5 changes: 3 additions & 2 deletions packages/util-crypto/src/sr25519/deriveSoft.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { sr25519DeriveKeypairSoft } from '@polkadot/wasm-crypto';
import * as sr25519 from '@scure/sr25519';

import { createDeriveFn } from './derive.js';

export const sr25519DeriveSoft = /*#__PURE__*/ createDeriveFn(sr25519DeriveKeypairSoft);
// eslint-disable-next-line @typescript-eslint/unbound-method
export const sr25519DeriveSoft = /*#__PURE__*/ createDeriveFn(sr25519.HDKD.secretSoft);
5 changes: 0 additions & 5 deletions packages/util-crypto/src/sr25519/pair/fromSeed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
/// <reference types="@polkadot/dev-test/globals.d.ts" />

import { stringToU8a, u8aToHex } from '@polkadot/util';
import { waitReady } from '@polkadot/wasm-crypto';

import { mnemonicToMiniSecret } from '../../mnemonic/index.js';
import { sr25519PairFromSeed } from '../index.js';
Expand All @@ -17,10 +16,6 @@ describe('sr25519PairFromSeed', (): void => {
secretKey: new Uint8Array([240, 16, 102, 96, 195, 221, 162, 63, 22, 218, 169, 172, 91, 129, 27, 150, 48, 119, 245, 188, 10, 248, 159, 133, 128, 79, 13, 232, 228, 36, 240, 80, 249, 141, 102, 243, 148, 66, 80, 111, 249, 71, 253, 145, 31, 24, 199, 167, 165, 218, 99, 154, 99, 232, 211, 180, 226, 51, 247, 65, 67, 217, 81, 193])
};

beforeEach(async (): Promise<void> => {
await waitReady();
});

it('generates a valid publicKey/secretKey pair (u8a)', (): void => {
expect(
sr25519PairFromSeed(TEST)
Expand Down
15 changes: 9 additions & 6 deletions packages/util-crypto/src/sr25519/pair/fromSeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@

import type { Keypair } from '../../types.js';

import { u8aToU8a } from '@polkadot/util';
import { sr25519KeypairFromSeed } from '@polkadot/wasm-crypto';
import * as sr25519 from '@scure/sr25519';

import { sr25519PairFromU8a } from './fromU8a.js';
import { u8aToU8a } from '@polkadot/util';

/**
* @name sr25519PairFromSeed
Expand All @@ -19,7 +18,11 @@ export function sr25519PairFromSeed (seed: string | Uint8Array): Keypair {
throw new Error(`Expected a seed matching 32 bytes, found ${seedU8a.length}`);
}

return sr25519PairFromU8a(
sr25519KeypairFromSeed(seedU8a)
);
const sec = sr25519.secretFromSeed(seedU8a);
const pub = sr25519.getPublicKey(sec);

return {
publicKey: pub,
secretKey: sec
};
}
5 changes: 0 additions & 5 deletions packages/util-crypto/src/sr25519/sign.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
/// <reference types="@polkadot/dev-test/globals.d.ts" />

import { stringToU8a } from '@polkadot/util';
import { waitReady } from '@polkadot/wasm-crypto';

import { randomAsU8a } from '../random/asU8a.js';
import { sr25519PairFromSeed } from './pair/fromSeed.js';
Expand All @@ -13,10 +12,6 @@ import { sr25519Sign } from './sign.js';
const MESSAGE = stringToU8a('this is a message');

describe('sign', (): void => {
beforeEach(async (): Promise<void> => {
await waitReady();
});

it('has 64-byte signatures', (): void => {
const pair = sr25519PairFromSeed(randomAsU8a());

Expand Down
5 changes: 3 additions & 2 deletions packages/util-crypto/src/sr25519/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

import type { Keypair } from '../types.js';

import * as sr25519 from '@scure/sr25519';

import { u8aToU8a } from '@polkadot/util';
import { sr25519Sign as wasmSign } from '@polkadot/wasm-crypto';

/**
* @name sr25519Sign
Expand All @@ -17,5 +18,5 @@ export function sr25519Sign (message: string | Uint8Array, { publicKey, secretKe
throw new Error('Expected a valid secretKey, 64-bytes');
}

return wasmSign(publicKey, secretKey, u8aToU8a(message));
return sr25519.sign(secretKey, u8aToU8a(message));
}
5 changes: 0 additions & 5 deletions packages/util-crypto/src/sr25519/verify.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
/// <reference types="@polkadot/dev-test/globals.d.ts" />

import { stringToU8a } from '@polkadot/util';
import { waitReady } from '@polkadot/wasm-crypto';

import { randomAsU8a } from '../random/asU8a.js';
import { sr25519PairFromSeed } from './pair/fromSeed.js';
Expand All @@ -14,10 +13,6 @@ import { sr25519Verify } from './verify.js';
const MESSAGE = stringToU8a('this is a message');

describe('verify', (): void => {
beforeEach(async (): Promise<void> => {
await waitReady();
});

it('can sign and verify a message', (): void => {
const pair = sr25519PairFromSeed(randomAsU8a());
const signature = sr25519Sign(MESSAGE, pair);
Expand Down
5 changes: 3 additions & 2 deletions packages/util-crypto/src/sr25519/verify.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

import * as sr25519 from '@scure/sr25519';

import { u8aToU8a } from '@polkadot/util';
import { sr25519Verify as wasmVerify } from '@polkadot/wasm-crypto';

/**
* @name sr25519Verify
Expand All @@ -18,5 +19,5 @@ export function sr25519Verify (message: string | Uint8Array, signature: string |
throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`);
}

return wasmVerify(signatureU8a, u8aToU8a(message), publicKeyU8a);
return sr25519.verify(u8aToU8a(message), signatureU8a, publicKeyU8a);
}
7 changes: 5 additions & 2 deletions packages/util-crypto/src/sr25519/vrfSign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

import type { Keypair } from '../types.js';

import { randomBytes } from '@noble/hashes/utils';
import * as sr25519 from '@scure/sr25519';

import { u8aToU8a } from '@polkadot/util';
import { vrfSign } from '@polkadot/wasm-crypto';

const EMPTY_U8A = new Uint8Array();

Expand All @@ -17,5 +19,6 @@ export function sr25519VrfSign (message: string | Uint8Array, { secretKey }: Par
throw new Error('Invalid secretKey, expected 64-bytes');
}

return vrfSign(secretKey, u8aToU8a(context), u8aToU8a(message), u8aToU8a(extra));
return sr25519.vrf.sign(u8aToU8a(message), secretKey, u8aToU8a(context), u8aToU8a(extra), randomBytes);
// return vrfSign(secretKey, u8aToU8a(context), u8aToU8a(message), u8aToU8a(extra));
}
5 changes: 0 additions & 5 deletions packages/util-crypto/src/sr25519/vrfSignVerify.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
/// <reference types="@polkadot/dev-test/globals.d.ts" />

import { stringToU8a, u8aEq } from '@polkadot/util';
import { waitReady } from '@polkadot/wasm-crypto';

import { randomAsU8a } from '../random/asU8a.js';
import { sr25519PairFromSeed } from './pair/fromSeed.js';
Expand All @@ -14,10 +13,6 @@ import { sr25519VrfVerify } from './vrfVerify.js';
const MESSAGE = stringToU8a('this is a message');

describe('vrf sign and verify', (): void => {
beforeEach(async (): Promise<void> => {
await waitReady();
});

it('has 96-byte proofs', (): void => {
const pair = sr25519PairFromSeed(randomAsU8a());

Expand Down
5 changes: 3 additions & 2 deletions packages/util-crypto/src/sr25519/vrfVerify.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

import * as sr25519 from '@scure/sr25519';

import { u8aToU8a } from '@polkadot/util';
import { vrfVerify } from '@polkadot/wasm-crypto';

const EMPTY_U8A = new Uint8Array();

Expand All @@ -20,5 +21,5 @@ export function sr25519VrfVerify (message: string | Uint8Array, signOutput: stri
throw new Error('Invalid vrfSign output, expected 96 bytes');
}

return vrfVerify(publicKeyU8a, u8aToU8a(context), u8aToU8a(message), u8aToU8a(extra), proofU8a);
return sr25519.vrf.verify(u8aToU8a(message), proofU8a, publicKeyU8a, u8aToU8a(context), u8aToU8a(extra));
}
27 changes: 27 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1313,13 +1313,29 @@ __metadata:
languageName: node
linkType: hard

"@noble/curves@npm:~1.9.2":
version: 1.9.7
resolution: "@noble/curves@npm:1.9.7"
dependencies:
"@noble/hashes": "npm:1.8.0"
checksum: 10/3cfe2735ea94972988ca9e217e0ebb2044372a7160b2079bf885da789492a6291fc8bf76ca3d8bf8dee477847ee2d6fac267d1e6c4f555054059f5e8c4865d44
languageName: node
linkType: hard

"@noble/hashes@npm:1.3.3, @noble/hashes@npm:^1.3.3":
version: 1.3.3
resolution: "@noble/hashes@npm:1.3.3"
checksum: 10/1025ddde4d24630e95c0818e63d2d54ee131b980fe113312d17ed7468bc18f54486ac86c907685759f8a7e13c2f9b9e83ec7b67d1cc20836f36b5e4a65bb102d
languageName: node
linkType: hard

"@noble/hashes@npm:1.8.0, @noble/hashes@npm:~1.8.0":
version: 1.8.0
resolution: "@noble/hashes@npm:1.8.0"
checksum: 10/474b7f56bc6fb2d5b3a42132561e221b0ea4f91e590f4655312ca13667840896b34195e2b53b7f097ec080a1fdd3b58d902c2a8d0fbdf51d2e238b53808a177e
languageName: node
linkType: hard

"@nodelib/fs.scandir@npm:2.1.5":
version: 2.1.5
resolution: "@nodelib/fs.scandir@npm:2.1.5"
Expand Down Expand Up @@ -1638,6 +1654,7 @@ __metadata:
"@polkadot/x-bigint": "npm:13.5.7"
"@polkadot/x-randomvalues": "npm:13.5.7"
"@scure/base": "npm:^1.1.7"
"@scure/sr25519": "npm:^0.2.0"
tslib: "npm:^2.8.0"
peerDependencies:
"@polkadot/util": 13.5.7
Expand Down Expand Up @@ -2386,6 +2403,16 @@ __metadata:
languageName: node
linkType: hard

"@scure/sr25519@npm:^0.2.0":
version: 0.2.0
resolution: "@scure/sr25519@npm:0.2.0"
dependencies:
"@noble/curves": "npm:~1.9.2"
"@noble/hashes": "npm:~1.8.0"
checksum: 10/3c47b474811642b43fd8c96f7846c9d88c9a06eefa7d6360b6421ebdfb6cf582e1e8fdce9ae4708b088a0e323cd6519c883c3a33a284c2fad592414b02f19049
languageName: node
linkType: hard

"@sideway/address@npm:^4.1.4":
version: 4.1.4
resolution: "@sideway/address@npm:4.1.4"
Expand Down