The elliptic-curve cryptography used by Bitcoin and Ethereum, implemented in plain JavaScript without crypto libraries: secp256k1 arithmetic, Keccak-256, ECDSA with public key recovery, Schnorr signatures (BIP-340) and Shamir secret sharing. Everything below runs in the browser.
The points of y² = x³ + 7 over a small prime field. Click two points to add them. Enter k and press the button to compute k × P step by step.
The private key d is a random number below the curve order. The public key is d × G. The Ethereum address is the last 20 bytes of the Keccak-256 hash of the public key, with EIP-55 checksum capitalisation.
d = 1 gives the well-known address 0x7E5F…5Bdf. Keys shown on a web page should not be used for real funds.
The message is hashed the way Ethereum's personal_sign does (EIP-191). The nonce k comes from RFC 6979. The signature is (r, s, v), and v lets anyone recover the signer's public key.
Sign the message above with MetaMask (or any wallet), paste the signature here, and the signing address is recovered.
If the same nonce k is used to sign two different messages, the private key can be calculated from the two signatures: k = (z₁ − z₂) / (s₁ − s₂) and d = (s₁k − z₁) / r, all mod n. This is how the PlayStation 3 signing key was recovered in 2010.
The signature scheme used by Bitcoin Taproot. Public keys are 32 bytes (x coordinate only) and signatures are 64 bytes.
The private key is split into 5 shares so that any 3 can rebuild it and 2 reveal nothing. Select shares to try it.
Public keys and signatures are checked against OpenSSL (through Node's crypto module) in both directions, and against published Keccak-256, EIP-55 and BIP-340 test vectors. BigInt arithmetic is not constant-time, so this code is for learning, not for holding funds.
Source: github.com/hpark236/secp256k1-js