WebAssembly interface layer providing high-performance cryptographic functions for blockchain applications in the Polkadot ecosystem.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Sr25519 signature scheme implementation with keypair generation, signing, verification, and hierarchical key derivation. Sr25519 is the primary signature scheme used in the Polkadot ecosystem.
Generates an Sr25519 keypair from a 32-byte seed.
/**
* Generates Sr25519 keypair from seed
* @param seed - 32-byte seed as Uint8Array
* @returns 64-byte keypair as Uint8Array (32-byte secret key + 32-byte public key)
*/
function sr25519KeypairFromSeed(seed: Uint8Array): Uint8Array;Usage Example:
import { waitReady, sr25519KeypairFromSeed } from "@polkadot/wasm-crypto";
await waitReady();
const seed = new Uint8Array(32).fill(1); // Example seed
const keypair = sr25519KeypairFromSeed(seed);
const secretKey = keypair.slice(0, 32);
const publicKey = keypair.slice(32, 64);
console.log("Secret key length:", secretKey.length); // 32
console.log("Public key length:", publicKey.length); // 32Signs a message using Sr25519 private key.
/**
* Signs a message using Sr25519
* @param pubkey - 32-byte public key as Uint8Array
* @param secret - 32-byte secret key as Uint8Array
* @param message - Message to sign as Uint8Array
* @returns 64-byte signature as Uint8Array
*/
function sr25519Sign(pubkey: Uint8Array, secret: Uint8Array, message: Uint8Array): Uint8Array;Usage Example:
import { waitReady, sr25519KeypairFromSeed, sr25519Sign } from "@polkadot/wasm-crypto";
await waitReady();
const seed = new Uint8Array(32).fill(1);
const keypair = sr25519KeypairFromSeed(seed);
const secretKey = keypair.slice(0, 32);
const publicKey = keypair.slice(32, 64);
const message = new TextEncoder().encode("Hello, Polkadot!");
const signature = sr25519Sign(publicKey, secretKey, message);
console.log("Signature length:", signature.length); // 64Verifies an Sr25519 signature against a message and public key.
/**
* Verifies Sr25519 signature
* @param signature - 64-byte signature as Uint8Array
* @param message - Original message as Uint8Array
* @param pubkey - 32-byte public key as Uint8Array
* @returns true if signature is valid, false otherwise
*/
function sr25519Verify(signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean;Usage Example:
import {
waitReady,
sr25519KeypairFromSeed,
sr25519Sign,
sr25519Verify
} from "@polkadot/wasm-crypto";
await waitReady();
const seed = new Uint8Array(32).fill(1);
const keypair = sr25519KeypairFromSeed(seed);
const secretKey = keypair.slice(0, 32);
const publicKey = keypair.slice(32, 64);
const message = new TextEncoder().encode("Hello, Polkadot!");
const signature = sr25519Sign(publicKey, secretKey, message);
const isValid = sr25519Verify(signature, message, publicKey);
console.log("Signature is valid:", isValid); // trueDerives a new keypair using hard derivation (cannot derive public key without private key).
/**
* Derives Sr25519 keypair using hard derivation
* @param pair - 64-byte parent keypair as Uint8Array
* @param cc - 32-byte chain code as Uint8Array
* @returns 64-byte derived keypair as Uint8Array
*/
function sr25519DeriveKeypairHard(pair: Uint8Array, cc: Uint8Array): Uint8Array;Usage Example:
import {
waitReady,
sr25519KeypairFromSeed,
sr25519DeriveKeypairHard
} from "@polkadot/wasm-crypto";
await waitReady();
const seed = new Uint8Array(32).fill(1);
const parentKeypair = sr25519KeypairFromSeed(seed);
const chainCode = new Uint8Array(32).fill(2);
const derivedKeypair = sr25519DeriveKeypairHard(parentKeypair, chainCode);
const derivedPublicKey = derivedKeypair.slice(32, 64);
console.log("Derived public key:", derivedPublicKey);Derives a new keypair using soft derivation (can derive public key without private key).
/**
* Derives Sr25519 keypair using soft derivation
* @param pair - 64-byte parent keypair as Uint8Array
* @param cc - 32-byte chain code as Uint8Array
* @returns 64-byte derived keypair as Uint8Array
*/
function sr25519DeriveKeypairSoft(pair: Uint8Array, cc: Uint8Array): Uint8Array;Derives a public key using soft derivation from just the parent public key.
/**
* Derives Sr25519 public key using soft derivation
* @param pubkey - 32-byte parent public key as Uint8Array
* @param cc - 32-byte chain code as Uint8Array
* @returns 32-byte derived public key as Uint8Array
*/
function sr25519DerivePublicSoft(pubkey: Uint8Array, cc: Uint8Array): Uint8Array;Usage Example:
import {
waitReady,
sr25519KeypairFromSeed,
sr25519DeriveKeypairSoft,
sr25519DerivePublicSoft
} from "@polkadot/wasm-crypto";
await waitReady();
const seed = new Uint8Array(32).fill(1);
const parentKeypair = sr25519KeypairFromSeed(seed);
const parentPublicKey = parentKeypair.slice(32, 64);
const chainCode = new Uint8Array(32).fill(2);
// Derive keypair (requires full parent keypair)
const derivedKeypair = sr25519DeriveKeypairSoft(parentKeypair, chainCode);
// Derive just public key (only needs parent public key)
const derivedPublicKey = sr25519DerivePublicSoft(parentPublicKey, chainCode);
console.log("Keys match:",
Array.from(derivedKeypair.slice(32, 64)).join(',') ===
Array.from(derivedPublicKey).join(',')
); // truePerforms Diffie-Hellman key agreement to generate a shared secret.
/**
* Performs Sr25519 Diffie-Hellman key agreement
* @param pubkey - 32-byte other party's public key as Uint8Array
* @param secret - 32-byte own secret key as Uint8Array
* @returns 32-byte shared secret as Uint8Array
*/
function sr25519Agree(pubkey: Uint8Array, secret: Uint8Array): Uint8Array;Usage Example:
import {
waitReady,
sr25519KeypairFromSeed,
sr25519Agree
} from "@polkadot/wasm-crypto";
await waitReady();
// Alice's keypair
const aliceSeed = new Uint8Array(32).fill(1);
const aliceKeypair = sr25519KeypairFromSeed(aliceSeed);
const aliceSecret = aliceKeypair.slice(0, 32);
const alicePublic = aliceKeypair.slice(32, 64);
// Bob's keypair
const bobSeed = new Uint8Array(32).fill(2);
const bobKeypair = sr25519KeypairFromSeed(bobSeed);
const bobSecret = bobKeypair.slice(0, 32);
const bobPublic = bobKeypair.slice(32, 64);
// Generate shared secrets
const aliceShared = sr25519Agree(bobPublic, aliceSecret);
const bobShared = sr25519Agree(alicePublic, bobSecret);
// Shared secrets should be identical
console.log("Shared secrets match:",
Array.from(aliceShared).join(',') === Array.from(bobShared).join(',')
); // trueimport {
waitReady,
sr25519KeypairFromSeed,
sr25519Sign,
sr25519Verify,
sr25519DeriveKeypairSoft
} from "@polkadot/wasm-crypto";
async function demonstrateSr25519() {
await waitReady();
// Generate master keypair
const seed = new Uint8Array(32).fill(1);
const masterKeypair = sr25519KeypairFromSeed(seed);
const masterSecret = masterKeypair.slice(0, 32);
const masterPublic = masterKeypair.slice(32, 64);
// Derive child keypair
const chainCode = new Uint8Array(32).fill(2);
const childKeypair = sr25519DeriveKeypairSoft(masterKeypair, chainCode);
const childSecret = childKeypair.slice(0, 32);
const childPublic = childKeypair.slice(32, 64);
// Sign and verify with child key
const message = new TextEncoder().encode("Child key signature");
const signature = sr25519Sign(childPublic, childSecret, message);
const isValid = sr25519Verify(signature, message, childPublic);
console.log("Child signature valid:", isValid);
return { masterKeypair, childKeypair, signature };
}
demonstrateSr25519();Install with Tessl CLI
npx tessl i tessl/npm-polkadot--wasm-crypto