npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@project-eleven/pq-address

v0.2.0

Published

A Typescript library for encoding and decoding post‑quantum public keys into human‑friendly Bech32m addresses.

Downloads

140

Readme

PQ Address TS

A TypeScript library for encoding and decoding post‑quantum public keys into human‑friendly Bech32m addresses.

Motivation

Sharing a post‑quantum public key needs:

  1. A hash of the public key for privacy and fixed length.
  2. A strong checksum to catch typos and errors.
  3. A readable, typo‑resistant encoding.
  4. A clear network flag (production vs development).

pq‑address provides all four. It lets you generate and parse addresses for any public‑key type (ML‑DSA, SLH‑DSA, etc.), while guaranteeing future‑proof safety.

Design & Justification

  • Bech32m (BIP‑350)

    • Case insensitive
    • Friendly character set
    • Strong error detection
    • Improved checksum over Bech32
    • Efficient encoding & decoding
    • Smaller QR codes due to use of alphanumeric mode
  • Disjoint byte ranges

    • Version codes in 0x00–0x3F (up to 64 versions).
    • PubKeyType codes in 0x40–0xFF (up to 192 public key types).
    • Any byte‑swap or mis‑read triggers a clear “unknown code” error.

    By carving out non-overlapping slots for versions (0x00–0x3F) and public key types (0x40–0xFF), parsing becomes trivial—and any stray or swapped byte instantly flags itself as an “unknown code,” preventing silent failures.

  • HRP flag

    • "yp" for production/mainnet, "rh" for development/testnet.
  • Extendable

    • Add new PubKeyType variants without breaking old addresses.

Anatomy of a PQ address

Address example: yp1qpqg39uw700gcctpahe650p9zlzpnjt60cpz09m4kx7ncz8922635hs5cdx7q

  1. HRP (yp / rh)

    • yp = Mainnet
    • rh = Testnet
  2. Separator

    • Always the character 1.
  3. Data

    • The payload bytes:
      1. Version
      2. PubKeyType
      3. Raw pubkey hash digest
    • Converted into 5-bit words and then into Bech32 characters.
  4. Checksum

    • 6 Bech32 characters (BIP-350)
    • Catches typos and bit-errors.

PQ address length is 64 characters.

Note: A Bech32 string is at most 90 characters long [BIP-173]

A Note on Hash Algorithms

The default hash function for @project-eleven/pq-address is SHA-256. 256 bit hash functions are currently considered secure against Grover's attack. Even if the preimage is recovered, it only reveals a PQ secure public key and thus Shor's is not applicable.

Quickstart

Add to your package.json:

npm install @project-eleven/pq-address

Import @project-eleven/pq-address

import {
  encodeAddress,
  decodeAddress,
  Network,
  Version
  PubKeyType,
} from '@project-eleven/pq-address';

Encoding

const params = {
  network: Network.MAINNET,
  version: Version.V1,
  pubkeyType: PubKeyType.MlDsa44,
  pubkeyBytes: <PUB_KEY_BYTES>,
};

const pq_addr = encodeAddress(params);
console.log(pq_addr);

Decoding

const decoded = decodeAddress(pq_addr);
console.log(pq_addr);

Errors

import {
  Bech32EncodeFailure,
  InvalidLengthError,
  InvalidHashLengthError,
  InvalidPubkeyLengthError,
  UnknownHrpError,
  UnknownPubKeyTypeError,
  UnknownVersionError,
  PayloadTooShortError,
  Bech32DecodeFailure
} from '@project-eleven/pq-address';

// Example params...
const params = {
  network: Network.MAINNET,
  version: Version.V1,
  pubkeyType: PubKeyType.MlDsa44,
  pubkeyBytes: <PUB_KEY_BYTES>,
};

try {
  // ENCODE
  const addr = encodeAddress(params);
  console.log('Address:', addr);

  // DECODE
  const decoded = decodeAddress(addr);
  console.log('Decoded:', decoded);
  console.log('Re-encoded string:', decoded.toString());
} catch (e: unknown) {
  // Handle encode errors
  if (e instanceof Bech32EncodeFailure) {
    console.error('Bech32 encode failed:', e.original.message);
  } else if (e instanceof InvalidLengthError) {
    console.error(`Bech32m address exceeds safe length: got ${e.got}, max ${e.max}`);
  } else if (e instanceof InvalidPubKeyLengthError) {
    console.error(`Pubkey length mismatch: got ${e.got}, expected ${e.expected}`);
  }
  // Handle decode errors
  else if (e instanceof Bech32DecodeFailure) {
    console.error('Bad address format or checksum:', e.error.message);
  } else if (e instanceof UnknownHrpError) {
    console.error('Unknown network prefix (HRP):', e.hrp);
  } else if (e instanceof PayloadTooShortError) {
    console.error(`Payload too short: got ${e.got}, need ≥ ${e.need}`);
  } else if (e instanceof UnknownVersionError) {
    console.error('Unknown version byte:', e.code);
  } else if (e instanceof UnknownPubKeyTypeError) {
    console.error('Unknown pubkey type byte:', e.code);
  } else if (e instanceof InvalidHashLengthError) {
    console.error(`Hash length mismatch: got ${e.got}, expected ${e.expected}`);
  } else {
    // Fallback for any unexpected error
    console.error('Unexpected error:', e);
  }
}

Contributing

See CONTRIBUTING.md for details on how to contribute to this project.

License

This project is licensed under the MIT License - see the LICENSE file for details.