506b77351c735197567f110236cb7604a3043749
Before this, an exported Quantus account could not be imported by anything. decodePair located its divider by trying the two secret lengths every curve scheme uses, 64 then 32; an ML-DSA secret is 4032 or 4896 bytes, so neither matched and restore threw "Invalid encoding divider found in body". That is a data-durability bug rather than a convenience one, which is why it lands before any build lets a user create an account. decodePair now takes an optional secretLength. The caller passes it rather than this function searching for the divider: searching would work almost always and fail catastrophically when it did not, since PAIR_DIV is five bytes and a 4032-byte secret contains a false match about once in 270 million keys — and the result would be a silently wrong key rather than an error. The public key is read as the remainder, because its length also varies and the body ends there. The harder half is ordering. createFromJson returns a *locked* pair and callers read pair.address off it long before any password appears. Every other scheme manages because the address is the public key; an ML-DSA account id is a one-way Poseidon2 hash and the public key is inside the encrypted blob. So PairInfo gains an optional accountId, carried as data and used for the address while locked, which decodePkcs8 clears once the real key arrives. It also checks them against each other, and that check is not paranoia. For the curve schemes a JSON file with an edited `address` field cannot decode at all. Here it decodes perfectly and yields a pair reporting an address its key does not control — a user would see someone else's address in their own wallet and believe they held it. Pinned by a test that tampers exactly that field. One more silent-wrong-key path closed: decodePkcs8 decided "secret key or seed?" by length, so a 4032-byte ML-DSA secret took the seed branch and was fed to keygen as entropy, producing a valid and entirely wrong key. The type knows the answer, so it is asked. Refs quantus/common#3 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
@polkadot/common
Various useful utility functions that are used across all projects in the @polkadot namespace. It provides utility functions with additional safety checks, allowing not only for consistent coding, but also reducing the general boilerplate.
overview
This repository is split up into a number of internal packages, namely utilities -
- keyring Keyring management
- util General utilities
- util-crypto Crypto and hashing utilities
development
Contributions are welcome!
To start off, this repo (along with others in the @polkadot family) uses yarn workspaces to organise the code. As such, after cloning, its dependencies should be installed via yarn, not via npm; the latter will result in broken dependencies.
To get started -
- Clone the repo locally, via
git clone https://github.com/polkadot-js/common <optional local path> - Ensure that you have a recent version of Node.js, for development purposes Node 10 is recommended.
- Ensure that you have a recent version of Yarn, for development purposes Yarn >=1.10.1 is required.
- Install the dependencies by running
yarn - Build the everything via
yarn run build - You can also launch the API Docs, via
yarn vuepress dev docs - Access the docs via http://localhost:8080
tutorials
Looking for tutorials to get started? Look at examples for guides on how to use the base utilities.
Description
Fork of polkadot-js/common. Carries the ML-DSA (Dilithium) keypair types in @polkadot/keyring and @polkadot/util-crypto: Quantus account ids are Poseidon2 hashes of 1952/2592-byte public keys, which upstream's 32-byte assumptions cannot express. Not upstreamable — see quantus/extension#1.
Languages
TypeScript
99.7%
JavaScript
0.2%
HTML
0.1%