A TypeScript implementation of the secp256k1 elliptic curve cryptography library, providing essential functionality for Bitcoin-compatible cryptographic operations.
This library is NOT available on NPM for security reasons. Cryptographic libraries require careful vetting and should be manually reviewed before use in production environments.
Since this package is not published to NPM, you need to install it directly from the GitHub repository:
# Clone the repository
git clone https://github.com/Fantasim/secp256k1.git
cd secp256k1
# Install dependencies
npm install
# Build the project (if applicable)
npm run build
- Private Key Generation: Create random private keys or import from existing values
- Public Key Derivation: Generate public keys from private keys with compressed/uncompressed formats
- Digital Signatures: ECDSA signing and verification using SHA-512 hashing
- Point Operations: Elliptic curve point arithmetic (addition, doubling, scalar multiplication)
- Constant-Time Operations: Side-channel attack resistant implementations
- Format Support: Handle various key formats (hex strings, buffers, points)
import PrivateKey from "./src/private-key";
import Point from "./src/point";
// Generate a random private key
const privateKey = PrivateKey.random();
console.log("Private key:", privateKey.get().toString(16));
// Get the corresponding public key
const publicKey = privateKey.publicKey();
console.log("Public key (hex):", publicKey.to().hex());
console.log("Public key (compressed):", publicKey.to().hex(true));
// Point multiplication example
const result = Point.SECP256K1.multiplyCT(140n);
console.log("Point multiplication result:", result);
import PrivateKey from "./src/private-key";
// Create from random
const randomKey = PrivateKey.random();
// Create from buffer
const keyBuffer = Buffer.from("your-32-byte-private-key-here", "hex");
const privateKey = new PrivateKey(keyBuffer);
// Create from bigint
const privateKeyFromBigInt = new PrivateKey(123456789n);
// Get the raw private key value
const rawKey = privateKey.get();
import PublicKey from "./src/public-key";
import Point from "./src/point";
// Create from point
const point = new Point(x_coordinate, y_coordinate);
const publicKey = new PublicKey(point);
// Create from hex string (compressed or uncompressed)
const pubKeyFromHex = PublicKey.from("03" + "x_coordinate_64_chars");
// Create from buffer
const pubKeyBuffer = Buffer.from("public_key_hex", "hex");
const pubKeyFromBuffer = PublicKey.from(pubKeyBuffer);
// Export in different formats
const pubKey = privateKey.publicKey();
console.log("Uncompressed hex:", pubKey.to().hex(false));
console.log("Compressed hex:", pubKey.to().hex(true));
console.log("As bytes:", pubKey.to().bytes(true));
console.log("As point:", pubKey.to().point());
import PrivateKey from "./src/private-key";
const privateKey = PrivateKey.random();
const publicKey = privateKey.publicKey();
// Sign a message
const message = "Hello, Bitcoin!";
const signature = privateKey.sign(message);
// Verify the signature
const isValid = signature.verify(message, publicKey);
console.log("Signature valid:", isValid);
// Sign buffer data
const data = Buffer.from("binary data here");
const bufferSignature = privateKey.sign(data);
const isBufferValid = bufferSignature.verify(data, publicKey);
import Point from "./src/point";
// Use the secp256k1 generator point
const G = Point.SECP256K1;
// Scalar multiplication (constant-time)
const result = G.multiplyCT(42n);
// Point addition
const point1 = new Point(x1, y1);
const point2 = new Point(x2, y2);
const sum = point1.add(point2);
// Point doubling
const doubled = point1.double();
// Zero point
const zero = Point.ZERO;
PrivateKey.random()
- Generate a random private keynew PrivateKey(value)
- Create from bigint or Bufferget()
- Get the raw private key as bigintpublicKey()
- Derive the corresponding public keysign(data)
- Sign data and return a Signature object
PublicKey.from(input)
- Create from string, Point, or Bufferto().hex(compressed?)
- Export as hex stringto().bytes(compressed?)
- Export as Bufferto().point()
- Get the underlying Point object
verify(data, publicKey)
- Verify signature against data and public keySignature.dataToHash(data)
- Hash data using SHA-512 (internal method)
Point.SECP256K1
- The secp256k1 generator pointPoint.ZERO
- The point at infinityadd(point)
- Add two pointsdouble()
- Double a pointmultiplyCT(scalar)
- Constant-time scalar multiplication
-
Random Number Generation: The current implementation uses
Math.random()
for key generation, which is NOT cryptographically secure. For production use, replace with a cryptographically secure random number generator. -
Side-Channel Attacks: The library implements constant-time operations where possible, but a full security audit is recommended before production use.
-
Input Validation: Always validate inputs, especially when dealing with user-provided private keys or signatures.
-
Key Storage: Never store private keys in plain text. Use proper key management practices.
For hashing operations (SHA-512), crypto-js is used (natively included in Node or most browser) If you feel unsafe about it, you just need to find a no-dependency implementation of SHA-512 and include it in the cloned project.
# Install dependencies
npm install
# Run tests (if available)
npm test
# Build the project
npm run build
Please check the repository for license information.
This is a cryptographic library. All contributions should be thoroughly reviewed and tested. Please ensure any changes maintain the security properties of the implementation.
This library is provided as-is for educational and development purposes. Use in production environments requires thorough security review and testing. The authors are not responsible for any loss of funds or security breaches resulting from the use of this library.