feat: add all @pezkuwi/wasm-crypto packages with bizinikiwi context

This commit is contained in:
2026-02-01 08:01:30 +03:00
parent c533e85807
commit b61206c14e
141 changed files with 17048 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
root = true
[*]
indent_style=space
indent_size=2
tab_width=2
end_of_line=lf
charset=utf-8
trim_trailing_whitespace=true
max_line_length=120
insert_final_newline=true
+86
View File
@@ -0,0 +1,86 @@
<!--
For general support, howto, coding and bundling questions, please
use the Substrate & Polkadot StackExchange at
https://substrate.stackexchange.com/
and get other ecosystem developers involved. This issues in this
repository are meant for the tracking of feature requests and bug
reports.
While all issues are looked at non-bug and non-features would take
quite a bit longer to get to and may yield less than satisfactory
responses in this format.
Additionally, please ensure you have done a search on the existing
and closed issues before logging a new request. This saves time on
all sides.
-->
* **I'm submitting a ...**
<!---
REQUIRED:
Classify the type of report your are submitting
-->
- [ ] Bug report
- [ ] Feature request
- [ ] Support request
- [ ] Other
* **What is the current behavior and expected behavior?**
<!---
REQUIRED:
If you're describing a bug, tell us what should happen. If you're
suggesting a change/improvement, tell us how it should work.
-->
* **What is the motivation for changing the behavior?**
<!---
OPTIONAL:
Suggest a motivation for the request or ideas how to implement the
addition or change
-->
* **Please tell us about your environment:**
<!---
REQUIRED:
Include as many relevant details about the environment in which you
experienced the issue. Also ensure that you have tested against the
latest stable releases if you believe this to be a bug
-->
- Version:
- Environment:
- [ ] Node.js
- [ ] Browser
- [ ] Other (limited support for other environments)
- Language:
- [ ] JavaScript
- [ ] TypeScript (include tsc --version)
- [ ] Other
+16
View File
@@ -0,0 +1,16 @@
name: bot
on:
pull_request:
types: [labeled]
jobs:
approve:
if: "! startsWith(github.event.head_commit.message, '[CI Skip]') && (!github.event.pull_request || github.event.pull_request.head.repo.full_name == github.repository)"
runs-on: ubuntu-latest
steps:
- uses: jacogr/action-approve@795afd1dd096a2071d7ec98740661af4e853b7da
with:
authors: jacogr, TarikGul, valentinfernandez1
labels: -auto
token: ${{ secrets.GH_PAT_BOT }}
+16
View File
@@ -0,0 +1,16 @@
name: bot
on:
pull_request:
types: [labeled]
jobs:
merge:
runs-on: ubuntu-latest
steps:
- uses: jacogr/action-merge@d2d64b4545acd93b0a9575177d3d215ae3f92029
with:
checks: pr (build),pr (lint),pr (test)
labels: -auto
strategy: squash
token: ${{ secrets.GH_PAT_BOT }}
+25
View File
@@ -0,0 +1,25 @@
name: 'Lock Threads'
on:
schedule:
- cron: '20 1/3 * * *'
jobs:
lock:
runs-on: ubuntu-latest
env:
YARN_ENABLE_SCRIPTS: false
steps:
- uses: dessant/lock-threads@c1b35aecc5cdb1a34539d14196df55838bb2f836
with:
github-token: ${{ secrets.GH_PAT_BOT }}
issue-inactive-days: '7'
issue-comment: >
This thread has been automatically locked since there has not been
any recent activity after it was closed. Please open a new issue
if you think you have a related problem or query.
pr-inactive-days: '2'
pr-comment: >
This pull request has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new issue for related bugs.
+30
View File
@@ -0,0 +1,30 @@
name: PR
on: [pull_request]
jobs:
pr:
continue-on-error: true
strategy:
matrix:
step: ['lint', 'test', 'build', 'deno']
runs-on: ubuntu-latest
env:
YARN_ENABLE_SCRIPTS: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- uses: denoland/setup-deno@v1
with:
deno-version: v1.42.x
- name: ${{ matrix.step }}
if: always()
continue-on-error: true
run: |
yarn install --immutable
if [ "${{ matrix.step }}" != "lint" ]; then
./scripts/install-build-deps.sh
fi
yarn polkadot-dev-deno-map
yarn ${{ matrix.step }}
+36
View File
@@ -0,0 +1,36 @@
name: Master
on:
push:
branches:
- master
jobs:
master:
if: "! startsWith(github.event.head_commit.message, '[CI Skip]')"
strategy:
matrix:
step: ['build:release']
runs-on: ubuntu-latest
env:
YARN_ENABLE_SCRIPTS: false
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
GH_PAT: ${{ secrets.GH_PAT_BOT }}
GH_RELEASE_GITHUB_API_TOKEN: ${{ secrets.GH_PAT_BOT }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GH_PAT_BOT }}
ref: ${{ github.ref }}
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- name: Set Execute Permissions
run: chmod +x ./scripts/*
- name: Run Install Build Deps
run: bash ./scripts/install-build-deps.sh
- name: build
run: |
yarn install --immutable
yarn ${{ matrix.step }}
+32
View File
@@ -0,0 +1,32 @@
binaryen/
bindgen/
build/
build-*/
bytes/
coverage/
node_modules/
pkg/
target/
tmp/
wabt/
/import_map.json
/mod.ts
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.npmrc
.pnp.*
.yarn/*
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
cc-test-reporter
lerna-debug.log*
npm-debug.log*
package-lock.json
report.*.json
tsconfig.*buildinfo
yarn-debug.log*
yarn-error.log*
+3
View File
@@ -0,0 +1,3 @@
Jaco <jacogr@gmail.com>
github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> <action@github.com>
github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Github Actions <action@github.com>
View File
+4
View File
@@ -0,0 +1,4 @@
build
coverage
packages
scripts
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2017-2025 @polkadot/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
module.exports = require('@polkadot/dev/config/prettier.cjs');
+4
View File
@@ -0,0 +1,4 @@
{
"eslint.enable": true,
"eslint.experimental.useFlatConfig": true
}
View File
+934
View File
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
compressionLevel: mixed
enableGlobalCache: false
enableImmutableInstalls: false
enableProgressBars: false
logFilters:
- code: YN0013
level: discard
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.6.0.cjs
+540
View File
@@ -0,0 +1,540 @@
# CHANGELOG
## 7.5.4 Dec 9, 2025
Changes:
- Bump polkadot-js dependencies ([#605](https://github.com/polkadot-js/wasm/pull/605))
## 7.5.3 Nov 24, 2025
Changes:
- Bump @polkadot dependencies ([#603](https://github.com/polkadot-js/wasm/pull/603))
## 7.5.2 Nov 10, 2025
Changes:
- Fix/Revert asm build ([#599](https://github.com/polkadot-js/wasm/pull/599))
- Bump @polkadot dependencies ([#601](https://github.com/polkadot-js/wasm/pull/601))
## 7.5.1 aug 25, 2025
Changes:
- Bump yarn to 4.5.1 ([#573](https://github.com/polkadot-js/wasm/pull/573))
- Update comments and labels from 2024 to 2025 ([#574](https://github.com/polkadot-js/wasm/pull/574))
- Bump yarn to 4.6.0 ([#575](https://github.com/polkadot-js/wasm/pull/575))
- Set execute for build script in CI ([#576](https://github.com/polkadot-js/wasm/pull/576))
- Set permissions on all scripts ([#577](https://github.com/polkadot-js/wasm/pull/577))
- Bump dev to 0.83.2 ([#578](https://github.com/polkadot-js/wasm/pull/578))
- chore: added check in ext_secp_recover for signature normalization ([#579](https://github.com/polkadot-js/wasm/pull/579))
- chore: Improve CI ([#580](https://github.com/polkadot-js/wasm/pull/580))
- Revert CI improvements and wasm-bindgen version ([#583](https://github.com/polkadot-js/wasm/pull/583))
- Added validation checks in PBKDF2 and Scrypt hashing functions ([#584](https://github.com/polkadot-js/wasm/pull/584))
- Rollback wasm-bindgen version change ([#586](https://github.com/polkadot-js/wasm/pull/586))
- Fix rust version to 1.84 ([#587](https://github.com/polkadot-js/wasm/pull/587))
- Default to installed rust version ([#588](https://github.com/polkadot-js/wasm/pull/588))
- Default to nightly rust version ([#589](https://github.com/polkadot-js/wasm/pull/589))
- Ci Fix ([#590](https://github.com/polkadot-js/wasm/pull/590))
- Read lock file ([#591](https://github.com/polkadot-js/wasm/pull/591))
- Setup nightly as default ([#592](https://github.com/polkadot-js/wasm/pull/592))
- Tweak install-build-deps.sh script ([#593](https://github.com/polkadot-js/wasm/pull/593))
- Remove ASM build ([#594](https://github.com/polkadot-js/wasm/pull/594))
- Bump @polkadot deps ([#595](https://github.com/polkadot-js/wasm/pull/595))
## 7.4.1 Oct 20, 2024
- Bump dev deps to 0.81.2
- Bump TS
- Ensure CJS is exported correctly
- Bump yarn
- Add missing sideEffect declarations
- Set Deno build in CI to 1.42.x
## 7.3.2 Dec 6, 2023
Changes:
- Apply fixes for OOB array access
## 7.3.1 Nov 17, 2023
Changes:
- Drop support for Node 16 (EOL 11 Sep 2023)
## 7.2.2 Aug 17, 2023
Changes:
- Adjust cjs exports for consistency
- Adjust usage of `?.` as per (latest) linting rules
## 7.2.1 May 13, 2023
Changes:
- Adjust `cjs/bytes.js` generation to follow `export.<var> = ...` form
- Add `module` to `package.json` export map (ESM-only)
## 7.1.2 Apr 28, 2023
Changes:
- Apply `readonly` specifiers to private class fields where applicable
- Adjust compilation output for `__internal__` class fields
## 7.1.1 Apr 22, 2023
Changes:
- Add `wasm-util` as dependency where `x-randomvalues` is a peer
- Drop support for Node 14 (EOL 30 Apr 2023)
## 7.0.3 Mar 11, 2023
Changes:
- Use consistent `.js` imports in source files (TS moduleResolution)
## 7.0.2 Mar 4, 2023
Changes:
- Update to latest `@polkadot/dev` (w/ tsc jsx detection output changes)
## 7.0.1 Mar 4, 2023
Changes:
- Swap TS -> JS compiler to use tsc (from babel)
- Adjust all tests to use `node:test` runner (ESM & CJS variants)
## 6.4.1 Dec 3, 2022
Changes:
- Add `/*#__PURE__*/` annotations for specific `export const something = someFunction(...)`
## 6.3.1 Jul 21, 2022
Changes:
- Optimize packed WASM base64 decoding loop
- Adjust test environment (no duplication)
- Adjust CI check steps, align with other org repos
- Remove unneeded `import_map.in.json` for Deno tests
## 6.2.3 Jul 7, 2022
Changes:
- Optimize WASM init with pre-allocated buffers
- Additional platform-specific tests
## 6.2.2 Jul 4, 2022
Changes:
- Protect against potential low-level double-sign leak in dalek-ed25519 (Don't use provided input pubKey, see https://github.com/MystenLabs/ed25519-unsafe-libs)
## 6.2.1 Jul 1, 2022
Changes:
- Add missing `peerDependencies` to `wasm-crypto` (`bridge` requirement)
- Adjust `WebAssembly.{Memory, ModuleImports}` usage to cater for non-dom TS
## 6.1.5 Jun 23, 2022
Changes:
- Adjust build outputs for Deno targets
## 6.1.4 Jun 22, 2022
Changes:
- Adjust build outputs for Deno targets
## 6.1.3 Jun 21, 2022
Changes:
- Fix bundle publish (from dev bump)
## 6.1.2 Jun 21, 2022
Changes:
- Adjust assert usage in all internal non-test code
- Additional comments where missing
## 6.1.1 May 13, 2022
Changes:
- Adjust init, allow RN with default ASM.js-only fallback
- Split `wasm-{bridge, util}` packages for internal re-use
## 6.0.1 Apr 9, 2022
- **Breaking change** In this major version the commonjs outputs are moved to a sub-folder. Since the `export` map and `main` field in `package.json` does reflect this change, there should be no usage changes. However the packages here will all need to be on the same version for internal linkage.
Changes:
- Update ed25519 secret key format return description
- Output commonjs files under the `cjs/**` root
## 5.1.1 Mar 27, 2022
Changes:
- Swap from `libsecp256k1` to `secp256k1` (this aligns with the Substrate use)
- Adjust `wasm-crypto/init*` to also export `initWasm(): Promise<void>` (optional manual init)
- Allow for `wasm-crypto/initNone` with no defined Wasm or Asm interfaces
- Fix initialization on React Native with only ASM
## 5.0.1 Mar 19, 2022
- **Breaking change** For users of React Native, you are now required to add `import '@polkadot/wasm-crypto/initOnlyAsm'` at your project top-level to ensure that asm.js is initialized. (Or alternatively `import '@polkadot/wasm-crypto/initWasmAsm'` to future-proof when WASM does become available)
- **Breaking change** For users who used to map the `data` and `empty` of the internal `wasm-crypto-{wasm, asmjs}` packages in their bundlers, swap to one of the `@polkadot/wasm-crypto/init*` top-level imports to set the type of interfaces you would prefer. A full writeup of the rationale and other options can be found [in the FAQ](https://polkadot.js.org/docs/util-crypto/FAQ#i-dont-have-wasm-available-in-my-environment)
Changes:
- Add (optional) `@polkadot/wasm-crypto/init{OnlyAsm, OnlyWasm, WasmAsm}` to allow specific interface types
- Add work-around for lazy secp256k1 init in asm.js environments
- Optimize asm.js output size
- Use latest `wasm-bindgen`, `binaryen` & `wabt` packages in build
- Additional workaround for Vite bundling
## 4.6.1 Mar 12, 2022
Changes:
- Adjust ed25519 internals, consistency in code
- Ensure package path is available under ESM & CJS
- JS wrapped bytes interoperability test
- Adjust for bundlers where `import.meta.url` is undefined
## 4.5.1 Dec 3, 2021
Changes:
- Add `secp256k1{Compress, Expand, Recover, Sign}` functions
- Remove all occurences of `.unwrap()` (match everywhere)
- Adjust and optimize WASM function JS interface construction
- Simplify base64 bytes decoding on construction
## 4.4.1 Nov 22, 2021
Changes:
- Add `hmacSha256` & `hmacSha512` functions
## 4.3.1 Nov 19, 2021
Contributed:
- Updated package.json to include repo (Thanks to https://github.com/v-zhzhou)
Changes:
- Add `keccak512` function
- Add `sha256` function
## 4.2.1 Aug 28, 2021
Contributed:
- Add sr25519 agreement external (Thanks to https://github.com/shelvenzhou)
Changes:
- Adjust tests to align with JS coding standards
- Allow for optional build with Rust stable bootstrap
## 4.1.2 Jul 9, 2021
Changes:
- Bump `@polkadot/dev` to allow for bundles with new-format
## 4.1.1 Jul 7, 2021
Changes:
- Add an explicit `engines` field to `package.json`
- Allow building as a completely stand-alone browser bundle (experimental)
## 4.0.2 Mar 5, 2021
Changes:
- Add import indirection for both CJS & ESM (where generated source file is commonjs)
## 4.0.1 Mar 4, 2021
**Important** In the 4.0 version the default package type has been changed to ESM modules by default. This should not affect usage, however since the output formats changed, a new major version is required.
Changes:
- Build to ESM by default (with cjs versions via export map)
## 3.2.4 Feb 24, 2021
Changes:
- Cleanup implicit dependencies, perform base64 decoding using base64-js
## 3.2.3 Feb 16, 2021
Changes:
- Change package detect import to use `.js` source, not `.json`
## 3.2.2 Jan 24, 2021
Changes:
- Remove `module` field in `package.json`
## 3.2.1 Jan 22, 2021
Contributed:
- Expose sr25519 `ext_vrf_{sign, verify}` methods (Thanks to https://github.com/stiiifff)
Changes:
- Add explicit `.editorconfig` for Rust sources
- Remove unused code bundles (`vrf_{sign,verify}_extra`, `secp256k1` with tests)
- Test run wrapper cleanups
## 3.1.1 Dec 19, 2020
Changes:
- Single-instance package detection
- Adjust WASM inflate with localized methods
## 3.0.1 Dec 13, 2020
**Important** This assumes `@polkadot/util` 5+ peerDependencies
**Important** While this package contains no external interface changes, it doe now compile and ship both cjs and esm modules. This means that modern bundlers will have more information for tree-shaking available. Additionally when using Node with `.mjs` extensions, the esm version imports will be used on recent Node versions. Adding an export map, as here, may have some impacts so a major semver bump is advised. There may be (small) dragons hiding in the dark corners...
Changes:
- Build and expose both cjs and esm via exports map
- Split wasm and asmjs files into the `@polkadot/wasm-crypto-{wasm,asmjs}` packages
- Add fflate WASM compression, with 180K raw savings (37K over-the-wire)
- Convert the package to full TypeScript sources
## 2.0.1 Nov 8, 2020
Changes:
- Rework generation of WASM interfaces (proper cross-platform JS support)
- Remove explicit `crypto` dependency, this is now applied by `@polkadot/x-randomvalues`
- Build via xargo for panic abort, an overall small sizes without stack (Pinned nightly)
- Move Rust library sources in to `rs/` subfolder
## 1.4.1 Aug 27, 2020
Changes:
- Re-add the BTC/ETH compatible `bip39ToSeed` dropped in the previous version (ETH-compatible pairs)
## 1.3.1 Aug 9, 2020
Changes:
- Add `scrypt` function for KDF generation
- Remove `bip39ToSeed`, we only use the `bip39ToMiniSecret` variant in Substrate
- Update ed25519-dalek to 1.0.0-pre.4
- Rework generation based on latest wasm-pack generator
## 1.2.1 Feb 29, 2020
Changes:
- Adjust build process for smaller wasm bundle outputs (~50K dropped from base bundle)
- Unpin nightly from nightly-2020-02-17 version
- Swap to yarn 2 and add support for use by yarn 2 projects
## 1.1.1 Feb 24, 2020
- **Important** The sr25519 interface dropped the use of `verify_simple_preaudit_deprecated` for signature verification, instead it now uses `verify_simple`. Only schnorrkel 0.8+ signatures will now pass verification. This is a follow-up of the 0.1 signing support that was dropped in a previous version.
Changes:
- Rework schnorrkel signatures test vectors based on the above change (Rust, WASM and ASM.js tests)
- Rust nightly pinned to last-known-working 2020-02-17 on CI (compiler issues, should to be reverted in a future release)
## 1.0.1 Feb 15, 2020
Changes:
- No functionality changes from 0.20.1. The interfaces here are stable in the current iteration.
## 0.20.1 Jan 30, 2020
Changes:
- Pull in schnorrkel 0.8.5 for full Substrate 2.x compatibility
## 0.14.1 Sep 09, 2019
Changes:
- No functionality changes at all, everything done is "under the hood" to give the codebase better maintainability
## 0.13.1 Jul 20, 2019
Changes:
- Added an asm.js fallback which is active for React Native via the `"react-native"` entry in `package.json`. Ensure that you run the build step with the `NODE_OPTIONS=--max_old_space_size=8192` flags, since the asm.js bundle is large. (For RN the full command would therefore be `NODE_OPTIONS=--max_old_space_size=8192 npm start`)
## 0.12.1 Jul 17, 2019
Changes:
- Remove deprecated `@polkadot/wasm-schnorrkel` & `@polkadot/wasm-dalek-ed25519` source (all combined in `@polkadot/wasm-crypto`, was kept for historical purposes)
- Security dependency bumps
- Updated Rust `hex-literal` for recent versions of the compiler (used in tests only)
## 0.11.1 May 31, 2019
Changes:
- Security dependency bumps
## 0.10.1 May 09, 2019
Changes:
- w3f/schnorrkel updated to 0.1.1 as per substrate
- Added known subkey signature test (Rust & JS)
## 0.9.1 Apr 29, 2019
Changes:
- Dependency bumps
## 0.8.1 Mar 31, 2019
Changes:
- Pull ed25519 & sr25519 into `@polkadot/wasm-crypto` as well (smaller final size)
- Disable build/publish of `wasm-dalek-ed25519` & `wasm-schnorrkel`
- Improve error messaging, instead of `__wasm_malloc of null`
## 0.7.1 Mar 30, 2019
Changes:
- Fix build scripts to properly attach errors in the log (dropped in 0.6.1)
## 0.6.1 Mar 27, 2019
Changes:
- Log init errors for both non-WebAssembly usage as well as WebAssembly errors
## 0.5.1 Mar 23, 2019
Changes:
- Add password argument to bip39ToSeed
## 0.4.1 Mar 23, 2019
Changes:
- Add bip39ToSeed
## 0.3.1 Mar 23, 2019
Changes:
- Add wasm-dalek-ed25519 for all used crypto there
- Add keccak256
- Try secp256k1 (bloating code, not used atm)
## 0.2.1 Mar 20, 2019
Changes:
- Add basic crypto functions, creation of wasm-crypto package
- blake2, bip39, sha2, xxhash
## 0.1.1 Mar 18, 2019
Changes:
- Initial release
+45
View File
@@ -0,0 +1,45 @@
# Contributing
## What?
Individuals making significant and valuable contributions are given commit-access to a project to contribute as they see fit.
A project is more like an open wiki than a standard guarded open source project.
## Rules
There are a few basic ground-rules for contributors (including the maintainer(s) of the project):
1. **No `--force` pushes** or modifying the Git history in any way. If you need to rebase, ensure you do it in your own repo.
2. **Non-master branches**, prefixed with a short name moniker (e.g. `<initials>-<feature>`) must be used for ongoing work.
3. **All modifications** must be made in a **pull-request** to solicit feedback from other contributors.
4. A pull-request *must not be merged until CI* has finished successfully.
#### Merging pull requests once CI is successful:
- A pull request with no large change to logic that is an urgent fix may be merged after a non-author contributor has reviewed it well.
- No PR should be merged until all reviews' comments are addressed.
#### Reviewing pull requests:
When reviewing a pull request, the end-goal is to suggest useful changes to the author. Reviews should finish with approval unless there are issues that would result in:
- Buggy behaviour.
- Undue maintenance burden.
- Breaking with house coding style.
- Pessimisation (i.e. reduction of speed as measured in the projects benchmarks).
- Feature reduction (i.e. it removes some aspect of functionality that a significant minority of users rely on).
- Uselessness (i.e. it does not strictly add a feature or fix a known issue).
#### Reviews may not be used as an effective veto for a PR because:
- There exists a somewhat cleaner/better/faster way of accomplishing the same feature/fix.
- It does not fit well with some other contributors' longer-term vision for the project.
## Releases
Declaring formal releases remains the prerogative of the project maintainer(s).
## Changes to this arrangement
This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change.
## Heritage
These contributing guidelines are modified from the "OPEN Open Source Project" guidelines for the Level project: [https://github.com/Level/community/blob/master/CONTRIBUTING.md](https://github.com/Level/community/blob/master/CONTRIBUTING.md)
+8
View File
@@ -0,0 +1,8 @@
618 Jaco 2024 (#559)
19 Tarik Gul Bump dev to 0.83.2 (#578)
12 Valentin Fernandez 7.5.1 (#596)
10 rajk93 7.5.4 (#606)
1 Evgeny Fixed type (#121)
1 Shunfan Zhou Support sr25519 agreement (#209)
1 Steve Degosserie Expose Schnorrkel's VRF capabilities (#170)
1 Zhongpeng Zhou Update package.json to include the repository (#220)
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+17
View File
@@ -0,0 +1,17 @@
# @polkadot/wasm
Various WASM wrappers around Rust crates
## overview
It is split up into a number of internal packages, namely utilities -
- [wasm-crypto](packages/wasm-crypto/) Various hashing functions, sr25519 & ed25519 crypto
These are split from the `polkadot-js/util` repo where it is heavily used as part of `@polkadot/util-crypto`. (There JS fallbacks are available for some interfaces, e.g. hashing, but for sr25519 WASM is the only interface). Since these don't undergo massive changes on a daily basis and has a build overhead (WASM compilation & optimisation), it is better managed as a seperate repo with a specific CI configuration.
## development
Contributions are welcome!
To start off, this repo (along with others in the [@polkadot](https://github.com/polkadot-js/) 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.
View File
+12
View File
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=0.5, maximum-scale=1">
<meta http-equiv="refresh" content="0;URL='https://js.pezkuwichain.io/docs/'" />
<title>Redirecting to https://js.pezkuwichain.io/docs/</title>
</head>
<body>
Redirecting to <a href="https://js.pezkuwichain.io/docs/">https://js.pezkuwichain.io/docs/</a>
</body>
</html>
+12
View File
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=0.5, maximum-scale=1">
<meta http-equiv="refresh" content="0;URL='https://js.pezkuwichain.io/docs/'" />
<title>Redirecting to https://js.pezkuwichain.io/docs/</title>
</head>
<body>
Redirecting to <a href="https://js.pezkuwichain.io/docs/">https://js.pezkuwichain.io/docs/</a>
</body>
</html>
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2017-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import baseConfig from '@polkadot/dev/config/eslint';
export default [
...baseConfig,
{
ignores: [
'mod.ts'
]
}
];
+5
View File
@@ -0,0 +1,5 @@
{
"imports": {
"https://esm.sh/v90/@types/bn.js@~5.2/index.d.ts": "https://esm.sh/v90/@types/bn.js@5.1.0/index.d.ts"
}
}
+54
View File
@@ -0,0 +1,54 @@
{
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/pezkuwichain/pezkuwi-wasm/issues",
"engines": {
"node": ">=18.14"
},
"homepage": "https://github.com/pezkuwichain/pezkuwi-wasm#readme",
"license": "Apache-2.0",
"packageManager": "yarn@4.6.0",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/pezkuwichain/pezkuwi-wasm.git"
},
"sideEffects": false,
"type": "module",
"version": "7.5.5",
"versions": {
"git": "7.5.4",
"npm": "7.5.4"
},
"workspaces": [
"packages/*"
],
"scripts": {
"build": "yarn build:wasm",
"build:js": "./scripts/build-js.sh",
"build:release": "polkadot-ci-ghact-build",
"build:rollup": "polkadot-exec-rollup --config",
"build:wasm": "./scripts/build.sh",
"clean": "./scripts/clean.sh",
"deno": "yarn deno:build && yarn deno:check",
"deno:build": "WITH_DENO=1 yarn build",
"deno:check": "deno check --import-map=import_map.json mod.ts",
"lint": "polkadot-dev-run-lint",
"postinstall": "polkadot-dev-yarn-only",
"test": "yarn test:wasm-crypto:rust",
"test:js": "yarn test:wasm-crypto:js",
"test:wasm-crypto:deno": "deno test --allow-read --import-map=import_map.json packages/wasm-crypto/test/deno.ts",
"test:wasm-crypto:js": "yarn test:wasm-crypto:js:jest && yarn test:wasm-crypto:js:node",
"test:wasm-crypto:js:jest": "polkadot-dev-run-test --env node --loader ./packages/wasm-crypto/test/loader-build.js",
"test:wasm-crypto:js:node": "node --no-warnings --loader ./packages/wasm-crypto/test/loader-build.js ./packages/wasm-crypto/test/wasm.js && node --no-warnings --loader ./packages/wasm-crypto/test/loader-build.js ./packages/wasm-crypto/test/asm.js",
"test:wasm-crypto:rust": "cd packages/wasm-crypto && RUST_BACKTRACE=full cargo test --release -- --test-threads=1 --nocapture"
},
"devDependencies": {
"@pezkuwi/util": "^14.0.1",
"@polkadot/dev": "^0.83.3",
"@types/node": "^20.16.1",
"fflate": "^0.8.2"
},
"resolutions": {
"typescript": "^5.5.4"
}
}
+3
View File
@@ -0,0 +1,3 @@
# @polkadot/wasm-bridge
A re-usable bridge between JS & WASM interfaces. It is used internally by `@polkadot/wasm-crypto`.
+35
View File
@@ -0,0 +1,35 @@
{
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/pezkuwichain/pezkuwi-wasm/issues",
"description": "A bridge layer between JS and Wasm",
"engines": {
"node": ">=18"
},
"homepage": "https://github.com/pezkuwichain/pezkuwi-wasm/tree/master/packages/wasm-bridge#readme",
"license": "Apache-2.0",
"name": "@pezkuwi/wasm-bridge",
"repository": {
"directory": "packages/wasm-bridge",
"type": "git",
"url": "https://github.com/pezkuwichain/pezkuwi-wasm.git"
},
"sideEffects": [
"./packageDetect.js",
"./packageDetect.cjs"
],
"type": "module",
"version": "7.5.5",
"main": "index.js",
"dependencies": {
"@pezkuwi/wasm-util": "7.5.5",
"tslib": "^2.7.0"
},
"devDependencies": {
"@pezkuwi/util": "^14.0.1",
"@pezkuwi/x-randomvalues": "^14.0.1"
},
"peerDependencies": {
"@pezkuwi/util": "*",
"@pezkuwi/x-randomvalues": "*"
}
}
+214
View File
@@ -0,0 +1,214 @@
// Copyright 2019-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
// A number of functions are "unsafe" and purposefully so - it is
// assumed that where the bridge is used, it is correctly wrapped
// in a safeguard (see withWasm in the wasm-crypto package) which
// then ensures that the internal wasm instance here is available
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { BridgeBase, InitFn, InitPromise, WasmBaseInstance, WasmImports } from './types.js';
import { stringToU8a, u8aToString } from '@pezkuwi/util';
import { Wbg } from './wbg.js';
/**
* @name Bridge
* @description
* Creates a bridge between the JS and WASM environments.
*
* For any bridge it is passed an function which is then called internally at the
* time of initialization. This affectively implements the layer between WASM and
* the native environment, providing all the plumbing needed for the Wbg classes.
*/
export class Bridge<C extends WasmBaseInstance> implements BridgeBase<C> {
readonly #createWasm: InitFn<C>;
readonly #heap: unknown[];
readonly #wbg: WasmImports;
#cachegetInt32: Int32Array | null;
#cachegetUint8: Uint8Array | null;
#heapNext: number;
#wasm: C | null;
#wasmError: string | null;
#wasmPromise: InitPromise<C> | null;
#type: 'asm' | 'wasm' | 'none';
constructor (createWasm: InitFn<C>) {
this.#createWasm = createWasm;
this.#cachegetInt32 = null;
this.#cachegetUint8 = null;
this.#heap = new Array(32)
.fill(undefined)
.concat(undefined, null, true, false);
this.#heapNext = this.#heap.length;
this.#type = 'none';
this.#wasm = null;
this.#wasmError = null;
this.#wasmPromise = null;
this.#wbg = { ...new Wbg(this) };
}
/** @description Returns the init error */
get error (): string | null {
return this.#wasmError;
}
/** @description Returns the init type */
get type (): 'asm' | 'wasm' | 'none' {
return this.#type;
}
/** @description Returns the created wasm interface */
get wasm (): C | null {
return this.#wasm;
}
/** @description Performs the wasm initialization */
async init (createWasm?: InitFn<C>): Promise<C | null> {
if (!this.#wasmPromise || createWasm) {
this.#wasmPromise = (createWasm || this.#createWasm)(this.#wbg);
}
const { error, type, wasm } = await this.#wasmPromise;
this.#type = type;
this.#wasm = wasm;
this.#wasmError = error;
return this.#wasm;
}
/**
* @internal
* @description Gets an object from the heap
*/
getObject (idx: number): unknown {
return this.#heap[idx];
}
/**
* @internal
* @description Removes an object from the heap
*/
dropObject (idx: number) {
if (idx < 36) {
return;
}
this.#heap[idx] = this.#heapNext;
this.#heapNext = idx;
}
/**
* @internal
* @description Retrieves and removes an object to the heap
*/
takeObject (idx: number): unknown {
const ret = this.getObject(idx);
this.dropObject(idx);
return ret;
}
/**
* @internal
* @description Adds an object to the heap
*/
addObject (obj: unknown): number {
if (this.#heapNext === this.#heap.length) {
this.#heap.push(this.#heap.length + 1);
}
const idx = this.#heapNext;
this.#heapNext = this.#heap[idx] as number;
this.#heap[idx] = obj;
return idx;
}
/**
* @internal
* @description Retrieve an Int32 in the WASM interface
*/
getInt32 (): Int32Array {
if (this.#cachegetInt32 === null || this.#cachegetInt32.buffer !== this.#wasm!.memory.buffer) {
this.#cachegetInt32 = new Int32Array(this.#wasm!.memory.buffer);
}
return this.#cachegetInt32;
}
/**
* @internal
* @description Retrieve an Uint8Array in the WASM interface
*/
getUint8 (): Uint8Array {
if (this.#cachegetUint8 === null || this.#cachegetUint8.buffer !== this.#wasm!.memory.buffer) {
this.#cachegetUint8 = new Uint8Array(this.#wasm!.memory.buffer);
}
return this.#cachegetUint8;
}
/**
* @internal
* @description Retrieves an Uint8Array in the WASM interface
*/
getU8a (ptr: number, len: number): Uint8Array {
return this.getUint8().subarray(ptr / 1, ptr / 1 + len);
}
/**
* @internal
* @description Retrieves a string in the WASM interface
*/
getString (ptr: number, len: number): string {
return u8aToString(this.getU8a(ptr, len));
}
/**
* @internal
* @description Allocates an Uint8Array in the WASM interface
*/
allocU8a (arg: Uint8Array): [number, number] {
const ptr = this.#wasm!.__wbindgen_malloc(arg.length * 1);
this.getUint8().set(arg, ptr / 1);
return [ptr, arg.length];
}
/**
* @internal
* @description Allocates a string in the WASM interface
*/
allocString (arg: string): [number, number] {
return this.allocU8a(stringToU8a(arg));
}
/**
* @internal
* @description Retrieves an Uint8Array from the WASM interface
*/
resultU8a (): Uint8Array {
const r0 = this.getInt32()[8 / 4 + 0];
const r1 = this.getInt32()[8 / 4 + 1];
const ret = this.getU8a(r0, r1).slice();
this.#wasm!.__wbindgen_free(r0, r1 * 1);
return ret;
}
/**
* @internal
* @description Retrieve a string from the WASM interface
*/
resultString (): string {
return u8aToString(this.resultU8a());
}
}
+5
View File
@@ -0,0 +1,5 @@
// Copyright 2019-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
export * from './bridge.js';
export * from './init.js';
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2019-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
import './packageDetect.js';
export * from './bundle.js';
+47
View File
@@ -0,0 +1,47 @@
// Copyright 2019-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { InitFn, InitPromise, InitResult, WasmBaseInstance, WasmImports } from './types.js';
/**
* @name createWasmFn
* @description
* Create a WASM (or ASM.js) creator interface based on the supplied information.
*
* It will attempt to create a WASM interface first and if this fails or is not available in
* the environment, will fallback to attempting to create an ASM.js interface.
*/
export function createWasmFn <C extends WasmBaseInstance> (root: 'crypto', wasmBytes: null | Uint8Array, asmFn: null | ((wbg: WasmImports) => C)): InitFn<C> {
return async (wbg: WasmImports): InitPromise<C> => {
const result: InitResult<C> = {
error: null,
type: 'none',
wasm: null
};
try {
if (!wasmBytes?.length) {
throw new Error('No WebAssembly provided for initialization');
} else if (typeof WebAssembly !== 'object' || typeof WebAssembly.instantiate !== 'function') {
throw new Error('WebAssembly is not available in your environment');
}
const source = await WebAssembly.instantiate(wasmBytes, { wbg });
result.wasm = source.instance.exports as unknown as C;
result.type = 'wasm';
} catch (error) {
// if we have a valid supplied asm.js, return that
if (typeof asmFn === 'function') {
result.wasm = asmFn(wbg);
result.type = 'asm';
} else {
result.error = `FATAL: Unable to initialize @pezkuwi/wasm-${root}:: ${(error as Error).message}`;
console.error(result.error);
}
}
return result;
};
}
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2019-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
export * from './index.js';
+11
View File
@@ -0,0 +1,11 @@
// Copyright 2017-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @polkadot/dev
// (packageInfo imports will be kept as-is, user-editable)
import { detectPackage } from '@pezkuwi/util';
import { packageInfo } from './packageInfo.js';
detectPackage(packageInfo, null, []);
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2017-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @polkadot/dev
export const packageInfo = { name: '@pezkuwi/wasm-bridge', path: 'auto', type: 'auto', version: '7.5.4' };
+47
View File
@@ -0,0 +1,47 @@
// Copyright 2019-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Use non-strong types instead of WasmImports which may not
// be available as part of the TS environment types (it needs dom)
export type WasmImports = Record<string, (...args: never[]) => unknown>;
// Use non-strong types instead of WebAssembly.Memory which may not
// be available as part of the TS environment types (it needs dom)
export interface WasmMemory { buffer: ArrayBuffer }
export declare interface InitResult<C extends WasmBaseInstance> {
error: string | null;
type: 'asm' | 'wasm' | 'none';
wasm: C | null;
}
export type InitPromise <C extends WasmBaseInstance> = Promise<InitResult<C>>;
export type InitFn <C extends WasmBaseInstance> = (wbg: WasmImports) => InitPromise<C>;
export interface BridgeBase<C extends WasmBaseInstance> extends InitResult<C> {
init (createWasm?: InitFn<C>): Promise<C | null>;
getObject (idx: number): unknown;
dropObject (idx: number): void;
takeObject (idx: number): unknown;
addObject (obj: unknown): number;
getInt32 (): Int32Array;
getUint8 (): Uint8Array;
getU8a (ptr: number, len: number): Uint8Array;
getString (ptr: number, len: number): string;
allocU8a (arg: Uint8Array): [number, number];
allocString (arg: string): [number, number];
resultU8a (): Uint8Array;
resultString (): string;
}
export interface WasmBindGen {
__wbindgen_exn_store (a: number): void;
__wbindgen_free (a: number, b: number): void;
__wbindgen_malloc (a: number): number;
__wbindgen_realloc (a: number, b: number, c: number): number;
}
export interface WasmBaseInstance extends WasmBindGen {
memory: WasmMemory;
}
+158
View File
@@ -0,0 +1,158 @@
// Copyright 2019-2025 @pezkuwi/wasm-bridge authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { BridgeBase, WasmBaseInstance } from './types.js';
import { getRandomValues } from '@pezkuwi/x-randomvalues';
const DEFAULT_CRYPTO = { getRandomValues };
const DEFAULT_SELF = { crypto: DEFAULT_CRYPTO };
/**
* @name Wbg
* @description
* This defines the internal interfaces that wasm-bindgen used to communicate
* with the host layer. None of these functions are available to the user, rather
* they are called internally from the WASM code itself.
*
* The interfaces here are exposed in the imports on the created WASM interfaces.
*
* Internally the implementation does a thin layer into the supplied bridge.
*/
export class Wbg<C extends WasmBaseInstance> {
readonly #bridge: BridgeBase<C>;
constructor (bridge: BridgeBase<C>) {
this.#bridge = bridge;
}
/** @internal */
abort = (): never => {
throw new Error('abort');
};
/** @internal - new hash */
__wbg___wbindgen_is_undefined_9e4d92534c42d778 = (idx: number): boolean => {
return this.#bridge.getObject(idx) === undefined;
};
/** @internal - old hash for compatibility */
__wbindgen_is_undefined = (idx: number): boolean => {
return this.#bridge.getObject(idx) === undefined;
};
/** @internal - new hash */
__wbg___wbindgen_throw_be289d5034ed271b = (ptr: number, len: number): never => {
throw new Error(this.#bridge.getString(ptr, len));
};
/** @internal - old hash for compatibility */
__wbindgen_throw = (ptr: number, len: number): never => {
throw new Error(this.#bridge.getString(ptr, len));
};
/** @internal - new hash */
__wbg_self_25aabeb5a7b41685 = (): number => {
return this.#bridge.addObject(DEFAULT_SELF);
};
/** @internal - old hash for compatibility */
__wbg_self_1b7a39e3a92c949c = (): number => {
return this.#bridge.addObject(DEFAULT_SELF);
};
/** @internal - new hash */
__wbg_require_0d6aeaec3c042c88 = (ptr: number, len: number, _extra: number): never => {
throw new Error(`Unable to require ${this.#bridge.getString(ptr, len)}`);
};
/** @internal - old hash for compatibility */
__wbg_require_604837428532a733 = (ptr: number, len: number): never => {
throw new Error(`Unable to require ${this.#bridge.getString(ptr, len)}`);
};
/** @internal - new hash */
__wbg_crypto_038798f665f985e2 = (_idx: number): number => {
return this.#bridge.addObject(DEFAULT_CRYPTO);
};
/** @internal - old hash for compatibility */
__wbg_crypto_968f1772287e2df0 = (_idx: number): number => {
return this.#bridge.addObject(DEFAULT_CRYPTO);
};
/** @internal - new hash */
__wbg_msCrypto_ff35fce085fab2a3 = (_idx: number): number => {
// msCrypto for IE11, return undefined/null
return this.#bridge.addObject(undefined);
};
/** @internal - new hash */
__wbg_getRandomValues_7dfe5bd1b67c9ca1 = (_idx: number): number => {
return this.#bridge.addObject(DEFAULT_CRYPTO.getRandomValues);
};
/** @internal - old hash for compatibility */
__wbg_getRandomValues_a3d34b4fee3c2869 = (_idx: number): number => {
return this.#bridge.addObject(DEFAULT_CRYPTO.getRandomValues);
};
/** @internal - new hash */
__wbg_getRandomValues_371e7ade8bd92088 = (_arg0: number, ptr: number, len: number): void => {
DEFAULT_CRYPTO.getRandomValues(this.#bridge.getU8a(ptr, len));
};
/** @internal - old hash for compatibility */
__wbg_getRandomValues_f5e14ab7ac8e995d = (_arg0: number, ptr: number, len: number): void => {
DEFAULT_CRYPTO.getRandomValues(this.#bridge.getU8a(ptr, len));
};
/** @internal - new hash */
__wbg_randomFillSync_994ac6d9ade7a695 = (_idx: number, _ptr: number, _len: number): never => {
throw new Error('randomFillSync is not available');
};
/** @internal - old hash for compatibility */
__wbg_randomFillSync_d5bd2d655fdf256a = (_idx: number, _ptr: number, _len: number): never => {
throw new Error('randomFillSync is not available');
};
/** @internal */
__wbindgen_object_drop_ref = (idx: number): void => {
this.#bridge.takeObject(idx);
};
/** @internal - new: static accessor for MODULE */
__wbg_static_accessor_MODULE_ef3aa2eb251158a5 = (): number => {
return this.#bridge.addObject(undefined);
};
/** @internal - new: Uint8Array.new_with_length */
__wbg_new_with_length_a2c39cbe88fd8ff1 = (len: number): number => {
return this.#bridge.addObject(new Uint8Array(len));
};
/** @internal - new: Uint8Array.subarray */
__wbg_subarray_a96e1fef17ed23cb = (idx: number, start: number, end: number): number => {
const arr = this.#bridge.getObject(idx) as Uint8Array;
return this.#bridge.addObject(arr.subarray(start, end));
};
/** @internal - new: Uint8Array.length */
__wbg_length_32ed9a279acd054c = (idx: number): number => {
const arr = this.#bridge.getObject(idx) as Uint8Array;
return arr.length;
};
/** @internal - new: Uint8Array.prototype.set.call */
__wbg_prototypesetcall_bdcdcc5842e4d77d = (destIdx: number, srcIdx: number, offset: number): void => {
const dest = this.#bridge.getObject(destIdx) as Uint8Array;
const src = this.#bridge.getObject(srcIdx) as Uint8Array;
dest.set(src, offset);
};
/** @internal - new: init externref table */
__wbindgen_init_externref_table = (): void => {
// No-op, externref table is initialized by the runtime
};
}
+12
View File
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": "..",
"outDir": "./build",
"rootDir": "./src"
},
"exclude": [
"**/mod.ts"
],
"references": []
}
+3
View File
@@ -0,0 +1,3 @@
## @polkadot/wasm-crypto-asmjs
Asm.js build outputs.
+32
View File
@@ -0,0 +1,32 @@
{
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/pezkuwichain/pezkuwi-wasm/issues",
"description": "Asm.js content for wasm-crypto",
"engines": {
"node": ">=18"
},
"homepage": "https://github.com/pezkuwichain/pezkuwi-wasm/tree/master/packages/wasm-crypto-asmjs#readme",
"license": "Apache-2.0",
"name": "@pezkuwi/wasm-crypto-asmjs",
"repository": {
"directory": "packages/wasm-crypto-asmjs",
"type": "git",
"url": "https://github.com/pezkuwichain/pezkuwi-wasm.git"
},
"sideEffects": [
"./packageDetect.js",
"./packageDetect.cjs"
],
"type": "module",
"version": "7.5.5",
"main": "index.js",
"dependencies": {
"tslib": "^2.7.0"
},
"devDependencies": {
"@pezkuwi/util": "^14.0.1"
},
"peerDependencies": {
"@pezkuwi/util": "*"
}
}
+5
View File
@@ -0,0 +1,5 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { asmJsInit } from './cjs/data.js';
export { packageInfo } from './packageInfo.js';
@@ -0,0 +1,6 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
const data = require('../data.js');
module.exports = data;
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
export declare const asmJsInit: null;
@@ -0,0 +1,6 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
const asmJsInit = null;
exports.asmJsInit = asmJsInit;
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
export declare const asmJsInit: null;
@@ -0,0 +1,4 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
export const asmJsInit = null;
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
import './packageDetect.js';
export * from './bundle.js';
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
export * from './index.js';
@@ -0,0 +1,11 @@
// Copyright 2017-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @polkadot/dev
// (packageInfo imports will be kept as-is, user-editable)
import { detectPackage } from '@pezkuwi/util';
import { packageInfo } from './packageInfo.js';
detectPackage(packageInfo, null, []);
@@ -0,0 +1,6 @@
// Copyright 2017-2025 @pezkuwi/wasm-crypto-asmjs authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @polkadot/dev
export const packageInfo = { name: '@pezkuwi/wasm-crypto-asmjs', path: 'auto', type: 'auto', version: '7.5.4' };
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": "..",
"outDir": "./build",
"rootDir": "./src"
},
"exclude": [
"**/mod.ts"
],
"references": []
}
+3
View File
@@ -0,0 +1,3 @@
## @polkadot/wasm-crypto-init
Internal `@polkadot/wasm-crypto` initialization functions for Browser, Node & RN.
+40
View File
@@ -0,0 +1,40 @@
{
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/pezkuwichain/pezkuwi-wasm/issues",
"description": "Init handlers for wasm-crypto",
"engines": {
"node": ">=18"
},
"homepage": "https://github.com/pezkuwichain/pezkuwi-wasm/tree/master/packages/wasm-crypto-init#readme",
"license": "Apache-2.0",
"name": "@pezkuwi/wasm-crypto-init",
"repository": {
"directory": "packages/wasm-crypto-init",
"type": "git",
"url": "https://github.com/pezkuwichain/pezkuwi-wasm.git"
},
"sideEffects": [
"./packageDetect.js",
"./packageDetect.cjs"
],
"type": "module",
"version": "7.5.5",
"browser": "wasm.js",
"main": "wasm.js",
"react-native": "asm.js",
"dependencies": {
"@pezkuwi/wasm-bridge": "7.5.5",
"@pezkuwi/wasm-crypto-asmjs": "7.5.5",
"@pezkuwi/wasm-crypto-wasm": "7.5.5",
"@pezkuwi/wasm-util": "7.5.5",
"tslib": "^2.7.0"
},
"devDependencies": {
"@pezkuwi/util": "^14.0.1",
"@pezkuwi/x-randomvalues": "^14.0.1"
},
"peerDependencies": {
"@pezkuwi/util": "*",
"@pezkuwi/x-randomvalues": "*"
}
}
+17
View File
@@ -0,0 +1,17 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { InitFn } from '@pezkuwi/wasm-bridge/types';
import type { WasmCryptoInstance } from './types.js';
import { createWasmFn } from '@pezkuwi/wasm-bridge';
import { asmJsInit } from '@pezkuwi/wasm-crypto-asmjs';
export { packageInfo } from './packageInfo.js';
/**
* @name createWasm
* @description
* Creates an interface using only ASM.js
*/
export const createWasm: InitFn<WasmCryptoInstance> = /*#__PURE__*/ createWasmFn('crypto', null, asmJsInit);
+18
View File
@@ -0,0 +1,18 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { InitFn } from '@pezkuwi/wasm-bridge/types';
import type { WasmCryptoInstance } from './types.js';
import { createWasmFn } from '@pezkuwi/wasm-bridge';
import { asmJsInit } from '@pezkuwi/wasm-crypto-asmjs';
import { wasmBytes } from '@pezkuwi/wasm-crypto-wasm';
export { packageInfo } from './packageInfo.js';
/**
* @name createWasm
* @description
* Creates an interface using WASM and a fallback ASM.js
*/
export const createWasm: InitFn<WasmCryptoInstance> = /*#__PURE__*/ createWasmFn('crypto', wasmBytes, asmJsInit);
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
export * from './wasm.js';
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
export * from './wasm.js';
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { InitFn } from '@pezkuwi/wasm-bridge/types';
import type { WasmCryptoInstance } from './types.js';
import { createWasmFn } from '@pezkuwi/wasm-bridge';
export { packageInfo } from './packageInfo.js';
/**
* @name createWasm
* @description
* Creates an interface using no WASM and no ASM.js
*/
export const createWasm: InitFn<WasmCryptoInstance> = /*#__PURE__*/ createWasmFn('crypto', null, null);
@@ -0,0 +1,14 @@
// Copyright 2017-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @polkadot/dev
// (packageInfo imports will be kept as-is, user-editable)
import { detectPackage } from '@pezkuwi/util';
import { packageInfo as bridgeInfo } from '@pezkuwi/wasm-bridge/packageInfo';
import { packageInfo as asmInfo } from '@pezkuwi/wasm-crypto-asmjs/packageInfo';
import { packageInfo as wasmInfo } from '@pezkuwi/wasm-crypto-wasm/packageInfo';
import { packageInfo } from './packageInfo.js';
detectPackage(packageInfo, null, [asmInfo, bridgeInfo, wasmInfo]);
@@ -0,0 +1,6 @@
// Copyright 2017-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @polkadot/dev
export const packageInfo = { name: '@pezkuwi/wasm-crypto-init', path: 'auto', type: 'auto', version: '7.5.4' };
+75
View File
@@ -0,0 +1,75 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { WasmBaseInstance } from '@pezkuwi/wasm-bridge/types';
/* eslint-disable camelcase */
// wasm-pack build output (formatted) from pkg/wasm_bg.d.ts
export interface WasmCryptoInstance extends WasmBaseInstance {
// exposed functions
ext_bip39_generate(resLen: 8, words: number): void;
ext_bip39_to_entropy(resLen: 8, ptrPhrase: number, lenPhrase: number): void;
ext_bip39_to_mini_secret(resLen: 8, ptrPhrase: number, lenPhrase: number, ptrPass: number, lenPass: number): void;
ext_bip39_to_seed(resLen: 8, ptrPhrase: number, lenPhrase: number, ptrPass: number, lenPass: number): void;
ext_bip39_validate(ptrPhrase: number, lenPhrase: number): number;
ext_ed_from_seed(resLen: 8, ptrSeed: number, lenSeed: number): void;
ext_ed_sign(resLen: 8, ptrPub: number, lenPub: number, ptrSec: number, lenSec: number, ptrMsg: number, lenMsg: number): void;
ext_ed_verify(ptrSig: number, lenSig: number, ptrMsg: number, lenMsg: number, ptrPub: number, lenPub: number): number;
ext_blake2b(resLen: 8, ptrData: number, lenData: number, ptrKey: number, lenKey: number, size: number): void;
ext_hmac_sha256(resLen: 8, ptrKey: number, lenKey: number, ptrData: number, lenData: number): void;
ext_hmac_sha512(resLen: 8, ptrKey: number, lenKey: number, ptrData: number, lenData: number): void;
ext_keccak256(resLen: 8, ptrData: number, lenData: number): void;
ext_keccak512(resLen: 8, ptrData: number, lenData: number): void;
ext_pbkdf2(resLen: 8, ptrData: number, lenData: number, ptrSalt: number, lenSalt: number, rounds: number): void;
ext_scrypt(resLen: 8, ptrPass: number, lenPass: number, ptrSalt: number, lenSalt: number, log2n: number, r: number, p: number): void;
ext_sha256(resLen: 8, ptrData: number, lenData: number): void;
ext_sha512(resLen: 8, ptrData: number, lenData: number): void;
ext_twox(resLen: 8, ptrData: number, lenData: number, rounds: number): void;
ext_secp_from_seed(reslen: 8, ptrSec: number, lenSec: number): void;
ext_secp_pub_compress(resLen: 8, ptrPub: number, lenPub: number): void;
ext_secp_pub_expand(resLen: 8, ptrPub: number, lenPub: number): void;
ext_secp_recover(resLen: 8, ptrMsgHash: number, lenMsgHash: number, ptrSig: number, lenSig: number, recovery: number): void;
ext_secp_sign(resLen: 8, ptrMsgHash: number, lenMsgHash: number, ptrSec: number, lenSec: number): void;
ext_sr_derive_keypair_hard(resLen: 8, ptrPair: number, lenPair: number, ptrCc: number, lenCc: number): void;
ext_sr_derive_keypair_soft(resLen: 8, ptrPub: number, lenPub: number, ptrCc: number, lenCc: number): void;
ext_sr_derive_public_soft(resLen: 8, ptrPub: number, lenPub: number, ptrCc: number, lenCc: number): void;
ext_sr_from_seed(resLen: 8, ptrSeed: number, lenSeed: number): void;
ext_sr_sign(resLen: 8, ptrPub: number, lenPub: number, ptrSec: number, lenSec: number, ptrMsg: number, lenMsg: number): void;
ext_sr_verify(ptrSig: number, lenSig: number, ptrMsg: number, lenMsg: number, ptrPub: number, lenPub: number): number;
ext_sr_agree(resLen: 8, ptrPub: number, lenPub: number, ptrSec: number, lenSec: number): void;
ext_vrf_sign(resLen: 8, ptrSec: number, lenSec: number, ptrCtx: number, lenCtx: number, ptrMsg: number, lenMsg: number, ptrExtra: number, lenExtra: number): void;
ext_vrf_verify(ptrPub: number, lenPub: number, ptrCtx: number, lenCtx: number, ptrMsg: number, lenMsg: number, ptrExtra: number, lenExtra: number, ptrProof: number, lenProof: number): number;
}
+17
View File
@@ -0,0 +1,17 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-init authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { InitFn } from '@pezkuwi/wasm-bridge/types';
import type { WasmCryptoInstance } from './types.js';
import { createWasmFn } from '@pezkuwi/wasm-bridge';
import { wasmBytes } from '@pezkuwi/wasm-crypto-wasm';
export { packageInfo } from './packageInfo.js';
/**
* @name createWasm
* @description
* Creates an interface using only WASM
*/
export const createWasm: InitFn<WasmCryptoInstance> = /*#__PURE__*/ createWasmFn('crypto', wasmBytes, null);
@@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": "..",
"outDir": "./build",
"rootDir": "./src"
},
"exclude": [
"**/mod.ts"
],
"references": [
{ "path": "../wasm-bridge/tsconfig.build.json" },
{ "path": "../wasm-crypto-asmjs/tsconfig.build.json" },
{ "path": "../wasm-crypto-wasm/tsconfig.build.json" }
]
}
+3
View File
@@ -0,0 +1,3 @@
## @polkadot/wasm-crypto-wasm
Wasm build outputs.
+33
View File
@@ -0,0 +1,33 @@
{
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/pezkuwichain/pezkuwi-wasm/issues",
"description": "Wasm content for wasm-crypto",
"engines": {
"node": ">=18"
},
"homepage": "https://github.com/pezkuwichain/pezkuwi-wasm/tree/master/packages/wasm-crypto-wasm#readme",
"license": "Apache-2.0",
"name": "@pezkuwi/wasm-crypto-wasm",
"repository": {
"directory": "packages/wasm-crypto-wasm",
"type": "git",
"url": "https://github.com/pezkuwichain/pezkuwi-wasm.git"
},
"sideEffects": [
"./packageDetect.js",
"./packageDetect.cjs"
],
"type": "module",
"version": "7.5.5",
"main": "index.js",
"dependencies": {
"@pezkuwi/wasm-util": "7.5.5",
"tslib": "^2.7.0"
},
"devDependencies": {
"@pezkuwi/util": "^14.0.1"
},
"peerDependencies": {
"@pezkuwi/util": "*"
}
}
+19
View File
@@ -0,0 +1,19 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { base64Decode, unzlibSync } from '@pezkuwi/wasm-util';
import { bytes, lenIn, lenOut } from './cjs/bytes.js';
export { packageInfo } from './packageInfo.js';
/**
* @name wasmBytes
* @description
* The decoded WASM interface as exposed by this package.
*
* The build process will output into cjs/* into a compressed base64 format.
* Upon loading the exposed bytes will be decoded and decompressed from this
* specific format and returned.
*/
export const wasmBytes = /*#__PURE__*/ unzlibSync(base64Decode(bytes, new Uint8Array(lenIn)), new Uint8Array(lenOut));
+8
View File
@@ -0,0 +1,8 @@
// Copyright 2019-2026 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
export declare const bytes: string;
export declare const lenIn: number;
export declare const lenOut: number;
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
// Copyright 2019-2026 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
const bytes = require('../bytes.js');
module.exports = bytes;
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
+8
View File
@@ -0,0 +1,8 @@
// Copyright 2019-2026 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
export declare const bytes: string;
export declare const lenIn: number;
export declare const lenOut: number;
File diff suppressed because one or more lines are too long
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2019-2026 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
import './packageDetect.js';
export * from './bundle.js';
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2019-2026 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
export * from './index.js';
@@ -0,0 +1,11 @@
// Copyright 2017-2026 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @pezkuwi/dev
// (packageInfo imports will be kept as-is, user-editable)
import { detectPackage } from '@pezkuwi/util';
import { packageInfo } from './packageInfo.js';
detectPackage(packageInfo, null, []);
@@ -0,0 +1,6 @@
// Copyright 2017-2025 @pezkuwi/wasm-crypto-wasm authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @pezkuwi/dev
export const packageInfo = { name: '@pezkuwi/wasm-crypto-wasm', path: 'auto', type: 'auto', version: '7.5.4' };
@@ -0,0 +1,14 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": "..",
"outDir": "./build",
"rootDir": "./src"
},
"exclude": [
"**/mod.ts"
],
"references": [
{ "path": "../wasm-util/tsconfig.build.json" }
]
}
+1027
View File
File diff suppressed because it is too large Load Diff
+50
View File
@@ -0,0 +1,50 @@
# name & version is only used internally, doesn't need to be adjusted. In the case of
# name keep it consistent at "wasm" since the scripts (for re-use purposes) expect that
[package]
authors = ["Jaco Greeff <jacogr@gmail.com>"]
description = "WASM bindings to Rust crypto libraries."
edition = "2018"
license = "Apache-2.0"
name = "wasm"
publish = false
repository = "https://github.com/pezkuwichain/pezkuwi-wasm/"
resolver = "2"
version = "0.0.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
blake2-rfc = "0.2.18"
byteorder = "1.3.1"
curve25519-dalek = { version = "2.1.0", default-features = false }
ed25519-dalek = { version = "1.0.0-pre.4", features = [] }
getrandom = { version="0.2.3", features = ["js"] }
hmac = "0.7.0"
secp256k1 = { version = "0.21.2", default-features = false, features = ["recovery", "global-context"] }
merlin = { version = "2.0", default-features = false }
pbkdf2 = { version = "0.3.0", default-features = false }
rand = { version="0.7.3", default-features = false, features = ["wasm-bindgen"] }
schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"] }
scrypt = { version = "0.2", default-features = false }
sha2 = "0.8.1"
tiny-bip39 = { version = "0.7", default-features = false }
tiny-keccak = { version = "2.0.1", features = ["keccak"] }
twox-hash = "1.5.0"
wasm-bindgen = "=0.2.90"
wee_alloc = "0.4.3"
[dev-dependencies]
hex-literal = "0.2.0"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
[profile.release]
codegen-units = 1
debug = false
debug-assertions = false
incremental = false
lto = true
opt-level = "z"
panic = "abort"
rpath = false
+29
View File
@@ -0,0 +1,29 @@
# @polkadot/wasm-crypto
Wrapper around crypto hashing functions
## Usage
Install the package (also requires `@polkadot/util` for `TextEncoder` polyfills - not included here as a dependency to keep the tree lean)
`yarn add @polkadot/wasm-crypto @polkadot/util`
Use it -
```js
import { u8aToHex } from '@polkadot/util';
import { bip39Generate, bip39ToSeed, waitReady } from '@polkadot/wasm-crypto';
// first wait until the WASM has been loaded (async init)
await waitReady();
// generate phrase
const phrase = bip39Generate(12);
// get ed25519 seed from phrase
const seed = bip39ToSeed(phrase, '');
// display
console.log('phrase:', phrase);
console.log('seed:', u8aToHex(seed));
```
+2
View File
@@ -0,0 +1,2 @@
[dependencies]
std = { default-features = false, features = ["panic_immediate_abort"] }
+47
View File
@@ -0,0 +1,47 @@
{
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/pezkuwichain/pezkuwi-wasm/issues",
"description": "A wasm interface layer for use by @pezkuwi/util-crypto",
"engines": {
"node": ">=18"
},
"homepage": "https://github.com/pezkuwichain/pezkuwi-wasm/tree/master/packages/wasm-crypto#readme",
"license": "Apache-2.0",
"name": "@pezkuwi/wasm-crypto",
"repository": {
"directory": "packages/wasm-crypto",
"type": "git",
"url": "https://github.com/pezkuwichain/pezkuwi-wasm.git"
},
"sideEffects": [
"./initNone.js",
"./initNone.cjs",
"./initOnlyAsm.js",
"./initOnlyAsm.cjs",
"./initOnlyWasm.js",
"./initOnlyWasm.cjs",
"./initWasmAsm.js",
"./initWasmAsm.cjs",
"./packageDetect.js",
"./packageDetect.cjs"
],
"type": "module",
"version": "7.5.5",
"main": "index.js",
"dependencies": {
"@pezkuwi/wasm-bridge": "7.5.5",
"@pezkuwi/wasm-crypto-asmjs": "7.5.5",
"@pezkuwi/wasm-crypto-init": "7.5.5",
"@pezkuwi/wasm-crypto-wasm": "7.5.5",
"@pezkuwi/wasm-util": "7.5.5",
"tslib": "^2.7.0"
},
"devDependencies": {
"@pezkuwi/util": "^14.0.1",
"@pezkuwi/x-randomvalues": "^14.0.1"
},
"peerDependencies": {
"@pezkuwi/util": "*",
"@pezkuwi/x-randomvalues": "*"
}
}
+247
View File
@@ -0,0 +1,247 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { WasmCryptoInstance } from '@pezkuwi/wasm-crypto-init/types';
import { bridge, initBridge } from './init.js';
export { packageInfo } from './packageInfo.js';
export { bridge };
// Removes the first parameter (expected as WasmCryptoInstance) and leaves the
// rest of the parameters in-tack. This allows us to dynamically create a function
// return from the withWasm helper
type PopFirst<T extends unknown[]> =
T extends [WasmCryptoInstance, ...infer N]
? N
: [];
/**
* @internal
* @description
* This create an extenal interface function from the signature, all the while checking
* the actual bridge wasm interface to ensure it has been initialized.
*
* This means that we can call it
*
* withWasm(wasm: WasmCryptoInstance, a: number, b: string) => Uint8Array
*
* and in this case it will create an interface function with the signarure
*
* (a: number, b: string) => Uint8Array
*/
function withWasm <T, F extends (wasm: WasmCryptoInstance, ...params: never[]) => T> (fn: F): (...params: PopFirst<Parameters<F>>) => ReturnType<F> {
return (...params: PopFirst<Parameters<F>>): ReturnType<F> => {
if (!bridge.wasm) {
throw new Error('The WASM interface has not been initialized. Ensure that you wait for the initialization Promise with waitReady() from @pezkuwi/wasm-crypto (or cryptoWaitReady() from @pezkuwi/util-crypto) before attempting to use WASM-only interfaces.');
}
return fn(bridge.wasm, ...params) as ReturnType<F>;
};
}
export const bip39Generate = /*#__PURE__*/ withWasm((wasm, words: 12 | 15 | 18 | 21 | 24): string => {
wasm.ext_bip39_generate(8, words);
return bridge.resultString();
});
export const bip39ToEntropy = /*#__PURE__*/ withWasm((wasm, phrase: string): Uint8Array => {
wasm.ext_bip39_to_entropy(8, ...bridge.allocString(phrase));
return bridge.resultU8a();
});
export const bip39ToMiniSecret = /*#__PURE__*/ withWasm((wasm, phrase: string, password: string): Uint8Array => {
wasm.ext_bip39_to_mini_secret(8, ...bridge.allocString(phrase), ...bridge.allocString(password));
return bridge.resultU8a();
});
export const bip39ToSeed = /*#__PURE__*/ withWasm((wasm, phrase: string, password: string): Uint8Array => {
wasm.ext_bip39_to_seed(8, ...bridge.allocString(phrase), ...bridge.allocString(password));
return bridge.resultU8a();
});
export const bip39Validate = /*#__PURE__*/ withWasm((wasm, phrase: string): boolean => {
const ret = wasm.ext_bip39_validate(...bridge.allocString(phrase));
return ret !== 0;
});
export const ed25519KeypairFromSeed = /*#__PURE__*/ withWasm((wasm, seed: Uint8Array): Uint8Array => {
wasm.ext_ed_from_seed(8, ...bridge.allocU8a(seed));
return bridge.resultU8a();
});
export const ed25519Sign = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, seckey: Uint8Array, message: Uint8Array): Uint8Array => {
wasm.ext_ed_sign(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(seckey), ...bridge.allocU8a(message));
return bridge.resultU8a();
});
export const ed25519Verify = /*#__PURE__*/ withWasm((wasm, signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean => {
const ret = wasm.ext_ed_verify(...bridge.allocU8a(signature), ...bridge.allocU8a(message), ...bridge.allocU8a(pubkey));
return ret !== 0;
});
export const secp256k1FromSeed = /*#__PURE__*/ withWasm((wasm, seckey: Uint8Array): Uint8Array => {
wasm.ext_secp_from_seed(8, ...bridge.allocU8a(seckey));
return bridge.resultU8a();
});
export const secp256k1Compress = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array): Uint8Array => {
wasm.ext_secp_pub_compress(8, ...bridge.allocU8a(pubkey));
return bridge.resultU8a();
});
export const secp256k1Expand = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array): Uint8Array => {
wasm.ext_secp_pub_expand(8, ...bridge.allocU8a(pubkey));
return bridge.resultU8a();
});
export const secp256k1Recover = /*#__PURE__*/ withWasm((wasm, msgHash: Uint8Array, sig: Uint8Array, recovery: number): Uint8Array => {
wasm.ext_secp_recover(8, ...bridge.allocU8a(msgHash), ...bridge.allocU8a(sig), recovery);
return bridge.resultU8a();
});
export const secp256k1Sign = /*#__PURE__*/ withWasm((wasm, msgHash: Uint8Array, seckey: Uint8Array): Uint8Array => {
wasm.ext_secp_sign(8, ...bridge.allocU8a(msgHash), ...bridge.allocU8a(seckey));
return bridge.resultU8a();
});
export const sr25519DeriveKeypairHard = /*#__PURE__*/ withWasm((wasm, pair: Uint8Array, cc: Uint8Array): Uint8Array => {
wasm.ext_sr_derive_keypair_hard(8, ...bridge.allocU8a(pair), ...bridge.allocU8a(cc));
return bridge.resultU8a();
});
export const sr25519DeriveKeypairSoft = /*#__PURE__*/ withWasm((wasm, pair: Uint8Array, cc: Uint8Array): Uint8Array => {
wasm.ext_sr_derive_keypair_soft(8, ...bridge.allocU8a(pair), ...bridge.allocU8a(cc));
return bridge.resultU8a();
});
export const sr25519DerivePublicSoft = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, cc: Uint8Array): Uint8Array => {
wasm.ext_sr_derive_public_soft(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(cc));
return bridge.resultU8a();
});
export const sr25519KeypairFromSeed = /*#__PURE__*/ withWasm((wasm, seed: Uint8Array): Uint8Array => {
wasm.ext_sr_from_seed(8, ...bridge.allocU8a(seed));
return bridge.resultU8a();
});
export const sr25519Sign = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, secret: Uint8Array, message: Uint8Array): Uint8Array => {
wasm.ext_sr_sign(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(secret), ...bridge.allocU8a(message));
return bridge.resultU8a();
});
export const sr25519Verify = /*#__PURE__*/ withWasm((wasm, signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean => {
const ret = wasm.ext_sr_verify(...bridge.allocU8a(signature), ...bridge.allocU8a(message), ...bridge.allocU8a(pubkey));
return ret !== 0;
});
export const sr25519Agree = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, secret: Uint8Array): Uint8Array => {
wasm.ext_sr_agree(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(secret));
return bridge.resultU8a();
});
export const vrfSign = /*#__PURE__*/ withWasm((wasm, secret: Uint8Array, context: Uint8Array, message: Uint8Array, extra: Uint8Array): Uint8Array => {
wasm.ext_vrf_sign(8, ...bridge.allocU8a(secret), ...bridge.allocU8a(context), ...bridge.allocU8a(message), ...bridge.allocU8a(extra));
return bridge.resultU8a();
});
export const vrfVerify = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, context: Uint8Array, message: Uint8Array, extra: Uint8Array, outAndProof: Uint8Array): boolean => {
const ret = wasm.ext_vrf_verify(...bridge.allocU8a(pubkey), ...bridge.allocU8a(context), ...bridge.allocU8a(message), ...bridge.allocU8a(extra), ...bridge.allocU8a(outAndProof));
return ret !== 0;
});
export const blake2b = /*#__PURE__*/ withWasm((wasm, data: Uint8Array, key: Uint8Array, size: number): Uint8Array => {
wasm.ext_blake2b(8, ...bridge.allocU8a(data), ...bridge.allocU8a(key), size);
return bridge.resultU8a();
});
export const hmacSha256 = /*#__PURE__*/ withWasm((wasm, key: Uint8Array, data: Uint8Array): Uint8Array => {
wasm.ext_hmac_sha256(8, ...bridge.allocU8a(key), ...bridge.allocU8a(data));
return bridge.resultU8a();
});
export const hmacSha512 = /*#__PURE__*/ withWasm((wasm, key: Uint8Array, data: Uint8Array): Uint8Array => {
wasm.ext_hmac_sha512(8, ...bridge.allocU8a(key), ...bridge.allocU8a(data));
return bridge.resultU8a();
});
export const keccak256 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array): Uint8Array => {
wasm.ext_keccak256(8, ...bridge.allocU8a(data));
return bridge.resultU8a();
});
export const keccak512 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array): Uint8Array => {
wasm.ext_keccak512(8, ...bridge.allocU8a(data));
return bridge.resultU8a();
});
export const pbkdf2 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array, salt: Uint8Array, rounds: number): Uint8Array => {
wasm.ext_pbkdf2(8, ...bridge.allocU8a(data), ...bridge.allocU8a(salt), rounds);
return bridge.resultU8a();
});
export const scrypt = /*#__PURE__*/ withWasm((wasm, password: Uint8Array, salt: Uint8Array, log2n: number, r: number, p: number): Uint8Array => {
wasm.ext_scrypt(8, ...bridge.allocU8a(password), ...bridge.allocU8a(salt), log2n, r, p);
return bridge.resultU8a();
});
export const sha256 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array): Uint8Array => {
wasm.ext_sha256(8, ...bridge.allocU8a(data));
return bridge.resultU8a();
});
export const sha512 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array): Uint8Array => {
wasm.ext_sha512(8, ...bridge.allocU8a(data));
return bridge.resultU8a();
});
export const twox = /*#__PURE__*/ withWasm((wasm, data: Uint8Array, rounds: number) => {
wasm.ext_twox(8, ...bridge.allocU8a(data), rounds);
return bridge.resultU8a();
});
export function isReady (): boolean {
return !!bridge.wasm;
}
export async function waitReady (): Promise<boolean> {
try {
const wasm = await initBridge();
return !!wasm;
} catch {
return false;
}
}
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import './packageDetect.js';
export * from './bundle.js';
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { InitFn } from '@pezkuwi/wasm-bridge/types';
import type { WasmCryptoInstance } from '@pezkuwi/wasm-crypto-init/types';
import { Bridge } from '@pezkuwi/wasm-bridge';
import { createWasm } from '@pezkuwi/wasm-crypto-init';
/**
* @name bridge
* @description
* The JS <-> WASM bridge that is in operation. For the specific package
* it is a global, i.e. all operations happens on this specific bridge
*/
export const bridge = new Bridge<WasmCryptoInstance>(createWasm);
/**
* @name initBridge
* @description
* Creates a new bridge interface with the (optional) initialization function
*/
export async function initBridge (createWasm?: InitFn<WasmCryptoInstance>): Promise<WasmCryptoInstance | null> {
return bridge.init(createWasm);
}
+23
View File
@@ -0,0 +1,23 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { createWasm } from '@pezkuwi/wasm-crypto-init/none';
import { initBridge } from './init.js';
/**
* @name initWasm
* @description
* For historic purposes and for tighter control on init, specifically performing
* a WASM initialization with no interface whatsoever (no WASM, no ASM.js)
*
* Generally should not be used unless you want explicit control over which
* interfaces are initialized.
*/
export async function initWasm (): Promise<void> {
await initBridge(createWasm);
}
initWasm().catch((): void => {
// cannot happen, initWasm doesn't throw
});
+23
View File
@@ -0,0 +1,23 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { createWasm } from '@pezkuwi/wasm-crypto-init/asm';
import { initBridge } from './init.js';
/**
* @name initWasm
* @description
* For historic purposes and for tighter control on init, specifically performing
* a WASM initialization with only ASM.js
*
* Generally should not be used unless you want explicit control over which
* interfaces are initialized.
*/
export async function initWasm (): Promise<void> {
await initBridge(createWasm);
}
initWasm().catch((): void => {
// cannot happen, initWasm doesn't throw
});
+23
View File
@@ -0,0 +1,23 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { createWasm } from '@pezkuwi/wasm-crypto-init/wasm';
import { initBridge } from './init.js';
/**
* @name initWasm
* @description
* For historic purposes and for tighter control on init, specifically performing
* a WASM initialization with only WASM (generally the default for most platforms)
*
* Generally should not be used unless you want explicit control over which
* interfaces are initialized.
*/
export async function initWasm (): Promise<void> {
await initBridge(createWasm);
}
initWasm().catch((): void => {
// cannot happen, initWasm doesn't throw
});
+23
View File
@@ -0,0 +1,23 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { createWasm } from '@pezkuwi/wasm-crypto-init/both';
import { initBridge } from './init.js';
/**
* @name initWasm
* @description
* For historic purposes and for tighter control on init, specifically performing
* a WASM initialization with ASM and an ASM.js fallback
*
* Generally should not be used unless you want explicit control over which
* interfaces are initialized.
*/
export async function initWasm (): Promise<void> {
await initBridge(createWasm);
}
initWasm().catch((): void => {
// cannot happen, initWasm doesn't throw
});
+24
View File
@@ -0,0 +1,24 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Use `wee_alloc` as the global allocator.
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[path = "rs/bip39.rs"]
pub mod bip39;
#[path = "rs/ed25519.rs"]
pub mod ed25519;
#[path = "rs/hashing.rs"]
pub mod hashing;
#[path = "rs/secp256k1.rs"]
pub mod secp256k1;
#[path = "rs/sr25519.rs"]
pub mod sr25519;
#[path = "rs/vrf.rs"]
pub mod vrf;
+4
View File
@@ -0,0 +1,4 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
export * from './index.js';
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2017-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @polkadot/dev
// (packageInfo imports will be kept as-is, user-editable)
import { detectPackage } from '@pezkuwi/util';
import { packageInfo as bridgeInfo } from '@pezkuwi/wasm-bridge/packageInfo';
import { packageInfo as asmInfo } from '@pezkuwi/wasm-crypto-asmjs/packageInfo';
import { packageInfo as initInfo } from '@pezkuwi/wasm-crypto-init/packageInfo';
import { packageInfo as wasmInfo } from '@pezkuwi/wasm-crypto-wasm/packageInfo';
import { packageInfo as utilInfo } from '@pezkuwi/wasm-util/packageInfo';
import { packageInfo } from './packageInfo.js';
detectPackage(packageInfo, null, [asmInfo, bridgeInfo, initInfo, utilInfo, wasmInfo]);
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2017-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Do not edit, auto-generated by @polkadot/dev
export const packageInfo = { name: '@pezkuwi/wasm-crypto', path: 'auto', type: 'auto', version: '7.5.4' };
+10
View File
@@ -0,0 +1,10 @@
root = true
[*]
indent_style=tab
indent_size=tab
tab_width=4
end_of_line=lf
charset=utf-8
trim_trailing_whitespace=true
max_line_length=100
insert_final_newline=true
+139
View File
@@ -0,0 +1,139 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
use bip39::{Mnemonic, MnemonicType, Language, Seed};
use hmac::Hmac;
use pbkdf2::pbkdf2;
use sha2::Sha512;
use wasm_bindgen::prelude::*;
/// Generate a bip39 phrase
///
/// words: number of words, either 12, 15, 18 21 or 24
///
/// Returns the bip 39 phrase
#[wasm_bindgen]
pub fn ext_bip39_generate(words: u32) -> String {
match MnemonicType::for_word_count(words as usize) {
Ok(p) => Mnemonic::new(p, Language::English)
.into_phrase(),
_ => panic!("Invalid count provided.")
}
}
/// Create entropy from a bip39 phrase
///
/// * phrase: mnemonic phrase
///
/// Returns the entropy
#[wasm_bindgen]
pub fn ext_bip39_to_entropy(phrase: &str) -> Vec<u8> {
match Mnemonic::from_phrase(phrase, Language::English) {
Ok(m) => m
.entropy()
.to_vec(),
_ => panic!("Invalid phrase provided.")
}
}
/// Create a mini-secret from a bip39 phrase
///
/// * phrase: mnemonic phrase
///
/// Returns the 32-byte mini-secret via entropy
#[wasm_bindgen]
pub fn ext_bip39_to_mini_secret(phrase: &str, password: &str) -> Vec<u8> {
match Mnemonic::from_phrase(phrase, Language::English) {
Ok(m) => {
let mut res = [0u8; 64];
let mut seed = vec![];
seed.extend_from_slice(b"mnemonic");
seed.extend_from_slice(password.as_bytes());
pbkdf2::<Hmac<Sha512>>(m.entropy(), &seed, 2048, &mut res);
res[..32].to_vec()
},
_ => panic!("Invalid phrase provided.")
}
}
/// Creates a BTC/ETH compatible seed from a bip-39 phrase
///
/// @phrase: mnemonic phrase
///
/// Returns a 32-byte seed
#[wasm_bindgen]
pub fn ext_bip39_to_seed(phrase: &str, password: &str) -> Vec<u8> {
match Mnemonic::from_phrase(phrase, Language::English) {
Ok(m) => Seed::new(&m, password)
.as_bytes()[..32]
.to_vec(),
_ => panic!("Invalid phrase provided.")
}
}
/// Validates a bip39 phrase
///
/// * phrase: mnemonic phrase
///
/// Returns the true/false
#[wasm_bindgen]
pub fn ext_bip39_validate(phrase: &str) -> bool {
match Mnemonic::validate(phrase, Language::English) {
Ok(_) => true,
_ => false
}
}
#[cfg(test)]
pub mod tests {
use hex_literal::hex;
use super::*;
#[test]
fn can_bip39_entropy() {
let phrase = "legal winner thank year wave sausage worth useful legal winner thank yellow";
let entropy = hex!("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f");
let res = ext_bip39_to_entropy(phrase);
assert_eq!(res, entropy);
}
#[test]
fn can_bip39_mini_secret() {
let phrase = "legal winner thank year wave sausage worth useful legal winner thank yellow";
let password = "Substrate";
let mini = hex!("4313249608fe8ac10fd5886c92c4579007272cb77c21551ee5b8d60b78041685");
let res = ext_bip39_to_mini_secret(phrase, password);
assert_eq!(res[..], mini[..]);
}
#[test]
fn can_bip39_seed() {
let phrase = "seed sock milk update focus rotate barely fade car face mechanic mercy";
let seed = hex!("3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027");
let res = ext_bip39_to_seed(phrase, "");
assert_eq!(res[..], seed[..]);
}
#[test]
fn can_bip39_generate() {
let phrase = ext_bip39_generate(12);
let is_valid = ext_bip39_validate(&phrase);
assert!(is_valid);
}
#[test]
fn can_bip39_validate() {
let is_valid = ext_bip39_validate("seed sock milk update focus rotate barely fade car face mechanic mercy");
let is_invalid = ext_bip39_validate("wine photo extra cushion basket dwarf humor cloud truck job boat submit");
assert_eq!(is_valid, true);
assert_eq!(is_invalid, false);
}
}
+142
View File
@@ -0,0 +1,142 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
use std::convert::TryFrom;
use ed25519_dalek::{Keypair, PublicKey, SecretKey, Signature, Signer as _, Verifier as _};
use wasm_bindgen::prelude::*;
/// Keypair helper function
fn new_from_seed(seed: &[u8]) -> Keypair {
match SecretKey::from_bytes(seed) {
Ok(secret) => {
let public: PublicKey = (&secret).into();
Keypair { secret: secret, public: public }
},
_ => panic!("Invalid seed provided.")
}
}
/// Generate a key pair.
///
/// * seed: UIntArray with 32 element
///
/// returned vector is the concatenation of first the seed (32 bytes)
/// followed by the public key (32) bytes, as the full secret keys.
#[wasm_bindgen]
pub fn ext_ed_from_seed(seed: &[u8]) -> Vec<u8> {
new_from_seed(seed)
.to_bytes()
.to_vec()
}
/// Sign a message
///
/// The combination of both public and private key must be provided.
/// This is effectively equivalent to a keypair.
///
/// * _: UIntArray with 32 element (was pubkey, now ignored)
/// * private: UIntArray with 64 element
/// * message: Arbitrary length UIntArray
///
/// * returned vector is the signature consisting of 64 bytes.
#[wasm_bindgen]
pub fn ext_ed_sign(_: &[u8], seckey: &[u8], message: &[u8]) -> Vec<u8> {
// https://github.com/MystenLabs/ed25519-unsafe-libs
// we never use the provided pubkey
new_from_seed(seckey)
.sign(message)
.to_bytes()
.to_vec()
}
/// Verify a message and its corresponding against a public key;
///
/// * signature: UIntArray with 64 element
/// * message: Arbitrary length UIntArray
/// * pubkey: UIntArray with 32 element
#[wasm_bindgen]
pub fn ext_ed_verify(signature: &[u8], message: &[u8], pubkey: &[u8]) -> bool {
match (Signature::try_from(signature), PublicKey::from_bytes(pubkey)) {
(Ok(s), Ok(k)) => k
.verify(message, &s)
.is_ok(),
_ => false
}
}
#[cfg(test)]
pub mod tests {
extern crate rand;
use hex_literal::hex;
use super::*;
use ed25519_dalek::{SIGNATURE_LENGTH, KEYPAIR_LENGTH, SECRET_KEY_LENGTH};
fn generate_random_seed() -> Vec<u8> {
(0..32).map(|_| rand::random::<u8>() ).collect()
}
#[test]
fn can_new_keypair() {
let seed = generate_random_seed();
let keypair = ext_ed_from_seed(seed.as_slice());
assert!(keypair.len() == KEYPAIR_LENGTH);
}
#[test]
fn creates_pair_from_known() {
let seed = b"12345678901234567890123456789012";
let expected = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee");
let keypair = ext_ed_from_seed(seed);
let public = &keypair[SECRET_KEY_LENGTH..KEYPAIR_LENGTH];
assert_eq!(public, expected);
}
#[test]
fn can_sign_message() {
let seed = generate_random_seed();
let keypair = ext_ed_from_seed(seed.as_slice());
let private = &keypair[0..SECRET_KEY_LENGTH];
let public = &keypair[SECRET_KEY_LENGTH..KEYPAIR_LENGTH];
let message = b"this is a message";
let signature = ext_ed_sign(public, private, message);
assert!(signature.len() == SIGNATURE_LENGTH);
}
#[test]
fn can_verify_message() {
let seed = generate_random_seed();
let keypair = ext_ed_from_seed(seed.as_slice());
let private = &keypair[0..SECRET_KEY_LENGTH];
let public = &keypair[SECRET_KEY_LENGTH..KEYPAIR_LENGTH];
let message = b"this is a message";
let signature = ext_ed_sign(public, private, message);
let is_valid = ext_ed_verify(&signature[..], message, public);
assert!(is_valid);
}
#[test]
fn can_verify_known() {
let public = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee");
let message = b"this is a message";
let signature = hex!("90588f3f512496f2dd40571d162e8182860081c74e2085316e7c4396918f07da412ee029978e4dd714057fe973bd9e7d645148bf7b66680d67c93227cde95202");
let is_valid = ext_ed_verify(&signature, message, &public);
assert!(is_valid);
}
#[test]
fn can_verify_known_wrong() {
let public = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee");
let message = b"this is a message";
let signature = &[0u8; 64];
let is_valid = ext_ed_verify(signature, message, &public);
assert_eq!(is_valid, false);
}
}
+322
View File
@@ -0,0 +1,322 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
use blake2_rfc::blake2b::blake2b;
use byteorder::{ByteOrder, LittleEndian};
use hmac::{Hmac, Mac};
use pbkdf2::pbkdf2;
use scrypt::{ScryptParams, scrypt};
use sha2::{Digest, Sha256, Sha512};
use tiny_keccak::{Hasher, Keccak};
use twox_hash::XxHash;
use wasm_bindgen::prelude::*;
/// blake2b hash for the specified input
///
/// * data: Arbitrary data to be hashed
/// * key: Key to add to the hashing (normally empty)
/// * size: Size in bytes of the resulting output
///
/// Returns a vector with the hash result
#[wasm_bindgen]
pub fn ext_blake2b(data: &[u8], key: &[u8], size: u32) -> Vec<u8> {
// we cast to usize here - due to the WASM, we'd rather have u32 inputs
blake2b(size as usize, key, data)
.as_bytes()
.to_vec()
}
/// hmac with sha256
#[wasm_bindgen]
pub fn ext_hmac_sha256(key: &[u8], data: &[u8]) -> Vec<u8> {
match Hmac::<Sha256>::new_varkey(key) {
Ok(mut m) => {
m.input(data);
m
.result()
.code()
.to_vec()
},
_ => panic!("Invalid key provided.")
}
}
/// hmac with sha512
#[wasm_bindgen]
pub fn ext_hmac_sha512(key: &[u8], data: &[u8]) -> Vec<u8> {
match Hmac::<Sha512>::new_varkey(key) {
Ok(mut m) => {
m.input(data);
m
.result()
.code()
.to_vec()
},
_ => panic!("Invalid key provided.")
}
}
/// Create a keccak256 hash for the specified input
///
// * data: Arbitrary data to be hashed
///
/// Returns the hash as a vector
#[wasm_bindgen]
pub fn ext_keccak256(data: &[u8]) -> Vec<u8> {
let mut keccak = Keccak::v256();
let mut res = [0u8; 32];
keccak.update(data);
keccak.finalize(&mut res);
res.to_vec()
}
/// Create a keccak512 hash for the specified input
///
// * data: Arbitrary data to be hashed
///
/// Returns the hash as a vector
#[wasm_bindgen]
pub fn ext_keccak512(data: &[u8]) -> Vec<u8> {
let mut keccak = Keccak::v512();
let mut res = [0u8; 64];
keccak.update(data);
keccak.finalize(&mut res);
res.to_vec()
}
/// pbkdf2 kdf from an input, salt for the number of specified rounds
///
/// * data: Arbitrary data to be hashed
/// * salt: Salt for this hash
/// * rounds: The number of rounds to perform
///
/// Returns a vector with the hashed result
#[wasm_bindgen]
pub fn ext_pbkdf2(data: &[u8], salt: &[u8], rounds: u32) -> Vec<u8> {
// As per RFC 2898 [https://datatracker.ietf.org/doc/html/rfc2898], the number of rounds must be greater than 0
if rounds == 0 {
panic!("PBKDF2 rounds must be greater than 0");
}
let mut res = [0u8; 64];
// we cast to usize here - due to the WASM, we'd rather have u32 inputs
pbkdf2::<Hmac::<Sha512>>(data, salt, rounds as usize, &mut res);
res.to_vec()
}
/// scrypt kdf from input, salt and config
///
/// * password: Password to hash
/// * salt: Salt for this hash
/// * log2_n: log2(n)
/// * r: r
/// * p: p
///
/// Returns vector with the hashed result
#[wasm_bindgen]
pub fn ext_scrypt(password: &[u8], salt: &[u8], log2_n: u8, r: u32, p: u32) -> Vec<u8> {
// As per RFC 7914 [https://datatracker.ietf.org/doc/html/rfc7914.html], the cost parameter N (2 ^ log2_n) must be larger than 1
if log2_n == 0 {
panic!("Scrypt cost parameter N must be larger than 1, log2_n must be at least 1");
}
match ScryptParams::new(log2_n, r, p) {
Ok(p) => {
let mut res = [0u8; 64];
match scrypt(password, salt, &p, &mut res) {
Ok(_) => res.to_vec(),
_ => panic!("Invalid scrypt hash.")
}
},
_ => panic!("Invalid scrypt params.")
}
}
/// sha256 hash for the specified input
///
/// * data: Arbitrary data to be hashed
///
/// Returns a vector with the hash result
#[wasm_bindgen]
pub fn ext_sha256(data: &[u8]) -> Vec<u8> {
let mut hasher = Sha256::new();
hasher.input(data);
hasher
.result()
.to_vec()
}
/// sha512 hash for the specified input
///
/// * data: Arbitrary data to be hashed
///
/// Returns a vector with the hash result
#[wasm_bindgen]
pub fn ext_sha512(data: &[u8]) -> Vec<u8> {
let mut hasher = Sha512::new();
hasher.input(data);
hasher
.result()
.to_vec()
}
/// twox hash for the specified input and rounds
///
/// * data: Arbitrary data to be hashed
/// * rounds: Number of 8-byte rounds to add to the output
///
/// Returns a vector with the hash result
#[wasm_bindgen]
pub fn ext_twox(data: &[u8], rounds: u32) -> Vec<u8> {
use ::std::hash::Hasher;
let mut res = vec![];
let mut buf = [0u8; 8];
for round in 0..rounds {
// we cast to u64 here - due to the WASM, we'd rather have u32 inputs
let mut hasher = XxHash::with_seed(round as u64);
hasher.write(data);
LittleEndian::write_u64(&mut buf, hasher.finish());
res.extend_from_slice(&buf);
}
res
}
#[cfg(test)]
pub mod tests {
use hex_literal::hex;
use super::*;
#[test]
fn can_blake2b() {
let data = b"abc";
let expected_32 = hex!("bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319");
let expected_64 = hex!("ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923");
let hash_32 = ext_blake2b(data, &[], 32);
let hash_64 = ext_blake2b(data, &[], 64);
assert_eq!(hash_32[..], expected_32[..]);
assert_eq!(hash_64[..], expected_64[..]);
}
#[test]
fn can_keccak256() {
let data = b"test value";
let expected = hex!("2d07364b5c231c56ce63d49430e085ea3033c750688ba532b24029124c26ca5e");
let hash = ext_keccak256(data);
assert_eq!(hash[..], expected[..]);
}
#[test]
fn can_hmac_sha256() {
let key = b"secret";
let data = b"some message";
let expected = hex!("f28a70b41263840e5c059a0a733336e0957efba87902aa8cca11441d4b0c96d7");
let hash = ext_hmac_sha256(key, data);
assert_eq!(hash[..], expected[..]);
}
#[test]
fn can_hmac_sha512() {
let key = b"secret";
let data = b"some message";
let expected = hex!("295832e97ed77be75a9fa98029497e4a722c4b9a2f21b39d34f1befa931a39ec520fd24711d6f5c03501384ea66b83066a01a82c57a0460f8cd1f471fcce5841");
let hash = ext_hmac_sha512(key, data);
assert_eq!(hash[..], expected[..]);
}
#[test]
fn can_keccak512() {
let data = b"test";
let expected = hex!("1e2e9fc2002b002d75198b7503210c05a1baac4560916a3c6d93bcce3a50d7f00fd395bf1647b9abb8d1afcc9c76c289b0c9383ba386a956da4b38934417789e");
let hash = ext_keccak512(data);
assert_eq!(hash[..], expected[..]);
}
#[test]
fn can_pbkdf2() {
let salt = b"this is a salt";
let data = b"hello world";
let expected = hex!("5fcbe04f05300a3ecc5c35d18ea0b78f3f6853d2ae5f3fca374f69a7d1f78b5def5c60dae1a568026c7492511e0c53521e8bb6e03a650e1263265fee92722270");
let hash = ext_pbkdf2(data, salt, 2048);
assert_eq!(hash[..], expected[..]);
}
#[test]
#[should_panic(expected = "PBKDF2 rounds must be greater than 0")]
fn pbkdf2_zero_rounds_panics() {
let salt = b"this is a salt";
let data = b"hello world";
ext_pbkdf2(data, salt, 0);
}
#[test]
fn can_scrypt() {
let password = b"password";
let salt = b"salt";
let expected = hex!("745731af4484f323968969eda289aeee005b5903ac561e64a5aca121797bf7734ef9fd58422e2e22183bcacba9ec87ba0c83b7a2e788f03ce0da06463433cda6");
let hash = ext_scrypt(password, salt, 14, 8, 1);
assert_eq!(hash[..], expected[..]);
}
#[test]
#[should_panic(expected = "Scrypt cost parameter N must be larger than 1, log2_n must be at least 1")]
fn scrypt_zero_log2_n_panics() {
let password = b"password";
let salt = b"salt";
ext_scrypt(password, salt, 0, 8, 1);
}
#[test]
fn can_sha256() {
let data = b"hello world";
let expected = hex!("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9");
let hash = ext_sha256(data);
assert_eq!(hash[..], expected[..]);
}
#[test]
fn can_sha512() {
let data = b"hello world";
let expected = hex!("309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f");
let hash = ext_sha512(data);
assert_eq!(hash[..], expected[..]);
}
#[test]
fn can_twox() {
let data = b"abc";
let expected_64 = hex!("990977adf52cbc44");
let expected_256 = hex!("990977adf52cbc440889329981caa9bef7da5770b2b8a05303b75d95360dd62b");
let hash_64 = ext_twox(data, 1);
let hash_256 = ext_twox(data, 4);
assert_eq!(hash_64[..], expected_64[..]);
assert_eq!(hash_256[..], expected_256[..]);
}
}
+150
View File
@@ -0,0 +1,150 @@
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
use secp256k1::{
ecdsa::{RecoverableSignature, RecoveryId},
Message, PublicKey, SecretKey, SECP256K1,
};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn ext_secp_pub_compress(pubkey: &[u8]) -> Vec<u8> {
match PublicKey::from_slice(&pubkey) {
Ok(p) => p.serialize().to_vec(),
_ => panic!("Invalid pubkey provided."),
}
}
#[wasm_bindgen]
pub fn ext_secp_pub_expand(pubkey: &[u8]) -> Vec<u8> {
match PublicKey::from_slice(&pubkey) {
Ok(p) => p.serialize_uncompressed().to_vec(),
_ => panic!("Invalid pubkey provided."),
}
}
#[wasm_bindgen]
pub fn ext_secp_from_seed(seed: &[u8]) -> Vec<u8> {
match SecretKey::from_slice(seed) {
Ok(s) => {
let mut res = vec![];
let pubkey = PublicKey::from_secret_key(SECP256K1, &s);
res.extend_from_slice(&s.serialize_secret());
res.extend_from_slice(&pubkey.serialize());
res
}
_ => panic!("Invalid seed provided."),
}
}
#[wasm_bindgen]
pub fn ext_secp_recover(hash: &[u8], sig: &[u8], rec: i32) -> Vec<u8> {
match RecoveryId::from_i32(rec) {
Ok(r) => match (
Message::from_slice(hash),
RecoverableSignature::from_compact(&sig, r),
) {
(Ok(m), Ok(s)) => {
let standard = s.to_standard();
let mut normalized = standard;
normalized.normalize_s();
// check if the signature is normalized
if normalized.ne(&standard) {
panic!("Non-normalized signature provided.");
}
match s.recover(&m) {
Ok(k) => k.serialize().to_vec(),
_ => panic!("Unable to recover."),
}
}
_ => panic!("Invalid signature provided."),
},
_ => panic!("Invalid recovery data provided."),
}
}
#[wasm_bindgen]
pub fn ext_secp_sign(hash: &[u8], seckey: &[u8]) -> Vec<u8> {
match (Message::from_slice(hash), SecretKey::from_slice(seckey)) {
(Ok(m), Ok(s)) => {
let mut res = vec![];
let (rec, sig) = SECP256K1.sign_ecdsa_recoverable(&m, &s).serialize_compact();
res.extend_from_slice(&sig);
res.push(rec.to_i32() as u8);
res
}
_ => panic!("Invalid message or secret provided."),
}
}
#[cfg(test)]
pub mod tests {
use super::*;
use hex_literal::hex;
#[test]
fn can_create_pair() {
let seckey = hex!("4380de832af797688026ce24f85204d508243f201650c1a134929e5458b7fbae");
let expected = hex!("4380de832af797688026ce24f85204d508243f201650c1a134929e5458b7fbae03fd8c74f795ced92064b86191cb2772b1e3a0947740aa0a5a6e379592471fd85b");
let res = ext_secp_from_seed(&seckey);
assert_eq!(res[..], expected[..]);
}
#[test]
fn can_pub_compress_full() {
let pubkey = hex!("04b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af");
let expected = hex!("03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077");
let res = ext_secp_pub_compress(&pubkey);
assert_eq!(res[..], expected[..]);
}
#[test]
fn can_pub_expand_comp() {
let pubkey = hex!("03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077");
let expected = hex!("04b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af");
let res = ext_secp_pub_expand(&pubkey);
assert_eq!(res[..], expected[..]);
}
#[test]
fn can_recover() {
let expected = hex!("028d13da15a02f3a70677339d51b14177ee9b49657662b35e56a9d9dee17db1d30");
let sig = hex!("7505f2880114da51b3f5d535f8687953c0ab9af4ab81e592eaebebf53b728d2b6dfd9b5bcd70fee412b1f31360e7c2774009305cb84fc50c1d0ff8034dfa5fff");
let msg = hex!("a30b64ce1eedf409c8afb801d72c05234e64849ea538c15dd3c8cf4ffcf166c9");
let res = ext_secp_recover(&msg, &sig, 0);
assert_eq!(res[..], expected[..]);
}
#[test]
fn can_sign() {
// JS expectation - doesn't match?
// let expected = hex!("df92f73d9f060cefacf187b5414491cb992998ace017fa48839b5cda3e264ba8c4efa521361678d9b8582744d77aa4b8d886d7380b7808a683174afad9c4700300");
let expected = hex!("df92f73d9f060cefacf187b5414491cb992998ace017fa48839b5cda3e264ba83b105adec9e9872647a7d8bb28855b45e22805aea3d097953cbb1391f671d13e01");
let seckey = hex!("4380de832af797688026ce24f85204d508243f201650c1a134929e5458b7fbae");
let msg = hex!("68c731589a583d08b70861683b59ce3dd56284cb2f0da5b6cd83e6641dac3aab");
let res = ext_secp_sign(&msg, &seckey);
assert_eq!(res[..], expected[..]);
}
#[test]
#[should_panic(expected = "Non-normalized signature provided.")]
fn rejects_high_s_signature() {
// valid ECDSA signature with a high S value (non-normalized)
let sig = hex!(
"fa1b7a71500322d70bcd5b982c678c96c95f68893063e1621b8b85c867b80b1caae8c7c4f8b5c6d181e4c8898a3f4c329da0e2c21f6f80552a660e6c1d9fa201");
let msg = hex!("9a3c9be3a14a94df8cda1c474c0e9f8b1b35b1d85d2122cb87e6eb3c518e3be3");
let _ = ext_secp_recover(&msg, &sig, 0);
}
}

Some files were not shown because too many files have changed in this diff Show More