Skip to content

Commit

Permalink
Merge pull request #1 from fetchai/feat/browser-support
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanchriswhite committed Jun 16, 2022
2 parents e7f36ad + ebfa805 commit a401a66
Show file tree
Hide file tree
Showing 37 changed files with 6,150 additions and 1,132 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Expand Up @@ -89,4 +89,5 @@ module.exports = {
},
},
],
"ignorePatterns": ["pre.js", "post.js", "webpack.config.js", "karma.conf.js"],
};
20 changes: 10 additions & 10 deletions .github/workflows/main.yml
Expand Up @@ -41,7 +41,7 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: blst_wrap.cpp
path: prebuild/blst_wrap.cpp
path: prebuild/swig/blst_wrap.cpp
if-no-files-found: error

- name: Lint
Expand All @@ -67,7 +67,7 @@ jobs:
uses: actions/download-artifact@v2
with:
name: blst_wrap.cpp
path: prebuild/
path: prebuild/swig/

- name: Setup Node.js ${{matrix.node}}
uses: actions/setup-node@v1
Expand Down Expand Up @@ -102,7 +102,7 @@ jobs:
if: github.repository_owner == 'chainsafe' && github.event_name != 'pull_request'
with:
name: binding.node
path: prebuild/*.node
path: prebuild/swig/*.node
if-no-files-found: error

build-arm:
Expand All @@ -124,7 +124,7 @@ jobs:
uses: actions/download-artifact@v2
with:
name: blst_wrap.cpp
path: prebuild/
path: prebuild/swig

# Download spec tests with cache
- name: Restore spec tests cache
Expand All @@ -144,14 +144,14 @@ jobs:
run: |
docker buildx build --build-arg NODE_VERSION=${{matrix.node}} --platform linux/arm64 -t armbuild:latest --load --progress=plain .
docker create --name armbuild armbuild:latest
docker cp armbuild:/prebuild .
docker cp armbuild:/prebuild/swig .
- name: Upload binding.node
uses: actions/upload-artifact@v2
if: github.repository_owner == 'chainsafe' && github.event_name != 'pull_request'
with:
name: binding.node
path: prebuild/*.node
path: prebuild/swig/*.node
if-no-files-found: error

benchmark:
Expand All @@ -169,7 +169,7 @@ jobs:
uses: actions/download-artifact@v2
with:
name: blst_wrap.cpp
path: prebuild/
path: prebuild/swig/

- name: Install && Build TS + bindings
run: yarn bootstrap
Expand Down Expand Up @@ -200,20 +200,20 @@ jobs:
uses: actions/download-artifact@v2
with:
name: blst_wrap.cpp
path: prebuild/
path: prebuild/swig/
- name: Get binding.node pre-builts
uses: actions/download-artifact@v2
with:
name: binding.node
path: prebuild/
path: prebuild/swig/

- name: Build .ts source for release
run: yarn bootstrap

- name: Create Github release with prebuilds
uses: softprops/action-gh-release@v1
with:
files: prebuild/*
files: prebuild/swig/*
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Expand Up @@ -3,7 +3,10 @@ coverage
build
dist
node_modules
prebuild/*.node
prebuild/swig/*.node
prebuild/emscripten/blst.wasm
prebuild/emscripten/blst.js
prebuild/emscripten/blst.wasm.js

npm-debug.log
yarn-error.log
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
@@ -1,3 +1,3 @@
[submodule "blst"]
path = blst
url = https://github.com/supranational/blst.git
url = https://github.com/fetchai/blst.git
106 changes: 75 additions & 31 deletions README.md
@@ -1,58 +1,102 @@
# blst-ts
This repository is a fork of [chainsafe/blst-ts](https://github.com/chainsafe/blst-ts) which may be used as a staging area for changes that may (or may not) be upstreamed.

![ETH2.0_Spec_Version 0.12.0](https://img.shields.io/badge/ETH2.0_Spec_Version-0.12.0-2e86c1.svg)
![ES Version](https://img.shields.io/badge/ES-2017-yellow)
![Node Version](https://img.shields.io/badge/node-12.x-green)

Typescript wrapper for [supranational/blst](https://github.com/supranational/blst) native bindings, a highly performant BLS12-381 signature library.
## Developing

## Usage
Note that this repo contains a git submodule. Make sure the git submodule `blst` is populated before attempting to build locally. After cloning run:

```bash
yarn add @chainsafe/blst
git submodule update --init --recursive
```

This library comes with pre-compiled bindings for most platforms. You can check current support in [releases](https://github.com/ChainSafe/blst-ts/releases). If your platform is not supported, bindings will be compiled from source as a best effort with node-gyp.
### Using emscripten bindings

```ts
import {SecretKey, verify} from "@chainsafe/blst";
#### `package.json`:
```javascript
depencencies: {
"@chainsafe/blst": "git+https://github.com/fechai/blst-ts#feat/browser-support",
...
}
```

const msg = Buffer.from("sample-msg");
const sk = SecretKey.fromKeygen(Buffer.alloc(32, 1));
const pk = sk.toPublicKey();
const sig = sk.sign(msg);
#### `webpack.config.js` (V5):
```javascript
module.exports = {
resolve: {
fallback: {
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"buffer": require.resolve("buffer"),
"assert": require.resolve("assert-browserify"),
"path": require.resolve("path-browserify"),
"fs": false,
},
...
},
ignoreWarnings: [
{
module: /^(fs|process)$/,
}
]
}
```

console.log(verify(msg, pk, sig)); // true
#### `webpack.config.js` (V4):
```javascript
module.exports = {
plugins: [
new webpack.IgnorePlugin(/^(fs|process)$/),
],
...
}
```

This library exposes two types of classes for public keys and signatures: `PublicKey` & `AggregatePublicKey`, `Signature` & `AggregateSignature`
### Building WebAssembly module

- `PublicKey`: Contains an affine point (x,y). It's the default representation of the point and what you need to serialize to and deserialize from.
- `AggregatePublicKey`: Contains a jacobian point (x,y,z). It's optimal to perform aggregation operations.
_(NOTE: docker is required to use the script)_

## Spec versioning
```bash
yarn build:emscripten
```

This library has a hardcoded configuration compatible with Eth2.0 spec:
##### Manual build
_(NOTE: a copy of [emsdk](https://github.com/emscripten-core/emsdk) is required to build for web assembly. See [emscripten docs -> Building Projects](https://emscripten.org/docs/compiling/Building-Projects.html) for more information)_

| Setting | value |
| -------------- | --------------------------------------------- |
| PK_IN | `G1` |
| HASH_OR_ENCODE | `true` |
| DST | `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_` |
| RAND_BITS | `64` |
```bash
# ensure enscripten sdk is active
/path/to/emsdk/emsdk activate
source /path/to/emsdk/emsdk_env.sh

> [spec](https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#bls-signatures)
CROSS_COMPILE=em CFLAGS="-o ./prebuild/emscripten/blst.js --pre-js ./prebuild/emscripten/pre.js --post-js ./prebuild/emscripten/post.js ./prebuild/emscripten/blst_glue_wrapper.cpp" ./blst/build.sh -link -no-archive
```

> [test vectors](https://github.com/ethereum/eth2.0-spec-tests/tree/master/tests/bls)
## Testing in the browser

## Developing
Once built (see [building WebAssembly module](#building-webassembly-module)), applicable mocha tests can be run in the browser using webpack:

Note that this repo contains a git submodule. Make sure the git submodule `blst` is populated before attempting to build locally. After cloning run:
```bash
yarn test:browser
```

#### Karma

Additionally, [Karma](https://karma-runner.github.io/6.3/index.html) is configured to run browser-relevant tests in chrome by starting and running:

```bash
# Optionally, CHROME_BIN=$(which <non-standard-chromium-flavor>)
# (see: https://github.com/karma-runner/karma-chrome-launcher)

yarn karma start
```
git submodule update --init --recursive

```bash
# separate shell

yarn karma run
```

_(NOTE: it currently seems like Karma has to be run a few times before it picks up all the tests)_

## License

Apache-2.0
2 changes: 1 addition & 1 deletion blst
Submodule blst updated 1 files
+17 −9 build.sh
24 changes: 24 additions & 0 deletions karma.conf.js
@@ -0,0 +1,24 @@
const {module: _module, resolve, ignoreWarnings} = require("./webpack.config");

module.exports = (config) => {
config.set({
basePath: "",
files: [
"test/unit/lib/index.test.ts",
"test/unit/bindings/*.test.ts",
],
frameworks: ["webpack", "mocha", "chai"],
browsers: ["Chrome"],
plugins: ["karma-chrome-launcher", "karma-webpack", "karma-mocha", "karma-chai"],
preprocessors: {
"test/**/*.ts": ["webpack"],
// "src/**/*.ts": ["webpack"],
},
webpack: {
mode: "production",
module: _module,
resolve,
ignoreWarnings,
}
});
}
24 changes: 21 additions & 3 deletions package.json
Expand Up @@ -13,12 +13,15 @@
"install": "node dist/scripts/install.js",
"lint": "eslint --color --ext .ts src/ test/",
"build": "tsc --project tsconfig.build.json",
"build:emscripten": "node ./dist/scripts/buildEmscripten.js && yarn inline:wasm",
"bootstrap": "yarn install --ignore-scripts && yarn build && yarn install",
"clean": "rm -rf prebuild/*.node dist blst/libblst.a blst/bindings/libblst.a blst/bindings/node.js/blst.node blst/bindings/node.js/blst_wrap.cpp",
"clean": "rm -rf prebuild/emscripten/blst.{wasm,wasm.js,js} prebuild/swig/*.node dist blst/libblst.a blst/bindings/libblst.a blst/bindings/node.js/blst.node blst/bindings/node.js/blst_wrap.cpp",
"test": "yarn test:unit && yarn test:spec",
"test:unit": "mocha test/unit/**/*.test.ts",
"test:spec": "mocha 'test/spec/**/*.test.ts'",
"download-spec-tests": "node -r ts-node/register test/spec/downloadTests.ts"
"test:browser": "yarn inline:wasm && npx webpack serve",
"download-spec-tests": "node -r ts-node/register test/spec/downloadTests.ts",
"inline:wasm": "node ./dist/scripts/inline_bin.js ./prebuild/emscripten/blst.wasm"
},
"repository": {
"type": "git",
Expand All @@ -39,17 +42,32 @@
"@types/node-fetch": "^2.5.7",
"@typescript-eslint/eslint-plugin": "^4.21.0",
"@typescript-eslint/parser": "^4.21.0",
"assert-browserify": "^2.0.0",
"buffer": "^6.0.3",
"chai": "^4.2.0",
"crypto-browserify": "^3.12.0",
"eslint": "^7.23.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.3.1",
"js-yaml": "^4.1.0",
"karma": "^6.3.20",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.1",
"karma-mocha": "^2.0.1",
"karma-typescript": "^5.5.3",
"karma-webpack": "^5.0.0",
"mocha": "^8.1.3",
"path-browserify": "^1.0.1",
"prettier": "^2.2.1",
"stream-browserify": "^3.0.0",
"threads": "^1.6.3",
"ts-loader": "^9.3.0",
"ts-node": "^9.0.0",
"typescript": "^4.0.3"
"typescript": "^4.0.3",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.8.1"
},
"dependencies": {
"node-fetch": "^2.6.1",
Expand Down
25 changes: 25 additions & 0 deletions prebuild/emscripten/blst.d.ts
@@ -0,0 +1,25 @@
import {
P1_AffineConstructor,
P1Constructor,
P2_AffineConstructor,
P2Constructor,
PairingConstructor,
PTConstructor,
SecretKeyConstructor,
} from "../../src/bindings";

export const initialized: Promise<void>;

// BLS12_381_G1: P1_Affine;
// BLS12_381_NEG_G1: P1_Affine;
// BLS12_381_G2: P2_Affine;
// BLS12_381_NEG_G2: P2_Affine;
export const SecretKey: SecretKeyConstructor;
export const P1_Affine: P1_AffineConstructor;
export const P2_Affine: P2_AffineConstructor;
export const P1: P1Constructor;
export const P2: P2Constructor;
export const PT: PTConstructor;
export const Pairing: PairingConstructor;
export const G1: () => P1;
export const G2: () => P2;

0 comments on commit a401a66

Please sign in to comment.