Antelope ECC
A lightweight universal JavaScript digital-signature and cryptographic-key utility package for Antelope-based blockchains.
- Creates recoverable Antelope
SIG_K1_signatures from 32-byte transaction digests. - Uses the standards-focused
isomorphic-secp256k1-jsimplementation for secp256k1, ECDSA, and RFC 6979 operations. - Applies Antelope's historical compact-canonical signing policy, inherited from the Graphene/BitShares
fclibrary, only inside this package. - Creates, validates, converts, and recovers Antelope
PVT_K1_,PUB_K1_, and legacy key representations.
Requirements
Supported runtime environments:
- Node.js versions
>=20.19.0. - Browsers matching the Browserslist query
> 0.5%, not OperaMini all, not dead.
Installation
For Node.js, to install antelope-ecc run:
npm i antelope-ecc
Ways to import in ESM
import { sign } from "antelope-ecc"; // Tree shaking capabilities.
As default exports
import AntelopeECC from "antelope-ecc";
Ways to require/import in Common JS
const AntelopeECC = import("antelope-ecc");
AntelopeECC.then(({ sign }) => {
// As import is async
});
Sign a message digest.
import { sign } from "antelope-ecc";
import { createHash } from "crypto";
await sign({
hash: createHash("sha256")
.update(Uint8Array.from([1, 2, 3, 4, 5]))
.digest()
.toString("hex"), // Uint8Array | string
wif_private_key: "PVT_K1_43…",
}).then(console.log);
The logged output will be SIG_K1…
Antelope K1 signing compatibility
The underlying ECDSA signer first creates a deterministic, low-S secp256k1 signature using RFC 6979. Antelope additionally retains a historical signature policy inherited from the Graphene/BitShares fc cryptography library: the positive DER integer representation of each fixed-width r and s component must be exactly 32 bytes.
If the first standards-based signature does not have that representation, this package deterministically derives another nonce and signs the original digest again until the Antelope policy is satisfied. This retry rule is implemented only by antelope-ecc; it is not an ECDSA, secp256k1, or RFC 6979 security requirement, and it is not exposed by isomorphic-secp256k1-js.
The policy exists for compatibility with Antelope/EOSIO signing software and historical signature vectors. Low-S normalization is the separate protection against the usual ECDSA (r, s) / (r, n - s) malleability.
Applications do not enable this mode or pass a compatibility option. The exported sign and sign_packed_txn functions always apply the policy because they return Antelope signatures. Applications that need only the first standards-based RFC 6979 signature should use isomorphic-secp256k1-js directly.
Signing sequence
- Decode and validate the Antelope
PVT_K1_private key and require an exact 32-byte message digest. - Generate the first recoverable secp256k1 ECDSA signature using RFC 6979 deterministic nonce derivation and low-S normalization.
- Test whether the fixed-width
randsvalues satisfy the inherited Graphene/BitShares 32-byte positive-DER-component policy. - If necessary, perform the deterministic compatibility retry internally while continuing to sign the original message digest.
- Verify the resulting signature before serializing the recovery header,
r, andsinto the 65-byte Antelope compact representation. - Add the
K1RIPEMD-160 checksum and Base58-encode the result asSIG_K1_….
Package boundary
isomorphic-secp256k1-jscontains the reusable secp256k1 arithmetic, hashing, RFC 6979 signer, verification, recovery, validation, and low-S handling. It does not expose the Graphene/BitShares retry policy.antelope-ecccontains the Antelope key formats,SIG_K1_encoding, recovery-header conversion, checksum, and inherited Graphene/BitShares compatibility retry.- The compatibility signer is an internal module and is not listed in the package
exportsmap. The supported public entry points remainsignandsign_packed_txn.
An example of how to create a pair keys.
import { new_keys } from "antelope-ecc";
new_keys().then(console.log);
The logged output will be an object containing PUB_K1 and PVT_K1 wif keys.
Recover public key from signature.
import { recover_public_key } from "antelope-ecc";
const hash = Uint8Array.from(
crypto.createHash("sha256").update(Buffer.from("ff", "hex")).digest()
); // Data signed with private key
recover_public_key({
signature: "SIG_K1_…",
hash,
}).then(console.log);
The logged output will contain the public key “PUB_K1…” used to sign the hash.
Exports
ECMAScript module deep exports are available through the package.json exports field. These links open the TypeScript source retained in Git; npm consumers import the corresponding compiled .js path:
antelope-ecc/keys/legacy_from_private_key.jsantelope-ecc/keys/legacy_from_public_key.jsantelope-ecc/keys/legacy_to_private_key.jsantelope-ecc/keys/legacy_to_public_key.jsantelope-ecc/keys/private_key_from_wif.jsantelope-ecc/keys/private_key_to_wif.jsantelope-ecc/keys/public_key_from_private_wif.jsantelope-ecc/keys/public_key_from_wif.jsantelope-ecc/keys/public_key_to_wif.jsantelope-ecc/keys/validate_private_key.jsantelope-ecc/keys/validate_public_key.jsantelope-ecc/mnemonic_create.jsantelope-ecc/mnemonic_recover.jsantelope-ecc/new_keys.jsantelope-ecc/recover_public_key.jsantelope-ecc/sign_packed_txn.jsantelope-ecc/sign.js
Development and publishing
The Git repository keeps the TypeScript source under src/ and does not keep compiler-generated .js or .d.ts files. The npm package still contains the compiled JavaScript and TypeScript declarations required by consumers.
npm run cleanremoves only the explicit compiler-output allowlist inscripts/clean.mjs.npm run buildcleans stale outputs and compilessrc/**/*.tsinto the package paths declared bypackage.json.npm packandnpm publishrun the tests and build throughprepack, include the generated files in the tarball, and then remove local generated files throughpostpack.- Generated root files and the generated root
internal/andkeys/directories are ignored by Git. Their TypeScript sources remain undersrc/.
Run npm pack --dry-run to inspect the files npm will include without publishing the package.