Files
skills/docs/security-stack/crypto/crypto-curve/src/primitives/p256/p256.md
2026-05-29 08:20:56 +01:00

5.3 KiB

p256

(no submodules)

Purpose

p256.ts is the stable public entry point for the NIST P-256 elliptic-curve primitive in @suaveplan/crypto-curve. It re-exports everything from p256.select.ts, which forwards to either the Noble-backed or native implementation based on crypto.config.ts.

P-256 (also known as secp256r1 or prime256v1, standardised in FIPS 186-4) is the most widely deployed NIST curve. It is mandatory in TLS 1.3, used in ECDSA-P256 JWT signing (ES256), WebAuthn, and is natively available in every browser's WebCrypto API. Callers import from this file and remain insulated from implementation changes.

Features

  • getPublicKey(privateKey) — 33-byte compressed public key.
  • sign(digest, privateKey) — compact 64-byte ECDSA signature (r ‖ s). Caller pre-hashes.
  • verify(signature, digest, publicKey) — boolean; never throws on malformed inputs.
  • randomPrivateKey() — rejection-sampled 32-byte private key.

Usage: Basic Example

import * as p256 from "@suaveplan/crypto-curve/p256";
import { sha256 } from "@suaveplan/crypto-hash/hash";

const sk = p256.randomPrivateKey();
const pk = p256.getPublicKey(sk);
const msg = new TextEncoder().encode("hello P-256");
const sig = p256.sign(sha256(msg), sk);
console.log(p256.verify(sig, sha256(msg), pk)); // true

Usage: Advanced Example

import * as p256 from "@suaveplan/crypto-curve/p256";
import { sha256 } from "@suaveplan/crypto-hash/hash";
import { toHex } from "@suaveplan/crypto-hash/encoding";

// Sign a JSON payload and produce a JWS-style compact token.
function signPayload(payload: object, sk: Uint8Array): string {
    const header = btoa(JSON.stringify({ alg: "ES256" }));
    const body = btoa(JSON.stringify(payload));
    const sigInput = new TextEncoder().encode(`${header}.${body}`);
    const sig = p256.sign(sha256(sigInput), sk);
    return `${header}.${body}.${toHex(sig)}`;
}

API Reference

All symbols re-exported from p256.select.ts:

  • getPublicKey(privateKey: Uint8Array): Uint8Array
  • sign(digest: Uint8Array, privateKey: Uint8Array): Uint8Array
  • verify(signature: Uint8Array, digest: Uint8Array, publicKey: Uint8Array): boolean
  • randomPrivateKey(): Uint8Array

Implementation Notes

This file is a zero-logic re-export barrel. Its sole purpose is the stable import path @suaveplan/crypto-curve/p256. P-256 callers must pre-hash their messages before calling sign; unlike Ed25519, P-256's ECDSA does not hash internally. Use SHA-256 for ES256 compatibility.