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

eccanon

v0.0.1

Published

Canonicalize secp256k1 private keys to ensure public keys always start with 02

Downloads

8

Readme

🔐 ECCANON

npm version License: MIT

The definitive secp256k1 private key canonicalizer for JavaScript.

Eccanon ensures your secp256k1 private keys always produce public keys starting with 02, making your cryptographic operations more predictable and canonical.

🚀 Why Eccanon?

In secp256k1 elliptic curve cryptography, public keys can be compressed to either start with 02 (even y-coordinate) or 03 (odd y-coordinate). For many applications, it's desirable to have a canonical form where all public keys start with 02.

Eccanon solves this by:

  • Canonicalizing private keys to ensure 02-prefixed public keys
  • Preserving the cryptographic security of your keys
  • Providing both library and CLI interfaces
  • Supporting hex strings and byte arrays
  • Zero dependencies except for noble-secp256k1

📦 Installation

npm install eccanon

For CLI usage:

npm install -g eccanon

📚 Library Usage

const eccanon = require('eccanon')

// Canonicalize a private key
const privateKey =
  'a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456'
const canonical = eccanon.canonicalize(privateKey)
console.log(canonical) // Guaranteed to produce a public key starting with 02

// Check if a key is already canonical
const isCanonical = eccanon.isCanonical(privateKey)
console.log(isCanonical) // true or false

// Generate a random canonical private key
const randomCanonical = eccanon.generateCanonical()
console.log(randomCanonical) // Random key that's already canonical

🖥️ CLI Usage

# Canonicalize a private key (default action)
eccanon a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456

# Check if a key is canonical
eccanon 0xa1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456 --check

# Generate a random canonical key
eccanon --generate

# Show help
eccanon --help

🧪 How It Works

The canonicalization process is mathematically elegant:

  1. Input: A secp256k1 private key
  2. Check: Generate the corresponding public key
  3. Decision:
    • If public key starts with 02 → Return original private key
    • If public key starts with 03 → Return (n - privateKey) mod n

Where n is the secp256k1 curve order: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

This transformation preserves the elliptic curve relationship while ensuring the canonical form.

🎯 API Reference

canonicalize(privateKey)

Canonicalizes a private key to ensure its public key starts with 02.

Parameters:

  • privateKey (string | Uint8Array): The private key to canonicalize

Returns:

  • (string): The canonicalized private key as a hex string

Throws:

  • Error if the private key is invalid or out of range

isCanonical(privateKey)

Checks if a private key is already canonical.

Parameters:

  • privateKey (string | Uint8Array): The private key to check

Returns:

  • (boolean): True if canonical, false otherwise

generateCanonical()

Generates a cryptographically secure random canonical private key.

Returns:

  • (string): A random canonical private key as a hex string

🔧 Input Formats

Eccanon accepts private keys in multiple formats:

// Hex string (with or without 0x prefix)
eccanon.canonicalize(
  'a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456'
)
eccanon.canonicalize(
  '0xa1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456'
)

// Uint8Array
const keyBytes = new Uint8Array(32)
// ... fill with key data
eccanon.canonicalize(keyBytes)

🎪 Demo

Try the interactive demo at: GitHub Pages Demo

🔍 Examples

Bitcoin Integration

const eccanon = require('eccanon')
const bitcoin = require('bitcoinjs-lib')

// Ensure canonical private key for Bitcoin
const privateKey = eccanon.canonicalize(myPrivateKey)
const keyPair = bitcoin.ECPair.fromPrivateKey(Buffer.from(privateKey, 'hex'))
// Public key is guaranteed to start with 02

Ethereum Integration

const eccanon = require('eccanon')
const { Wallet } = require('ethers')

// Canonical private key for Ethereum
const canonicalKey = eccanon.canonicalize(originalKey)
const wallet = new Wallet(canonicalKey)
// Deterministic public key format

🛡️ Security

  • Cryptographically Sound: The canonicalization preserves all security properties
  • No Key Weakening: The transformation maintains the discrete logarithm problem difficulty
  • Deterministic: Same input always produces the same output
  • Reversible: The mapping is mathematically reversible (though not implemented for security)

⚡ Performance

  • Fast: Optimized for high-performance applications
  • Minimal Dependencies: Only depends on noble-secp256k1
  • Memory Efficient: Works with both strings and byte arrays
  • Browser Compatible: Works in both Node.js and browsers

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📄 License

MIT License - see LICENSE for details.

🌟 Support