Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sr25519: switch from wasm to micro-sr25519 #1971

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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.3.2-0-x",
"@polkadot/x-randomvalues": "13.3.2-0-x",
"@scure/base": "^1.1.7",
"micro-sr25519": "^0.1.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 'micro-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 'micro-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: 2 additions & 3 deletions packages/util-crypto/src/sr25519/deriveHard.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { sr25519DeriveKeypairHard } from '@polkadot/wasm-crypto';

import * as sr25519 from 'micro-sr25519';

Check failure on line 4 in packages/util-crypto/src/sr25519/deriveHard.ts

View workflow job for this annotation

GitHub Actions / pr (lint)

Run autofix to sort these imports!
import { createDeriveFn } from './derive.js';

export const sr25519DeriveHard = /*#__PURE__*/ createDeriveFn(sr25519DeriveKeypairHard);
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 'micro-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);
}
4 changes: 2 additions & 2 deletions packages/util-crypto/src/sr25519/deriveSoft.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

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

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

export const sr25519DeriveSoft = /*#__PURE__*/ createDeriveFn(sr25519DeriveKeypairSoft);
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 'micro-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 'micro-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 'micro-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);
}
6 changes: 4 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,9 @@

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

import * as sr25519 from 'micro-sr25519';

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

const EMPTY_U8A = new Uint8Array();

Expand All @@ -17,5 +18,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));
// 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 'micro-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));
}
Loading
Loading