CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-polkadot--wasm-crypto

WebAssembly interface layer providing high-performance cryptographic functions for blockchain applications in the Polkadot ecosystem.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

secp256k1.mddocs/

Secp256k1 ECDSA Operations

Secp256k1 elliptic curve cryptography functions including key generation, signing, signature recovery, and public key compression/expansion operations. This is the same curve used by Bitcoin and Ethereum.

Capabilities

Generate Keypair from Seed

Generates a secp256k1 keypair from a secret key seed.

/**
 * Generates secp256k1 keypair from secret key
 * @param seckey - 32-byte secret key as Uint8Array
 * @returns 64-byte uncompressed public key as Uint8Array
 */
function secp256k1FromSeed(seckey: Uint8Array): Uint8Array;

Usage Example:

import { waitReady, secp256k1FromSeed } from "@polkadot/wasm-crypto";

await waitReady();

const secretKey = new Uint8Array(32).fill(1); // Example secret key
const publicKey = secp256k1FromSeed(secretKey);

console.log("Secret key length:", secretKey.length); // 32
console.log("Public key length:", publicKey.length); // 64 (uncompressed)

Sign Message Hash

Signs a message hash using secp256k1 ECDSA.

/**
 * Signs a message hash using secp256k1 ECDSA
 * @param msgHash - 32-byte message hash as Uint8Array
 * @param seckey - 32-byte secret key as Uint8Array
 * @returns 65-byte signature as Uint8Array (64-byte signature + 1-byte recovery ID)
 */
function secp256k1Sign(msgHash: Uint8Array, seckey: Uint8Array): Uint8Array;

Usage Example:

import { waitReady, secp256k1FromSeed, secp256k1Sign, sha256 } from "@polkadot/wasm-crypto";

await waitReady();

const secretKey = new Uint8Array(32).fill(1);
const publicKey = secp256k1FromSeed(secretKey);

// Hash the message first
const message = new TextEncoder().encode("Hello, secp256k1!");
const messageHash = sha256(message);

const signature = secp256k1Sign(messageHash, secretKey);
console.log("Signature length:", signature.length); // 65

Recover Public Key from Signature

Recovers the public key from a secp256k1 signature and message hash.

/**
 * Recovers public key from secp256k1 signature
 * @param msgHash - 32-byte message hash as Uint8Array
 * @param sig - 64-byte signature as Uint8Array (without recovery ID)
 * @param recovery - Recovery ID (0, 1, 2, or 3)
 * @returns 64-byte uncompressed public key as Uint8Array
 */
function secp256k1Recover(msgHash: Uint8Array, sig: Uint8Array, recovery: number): Uint8Array;

Usage Example:

import { 
  waitReady, 
  secp256k1FromSeed, 
  secp256k1Sign, 
  secp256k1Recover,
  sha256 
} from "@polkadot/wasm-crypto";

await waitReady();

const secretKey = new Uint8Array(32).fill(1);
const originalPublicKey = secp256k1FromSeed(secretKey);

const message = new TextEncoder().encode("Hello, secp256k1!");
const messageHash = sha256(message);

const fullSignature = secp256k1Sign(messageHash, secretKey);
const signature = fullSignature.slice(0, 64); // Remove recovery ID
const recoveryId = fullSignature[64]; // Extract recovery ID

const recoveredPublicKey = secp256k1Recover(messageHash, signature, recoveryId);

// Compare original and recovered public keys
const keysMatch = Array.from(originalPublicKey).join(',') === 
                  Array.from(recoveredPublicKey).join(',');
console.log("Keys match:", keysMatch); // true

Compress Public Key

Compresses a secp256k1 public key from 64 bytes to 33 bytes.

/**
 * Compresses secp256k1 public key
 * @param pubkey - 64-byte uncompressed public key as Uint8Array
 * @returns 33-byte compressed public key as Uint8Array
 */
function secp256k1Compress(pubkey: Uint8Array): Uint8Array;

Usage Example:

import { waitReady, secp256k1FromSeed, secp256k1Compress } from "@polkadot/wasm-crypto";

await waitReady();

const secretKey = new Uint8Array(32).fill(1);
const uncompressedPublicKey = secp256k1FromSeed(secretKey);
const compressedPublicKey = secp256k1Compress(uncompressedPublicKey);

console.log("Uncompressed length:", uncompressedPublicKey.length); // 64
console.log("Compressed length:", compressedPublicKey.length); // 33

Expand Public Key

Expands a compressed secp256k1 public key from 33 bytes to 64 bytes.

/**
 * Expands compressed secp256k1 public key
 * @param pubkey - 33-byte compressed public key as Uint8Array
 * @returns 64-byte uncompressed public key as Uint8Array
 */
function secp256k1Expand(pubkey: Uint8Array): Uint8Array;

Usage Example:

import { 
  waitReady, 
  secp256k1FromSeed, 
  secp256k1Compress, 
  secp256k1Expand 
} from "@polkadot/wasm-crypto";

await waitReady();

const secretKey = new Uint8Array(32).fill(1);
const originalPublicKey = secp256k1FromSeed(secretKey);

// Compress then expand
const compressedPublicKey = secp256k1Compress(originalPublicKey);
const expandedPublicKey = secp256k1Expand(compressedPublicKey);

// Keys should match after compression/expansion cycle
const keysMatch = Array.from(originalPublicKey).join(',') === 
                  Array.from(expandedPublicKey).join(',');
console.log("Compression/expansion cycle preserves key:", keysMatch); // true

Complete Secp256k1 Workflow

import { 
  waitReady, 
  secp256k1FromSeed, 
  secp256k1Sign, 
  secp256k1Recover,
  secp256k1Compress,
  secp256k1Expand,
  sha256 
} from "@polkadot/wasm-crypto";

async function demonstrateSecp256k1() {
  await waitReady();
  
  // Generate keypair
  const secretKey = new Uint8Array(32);
  crypto.getRandomValues(secretKey); // Use random secret in production
  
  const publicKey = secp256k1FromSeed(secretKey);
  
  // Test compression/expansion
  const compressedPubKey = secp256k1Compress(publicKey);
  const expandedPubKey = secp256k1Expand(compressedPubKey);
  
  console.log("Compression/expansion works:", 
    Array.from(publicKey).join(',') === Array.from(expandedPubKey).join(',')
  );
  
  // Sign and recover
  const message = new TextEncoder().encode("Test message for secp256k1");
  const messageHash = sha256(message);
  
  const fullSignature = secp256k1Sign(messageHash, secretKey);
  const signature = fullSignature.slice(0, 64);
  const recoveryId = fullSignature[64];
  
  const recoveredPubKey = secp256k1Recover(messageHash, signature, recoveryId);
  
  console.log("Key recovery works:", 
    Array.from(publicKey).join(',') === Array.from(recoveredPubKey).join(',')
  );
  
  return {
    secretKey,
    publicKey,
    compressedPubKey,
    signature,
    recoveredPubKey
  };
}

demonstrateSecp256k1();

Install with Tessl CLI

npx tessl i tessl/npm-polkadot--wasm-crypto

docs

bip39.md

ed25519.md

hashing.md

index.md

key-derivation.md

secp256k1.md

sr25519.md

vrf.md

tile.json