Skip to content

Commit e0fdfcb

Browse files
authored
Merge pull request #2 from pur3miish/ripemd160-migration
Ripemd160 migration
2 parents 7b2fd2e + de1e5ed commit e0fdfcb

41 files changed

Lines changed: 4895 additions & 833 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.json

Lines changed: 0 additions & 18 deletions
This file was deleted.

.github/workflows/node.js.yml

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,39 @@
11
name: CI
2-
on: [push, pull_request]
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
permissions:
8+
contents: read
9+
310
jobs:
411
test:
5-
name: Test with Node.js v${{ matrix.node }} and ${{ matrix.os }}
12+
name: Node ${{ matrix.node }} / ${{ matrix.os }}
613
runs-on: ${{ matrix.os }}
14+
715
strategy:
816
matrix:
9-
os: [ubuntu-latest, macos-latest]
10-
node: ["20"]
17+
os:
18+
- ubuntu-latest
19+
- macos-latest
20+
node:
21+
- 22
22+
- 24
23+
- 26
24+
1125
steps:
12-
- uses: actions/checkout@v3
13-
- name: Setup Node.js v${{ matrix.node }}
14-
uses: actions/setup-node@v3
26+
- name: Checkout
27+
uses: actions/checkout@v6
28+
29+
- name: Setup Node.js ${{ matrix.node }}
30+
uses: actions/setup-node@v6
1531
with:
1632
node-version: ${{ matrix.node }}
17-
- name: npm install and test
18-
run: npm install-test
33+
cache: npm
34+
35+
- name: Install dependencies
36+
run: npm ci
37+
38+
- name: Run package smoke test
39+
run: npm run smoke

.gitignore

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
node_modules
2-
/*.js
3-
/*.d.ts
4-
/internal/
5-
/keys/
1+
node_modules/
2+
dist/
3+
64
.DS_Store
5+
76
coverage/
8-
.nyc_output
7+
.nyc_output/
8+
9+
*.tgz

.npmrc

Lines changed: 0 additions & 1 deletion
This file was deleted.

.prettierignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
package.json
1+
dist/
2+
node_modules/
3+
coverage/

changelog.md

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,251 @@
11
# Antelope ECC Changelog
22

3+
## 6.0.0 - 2026-08-07
4+
5+
### Breaking Changes
6+
7+
- Updated the minimum supported Node.js version to **Node.js 22**.
8+
- Migrated `ripemd160-js` from v3 to **v4** and adopted its synchronous `Uint8Array -> Uint8Array` API.
9+
- Updated `isomorphic-secp256k1-js` to **v6**.
10+
- Standardized the package as **native ESM**.
11+
- Removed legacy/default package export behavior. Consumers should use named imports or documented deep imports.
12+
- Package build artifacts are now generated under `dist/` rather than alongside TypeScript source files.
13+
- Renamed the `sign_packed_txn()` `extension` argument to `context_free_data_hash` to correctly describe its role in the Antelope transaction signing preimage.
14+
- `new_keys()` is now synchronous and returns the generated key pair directly instead of `Promise<{ public_key, private_key }>`.
15+
- `recover_public_key()` is now synchronous and returns the recovered `PUB_K1_` key directly instead of `Promise<string>`.
16+
- Public-key derivation and RIPEMD-backed key conversion and validation operations no longer introduce unnecessary Promise wrappers.
17+
- `mnemonic_recover()` is now asynchronous because BIP39 recovery verifies the mnemonic checksum using SHA-256.
18+
- Key decoding and validation are stricter and may now reject malformed, checksum-valid, or structurally invalid key material that older versions accepted.
19+
- Signing now requires an exact 32-byte digest. Malformed, partial, or incorrectly sized hexadecimal input is rejected.
20+
- Existing callers using `await` with newly synchronous APIs remain compatible because JavaScript permits awaiting non-Promise values, but callers using `.then()`, `.catch()`, `Promise.all()`, or explicit `Promise<T>` typings must update their code.
21+
22+
### Added
23+
24+
- Added a side-effect-free root ESM entry point exposing the supported API through named exports.
25+
- Added explicit supported deep-import paths.
26+
- Added TypeScript declaration generation for the complete published API.
27+
- Added npm package smoke testing against the actual tarball produced by `npm pack`.
28+
- Added a committed npm lockfile for reproducible installations and CI.
29+
- Added modern ESLint flat configuration.
30+
- Added automated lint-fix and formatting scripts.
31+
- Added CI coverage across Node.js **22, 24, and 26** on Linux and macOS.
32+
- Added strict secp256k1 scalar validation for `PVT_K1_` private keys.
33+
- Added strict compressed SEC 1 point validation for `PUB_K1_` public keys.
34+
- Added checksum validation when decoding K1 private and public keys.
35+
- Added checksum validation when decoding and recovering `SIG_K1_` signatures.
36+
- Added strict 32-byte digest validation for signing and public-key recovery.
37+
- Added strict hexadecimal validation for packed transaction signing inputs.
38+
- Added validation that `chain_id` and `context_free_data_hash` are exactly 32 bytes.
39+
- Added bounded rejection sampling when generating random secp256k1 private keys.
40+
- Added BIP39 checksum validation during mnemonic recovery.
41+
- Added validation for standard BIP39 entropy sizes of 128, 160, 192, 224, and 256 bits.
42+
- Added validation for standard BIP39 mnemonic lengths of 12, 15, 18, 21, and 24 words.
43+
- Added BIP39 known-vector and invalid-checksum tests.
44+
- Added tests for checksum-valid but cryptographically invalid secp256k1 keys.
45+
- Added smoke-test assertions ensuring synchronous public APIs do not accidentally regress back to returning Promises.
46+
47+
### Changed
48+
49+
- RIPEMD-160 imports now use the v4 package API:
50+
51+
```js
52+
import { ripemd160 } from "ripemd160-js";
53+
```
54+
55+
- Updated Antelope private-key, public-key, and signature checksum operations to use synchronous RIPEMD-160.
56+
57+
- Removed unnecessary asynchronous RIPEMD-160 checksum handling.
58+
59+
- Updated K1 key encoding and decoding so cryptographic validity is checked in addition to Antelope Base58 checksum validity.
60+
61+
- `private_key_from_wif()` now validates the `PVT_K1_` checksum and secp256k1 scalar before returning the raw private key.
62+
63+
- `public_key_from_wif()` now validates the `PUB_K1_` checksum and compressed secp256k1 point before returning the raw public key.
64+
65+
- `private_key_to_wif()` now rejects invalid secp256k1 private scalars before encoding them.
66+
67+
- `public_key_to_wif()` now requires a valid compressed 33-byte secp256k1 public key before encoding it.
68+
69+
- `public_key_from_private_wif()` now uses the validated private-key decoding path before deriving the public key.
70+
71+
- `sign()` now validates the supplied `PVT_K1_` private key before signing.
72+
73+
- `sign()` now accepts only:
74+
75+
- a 32-byte `Uint8Array`; or
76+
- a hexadecimal string containing exactly 64 hexadecimal characters.
77+
78+
- `recover_public_key()` now validates the full `SIG_K1_` checksum before attempting secp256k1 public-key recovery.
79+
80+
- `recover_public_key()` now requires an exact 32-byte digest.
81+
82+
- `sign_packed_txn()` now validates the complete signing preimage rather than extracting hexadecimal byte pairs from partially valid input.
83+
84+
- `transaction_header` and `transaction_body` must now contain complete, even-length hexadecimal byte strings.
85+
86+
- `chain_id` must contain exactly 32 bytes of hexadecimal data.
87+
88+
- `context_free_data_hash` must contain exactly 32 bytes of hexadecimal data.
89+
90+
- `context_free_data_hash` defaults to 32 zero bytes when no context-free data is present.
91+
92+
- Clarified that `context_free_data_hash` is unrelated to Antelope `transaction_extensions`, which are serialized as part of the transaction itself.
93+
94+
- Replaced environment-specific Node.js random-byte handling with the standard Web Crypto API:
95+
96+
```js
97+
globalThis.crypto.getRandomValues(...)
98+
```
99+
100+
- Removed the previous `require("crypto")` and dynamic `import("crypto")` random-byte fallback logic.
101+
102+
- Random-byte generation now uses the same standards-based API in Node.js and modern browsers.
103+
104+
- Random-byte generation supports requests larger than the Web Crypto 65,536-byte per-call limit by filling the result in chunks.
105+
106+
- `new_keys()` now retries random candidates that are outside the valid secp256k1 private-scalar range.
107+
108+
- BIP39 mnemonic creation now validates supported entropy sizes.
109+
110+
- BIP39 mnemonic recovery now verifies checksum bits before returning entropy.
111+
112+
- Retained the historical Antelope/Graphene compact-canonical signature compatibility policy inside `antelope-ecc`.
113+
114+
- Kept generic standards-focused secp256k1 behavior isolated inside `isomorphic-secp256k1-js`.
115+
116+
- Updated TypeScript compilation to use `NodeNext` module and module-resolution semantics.
117+
118+
- TypeScript source now lives exclusively under `src/`.
119+
120+
- Compiled JavaScript and `.d.ts` files are generated exclusively under `dist/`.
121+
122+
- npm now publishes only the compiled `dist/` distribution.
123+
124+
- Updated README documentation for the v6 API, synchronous and asynchronous API boundaries, ESM usage, deep imports, Node.js requirements, Web Crypto support, package structure, signing semantics, and security considerations.
125+
126+
### Async API Boundary
127+
128+
The following APIs remain asynchronous because they perform operations that genuinely require asynchronous Web Crypto primitives:
129+
130+
- `sign()` — RFC 6979 signing uses asynchronous HMAC-SHA-256.
131+
- `sign_packed_txn()` — computes SHA-256 and then signs the resulting digest.
132+
- `legacy_from_private_key()` — performs SHA-256 checksum operations.
133+
- `mnemonic_create()` — computes the BIP39 SHA-256 checksum.
134+
- `mnemonic_recover()` — verifies the BIP39 SHA-256 checksum.
135+
136+
Pure key encoding, decoding, validation, public-key derivation, secure random-byte generation, and public-key recovery operations are synchronous.
137+
138+
### Tooling
139+
140+
- Updated TypeScript to v6.
141+
- Migrated from legacy `.eslintrc` configuration to ESLint flat config.
142+
- Updated ESLint to v10.
143+
- Updated Prettier to v3.
144+
- Updated `typescript-eslint`.
145+
- Updated `eslint-plugin-simple-import-sort`.
146+
- Updated test and development dependencies.
147+
- CI now uses `npm ci`.
148+
- CI now runs the complete npm package smoke test.
149+
- Simplified build cleanup so only generated `dist/` output is removed.
150+
151+
### Package Structure
152+
153+
Source files are maintained under:
154+
155+
```text
156+
src/
157+
├── index.ts
158+
├── sign.ts
159+
├── sign_packed_txn.ts
160+
├── recover_public_key.ts
161+
├── new_keys.ts
162+
├── mnemonic_create.ts
163+
├── mnemonic_recover.ts
164+
├── keys/
165+
└── internal/
166+
```
167+
168+
TypeScript generates the npm distribution under:
169+
170+
```text
171+
dist/
172+
├── index.js
173+
├── index.d.ts
174+
├── sign.js
175+
├── sign.d.ts
176+
├── sign_packed_txn.js
177+
├── sign_packed_txn.d.ts
178+
├── recover_public_key.js
179+
├── recover_public_key.d.ts
180+
├── new_keys.js
181+
├── new_keys.d.ts
182+
├── mnemonic_create.js
183+
├── mnemonic_create.d.ts
184+
├── mnemonic_recover.js
185+
├── mnemonic_recover.d.ts
186+
├── keys/
187+
└── internal/
188+
```
189+
190+
Generated JavaScript is no longer stored alongside TypeScript source files.
191+
192+
### Dependencies
193+
194+
Runtime dependencies are now:
195+
196+
- `base58-js` v3
197+
- `isomorphic-secp256k1-js` v6
198+
- `ripemd160-js` v4
199+
200+
### Removed
201+
202+
- Removed support for Node.js versions below 22.
203+
- Removed support for `ripemd160-js` v3.
204+
- Removed the legacy `ripemd160-js/ripemd160.js` deep import.
205+
- Removed the unused `eosio-wasm-js` runtime dependency.
206+
- Removed Node-specific `require("crypto")` random-byte handling.
207+
- Removed dynamic Node `crypto` import fallback logic.
208+
- Removed legacy ESLint `.eslintrc` configuration.
209+
- Removed generated JavaScript from the TypeScript source tree.
210+
- Removed obsolete root-level compiler output and cleanup behavior.
211+
- Removed stale CommonJS and default-import documentation.
212+
- Removed unnecessary Promise wrappers from synchronous key and recovery operations.
213+
214+
### Migration Notes
215+
216+
Applications upgrading from v5 should:
217+
218+
- run on Node.js 22 or later;
219+
- update default package imports to named imports;
220+
- use documented package exports for deep imports;
221+
- update `sign_packed_txn()` calls from `extension` to `context_free_data_hash`;
222+
- treat `new_keys()` as synchronous;
223+
- treat `recover_public_key()` as synchronous;
224+
- update `.then()` or explicit Promise typings for APIs that now return values directly;
225+
- provide exactly 32-byte digests to `sign()` and `recover_public_key()`;
226+
- expect malformed or cryptographically invalid K1 keys to be rejected more strictly;
227+
- `await mnemonic_recover()` because mnemonic recovery now performs BIP39 checksum verification.
228+
229+
Typical root imports are:
230+
231+
```js
232+
import {
233+
new_keys,
234+
recover_public_key,
235+
sign,
236+
sign_packed_txn,
237+
validate_private_key,
238+
validate_public_key,
239+
} from "antelope-ecc";
240+
```
241+
242+
Individual modules may also be imported through documented package subpaths:
243+
244+
```js
245+
import sign from "antelope-ecc/sign.js";
246+
import new_keys from "antelope-ecc/new_keys.js";
247+
```
248+
3249
## 5.0.1 - 2026-08-03
4250

5251
### Major

eslint.config.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import js from "@eslint/js";
2+
import globals from "globals";
3+
import simpleImportSort from "eslint-plugin-simple-import-sort";
4+
import tseslint from "typescript-eslint";
5+
6+
export default tseslint.config(
7+
{
8+
ignores: ["dist/**", "node_modules/**", "coverage/**"],
9+
},
10+
11+
js.configs.recommended,
12+
...tseslint.configs.recommended,
13+
14+
{
15+
files: ["src/**/*.ts", "test/**/*.ts", "scripts/**/*.mjs"],
16+
17+
languageOptions: {
18+
ecmaVersion: "latest",
19+
sourceType: "module",
20+
21+
globals: {
22+
...globals.browser,
23+
...globals.node,
24+
...globals.mocha,
25+
},
26+
},
27+
28+
plugins: {
29+
"simple-import-sort": simpleImportSort,
30+
},
31+
32+
rules: {
33+
"prefer-const": "off",
34+
"simple-import-sort/imports": "error",
35+
"simple-import-sort/exports": "error",
36+
},
37+
},
38+
);

0 commit comments

Comments
 (0)