forked from tornado-packages/noble-curves
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
a8ea9d757f | |||
|
efeca9f478 | ||
|
8ad2f9a185 | ||
|
be576b4c17 | ||
|
819514576c | ||
|
a0e398489f | ||
|
85d194cb93 | ||
|
1830124ca1 | ||
|
72cc640bb1 | ||
|
32bda7926d | ||
|
38a4ca1e6b | ||
|
07f7e53e31 | ||
|
537db4a968 | ||
|
a70501cec4 | ||
|
89aaf264c1 | ||
|
e93caf9567 | ||
|
0ce103bd6b | ||
|
6a85252dc3 | ||
|
a8503d6819 | ||
|
8397b26b45 | ||
|
8c39a6ac5a | ||
|
a1a7dc9cbf | ||
|
ba58a282bd | ||
|
c4c479047e | ||
|
2bf2e312a0 |
1
.github/funding.yml
vendored
1
.github/funding.yml
vendored
@ -1,2 +1 @@
|
||||
github: paulmillr
|
||||
# custom: https://paulmillr.com/funding/
|
29
.github/workflows/nodejs.yml
vendored
29
.github/workflows/nodejs.yml
vendored
@ -1,20 +1,23 @@
|
||||
name: Node CI
|
||||
|
||||
on: [push, pull_request]
|
||||
name: Run node.js tests
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
jobs:
|
||||
test:
|
||||
name: v${{ matrix.node }} @ ubuntu-latest
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node: [18, 20]
|
||||
node:
|
||||
- 18
|
||||
- 20
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- run: npm install
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
||||
- run: npm run lint --if-present
|
||||
- uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 # v4
|
||||
- name: Use Node.js ${{ matrix.node }}
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- run: npm install
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
||||
- run: npm run lint --if-present
|
||||
|
42
.github/workflows/publish-npm.yml
vendored
42
.github/workflows/publish-npm.yml
vendored
@ -1,23 +1,23 @@
|
||||
name: Publish Package to npm
|
||||
name: Publish package to npm
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
release:
|
||||
types: [created]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
|
||||
- uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3
|
||||
with:
|
||||
node-version: 20
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: npm
|
||||
- run: npm install -g npm
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm publish --provenance --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 # v4
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
|
||||
with:
|
||||
node-version: 20
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: npm
|
||||
- run: npm install -g npm
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm publish --provenance --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
|
28
.github/workflows/upload-release.yml
vendored
Normal file
28
.github/workflows/upload-release.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Upload standalone file to GitHub Releases
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 # v4
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
|
||||
with:
|
||||
node-version: 20
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: npm
|
||||
- run: npm install -g npm
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: |
|
||||
cd build
|
||||
npm ci
|
||||
npm run build:release
|
||||
cd ..
|
||||
- run: gh release upload ${{ github.event.release.tag_name }} build/`npx jsbt outfile`
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
31
README.md
31
README.md
@ -7,14 +7,18 @@ Audited & minimal JS implementation of elliptic curve cryptography.
|
||||
- 🏎 Ultra-fast, hand-optimized for caveats of JS engines
|
||||
- 🔍 Unique tests ensure correctness: property-based, cross-library and Wycheproof vectors, fuzzing
|
||||
- ➰ Short Weierstrass, Edwards, Montgomery curves
|
||||
- ✍️ ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
|
||||
- ✍️ ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement, hashing to curves
|
||||
- 🔖 SUF-CMA, SBS (non-repudiation), ZIP215 (consensus friendliness) features for ed25519
|
||||
- #️⃣ hash-to-curve for encoding or hashing an arbitrary string to an elliptic curve point
|
||||
- 🧜♂️ Poseidon ZK-friendly hash
|
||||
- 🪶 178KB for everything, 25KB for single-curve build
|
||||
|
||||
### This library belongs to _noble_ crypto
|
||||
For discussions, questions and support, visit
|
||||
[GitHub Discussions](https://github.com/paulmillr/noble-curves/discussions)
|
||||
section of the repository.
|
||||
|
||||
> **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
||||
### This library belongs to _noble_ cryptography
|
||||
|
||||
> **noble cryptography** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
||||
|
||||
- Zero or minimal dependencies
|
||||
- Highly readable TypeScript / JS code
|
||||
@ -22,7 +26,10 @@ Audited & minimal JS implementation of elliptic curve cryptography.
|
||||
- All libraries:
|
||||
[ciphers](https://github.com/paulmillr/noble-ciphers),
|
||||
[curves](https://github.com/paulmillr/noble-curves),
|
||||
[hashes](https://github.com/paulmillr/noble-hashes)
|
||||
[hashes](https://github.com/paulmillr/noble-hashes),
|
||||
[post-quantum](https://github.com/paulmillr/noble-post-quantum),
|
||||
4kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /
|
||||
[ed25519](https://github.com/paulmillr/noble-ed25519)
|
||||
- [Check out homepage](https://paulmillr.com/noble/)
|
||||
for reading resources, documentation and apps built with noble
|
||||
|
||||
@ -38,7 +45,7 @@ A standalone file [noble-curves.js](https://github.com/paulmillr/noble-curves/re
|
||||
```js
|
||||
// import * from '@noble/curves'; // Error: use sub-imports, to ensure small app size
|
||||
import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
|
||||
// import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
|
||||
// import { secp256k1 } from 'npm:@noble/curves@1.4.0/secp256k1'; // Deno
|
||||
```
|
||||
|
||||
- [Implementations](#implementations)
|
||||
@ -239,7 +246,7 @@ Same RFC7748 / RFC8032 / IRTF draft are followed.
|
||||
|
||||
#### bls12-381
|
||||
|
||||
See [abstract/bls](#abstractbls-barreto-lynn-scott-curves).
|
||||
See [abstract/bls](#bls-barreto-lynn-scott-curves).
|
||||
|
||||
#### All available imports
|
||||
|
||||
@ -548,7 +555,7 @@ import { Field } from '@noble/curves/abstract/modular';
|
||||
const x25519 = montgomery({
|
||||
a: 486662n,
|
||||
Gu: 9n,
|
||||
Fp: Field(2n ** 255n - 19n),
|
||||
P: 2n ** 255n - 19n,
|
||||
montgomeryBits: 255,
|
||||
nByteLength: 32,
|
||||
// Optional param
|
||||
@ -606,6 +613,12 @@ const signature = bls.sign(message, privateKey);
|
||||
const isValid = bls.verify(signature, message, publicKey);
|
||||
console.log({ publicKey, signature, isValid });
|
||||
|
||||
// Use custom DST, e.g. for Ethereum consensus layer
|
||||
const htfEthereum = {DST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_'};
|
||||
const signatureEth = bls.sign(message, privateKey, htfEthereum);
|
||||
const isValidEth = bls.verify(signature, message, publicKey, htfEthereum);
|
||||
console.log({ signatureEth, isValidEth });
|
||||
|
||||
// Sign 1 msg with 3 keys
|
||||
const privateKeys = [
|
||||
'18f020b98eb798752a50ed0563b079c125b0db5dd0b1060d1c1b47d4a193e1e4',
|
||||
@ -758,7 +771,7 @@ and [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380#section-5.2).
|
||||
This means, for 32-byte key, we would need 48-byte hash to get 2^-128 bias, which matches curve security level.
|
||||
|
||||
`hashToPrivateScalar()` that hashes to **private key** was created for this purpose.
|
||||
Use [abstract/hash-to-curve](#abstracthash-to-curve-hashing-strings-to-curve-points)
|
||||
Use [abstract/hash-to-curve](#hash-to-curve-hashing-strings-to-curve-points)
|
||||
if you need to hash to **public key**.
|
||||
|
||||
```ts
|
||||
|
@ -1,7 +1,7 @@
|
||||
# build
|
||||
|
||||
The directory is used to build a single file `noble-curves.js` which contains everything.
|
||||
The directory is used to build a single file which contains everything.
|
||||
|
||||
The output file uses iife wrapper and can be used in browsers as-is.
|
||||
The single file uses iife wrapper and can be used in browsers as-is.
|
||||
|
||||
Don't use it unless you can't use NPM/ESM, which support tree shaking.
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytesToHex, concatBytes, hexToBytes } from '@noble/curves/abstract/utils';
|
||||
import { bytesToHex, concatBytes, hexToBytes, utf8ToBytes } from '@noble/curves/abstract/utils';
|
||||
|
||||
export { secp256k1, schnorr as secp256k1_schnorr } from '@noble/curves/secp256k1';
|
||||
export {
|
||||
@ -17,4 +17,4 @@ export { p384 } from '@noble/curves/p384';
|
||||
export { p521 } from '@noble/curves/p521';
|
||||
export { bls12_381 } from '@noble/curves/bls12-381';
|
||||
|
||||
export const utils = { bytesToHex, concatBytes, hexToBytes };
|
||||
export const utils = { bytesToHex, concatBytes, hexToBytes, utf8ToBytes };
|
||||
|
445
build/package-lock.json
generated
Normal file
445
build/package-lock.json
generated
Normal file
@ -0,0 +1,445 @@
|
||||
{
|
||||
"name": "build",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "build",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@noble/curves": "file:..",
|
||||
"esbuild": "0.20.1"
|
||||
}
|
||||
},
|
||||
"..": {
|
||||
"version": "1.4.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@paulmillr/jsbt": "0.1.0",
|
||||
"fast-check": "3.0.0",
|
||||
"micro-bmark": "0.3.1",
|
||||
"micro-should": "0.4.0",
|
||||
"prettier": "3.1.1",
|
||||
"typescript": "5.3.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz",
|
||||
"integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz",
|
||||
"integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz",
|
||||
"integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz",
|
||||
"integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz",
|
||||
"integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz",
|
||||
"integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz",
|
||||
"integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz",
|
||||
"integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz",
|
||||
"integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz",
|
||||
"integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz",
|
||||
"integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz",
|
||||
"integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz",
|
||||
"integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz",
|
||||
"integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz",
|
||||
"integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz",
|
||||
"integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz",
|
||||
"integrity": "sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz",
|
||||
"integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz",
|
||||
"integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz",
|
||||
"integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz",
|
||||
"integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz",
|
||||
"integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz",
|
||||
"integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/curves": {
|
||||
"resolved": "..",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz",
|
||||
"integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.20.1",
|
||||
"@esbuild/android-arm": "0.20.1",
|
||||
"@esbuild/android-arm64": "0.20.1",
|
||||
"@esbuild/android-x64": "0.20.1",
|
||||
"@esbuild/darwin-arm64": "0.20.1",
|
||||
"@esbuild/darwin-x64": "0.20.1",
|
||||
"@esbuild/freebsd-arm64": "0.20.1",
|
||||
"@esbuild/freebsd-x64": "0.20.1",
|
||||
"@esbuild/linux-arm": "0.20.1",
|
||||
"@esbuild/linux-arm64": "0.20.1",
|
||||
"@esbuild/linux-ia32": "0.20.1",
|
||||
"@esbuild/linux-loong64": "0.20.1",
|
||||
"@esbuild/linux-mips64el": "0.20.1",
|
||||
"@esbuild/linux-ppc64": "0.20.1",
|
||||
"@esbuild/linux-riscv64": "0.20.1",
|
||||
"@esbuild/linux-s390x": "0.20.1",
|
||||
"@esbuild/linux-x64": "0.20.1",
|
||||
"@esbuild/netbsd-x64": "0.20.1",
|
||||
"@esbuild/openbsd-x64": "0.20.1",
|
||||
"@esbuild/sunos-x64": "0.20.1",
|
||||
"@esbuild/win32-arm64": "0.20.1",
|
||||
"@esbuild/win32-ia32": "0.20.1",
|
||||
"@esbuild/win32-x64": "0.20.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,17 +2,13 @@
|
||||
"name": "build",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"description": "Used to build a single file",
|
||||
"main": "input.js",
|
||||
"keywords": [],
|
||||
"type": "module",
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@noble/curves": "..",
|
||||
"esbuild": "0.18.11"
|
||||
"@noble/curves": "file:..",
|
||||
"esbuild": "0.20.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npx esbuild --bundle input.js --outfile=noble-curves.js --global-name=nobleCurves"
|
||||
"build:release": "npx esbuild --bundle input.js --outfile=`npx jsbt outfile` --global-name=`npx jsbt global`"
|
||||
}
|
||||
}
|
||||
|
26
package-lock.json
generated
26
package-lock.json
generated
@ -1,17 +1,18 @@
|
||||
{
|
||||
"name": "@noble/curves",
|
||||
"version": "1.3.0",
|
||||
"name": "@tornado/noble-curves",
|
||||
"version": "1.4.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@noble/curves",
|
||||
"version": "1.3.0",
|
||||
"name": "@tornado/noble-curves",
|
||||
"version": "1.4.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.3"
|
||||
"@noble/hashes": "1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@paulmillr/jsbt": "0.1.0",
|
||||
"fast-check": "3.0.0",
|
||||
"micro-bmark": "0.3.1",
|
||||
"micro-should": "0.4.0",
|
||||
@ -23,9 +24,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/hashes": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz",
|
||||
"integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
|
||||
"integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
@ -33,6 +34,15 @@
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@paulmillr/jsbt": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@paulmillr/jsbt/-/jsbt-0.1.0.tgz",
|
||||
"integrity": "sha512-TdowoHD36hkZARv6LW4jenkVTdK2vP0sy4ZM8E9MxaqAAIRdwmn3RlB+zWkEHi4hKTgLqMGkURfNkFtt0STX2Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"jsbt": "jsbt.js"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-check": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.0.0.tgz",
|
||||
|
11
package.json
11
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@noble/curves",
|
||||
"version": "1.3.0",
|
||||
"name": "@tornado/noble-curves",
|
||||
"version": "1.4.0",
|
||||
"description": "Audited & minimal JS implementation of elliptic curve cryptography",
|
||||
"files": [
|
||||
"abstract",
|
||||
@ -14,7 +14,7 @@
|
||||
"scripts": {
|
||||
"bench": "cd benchmark; node secp256k1.js; node curves.js; node ecdh.js; node hash-to-curve.js; node modular.js; node bls.js; node ristretto255.js; node decaf448.js",
|
||||
"build": "tsc && tsc -p tsconfig.esm.json",
|
||||
"build:release": "cd build; npm install && npm run build",
|
||||
"build:release": "cd build && npm i && npm run build",
|
||||
"build:clean": "rm *.{js,d.ts,d.ts.map,js.map} esm/*.{js,d.ts,d.ts.map,js.map} 2> /dev/null",
|
||||
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
|
||||
"format": "prettier --write 'src/**/*.{js,ts}' 'test/*.js'",
|
||||
@ -24,13 +24,14 @@
|
||||
"homepage": "https://paulmillr.com/noble/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/paulmillr/noble-curves.git"
|
||||
"url": "https://git.tornado.ws/tornado-packages/noble-curvest"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.3"
|
||||
"@noble/hashes": "1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@paulmillr/jsbt": "0.1.0",
|
||||
"fast-check": "3.0.0",
|
||||
"micro-bmark": "0.3.1",
|
||||
"micro-should": "0.4.0",
|
||||
|
@ -83,12 +83,12 @@ export type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
||||
getPublicKey: (privateKey: PrivKey) => Uint8Array;
|
||||
getPublicKeyForShortSignatures: (privateKey: PrivKey) => Uint8Array;
|
||||
sign: {
|
||||
(message: Hex, privateKey: PrivKey): Uint8Array;
|
||||
(message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
|
||||
(message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
|
||||
(message: ProjPointType<Fp2>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp2>;
|
||||
};
|
||||
signShortSignature: {
|
||||
(message: Hex, privateKey: PrivKey): Uint8Array;
|
||||
(message: ProjPointType<Fp>, privateKey: PrivKey): ProjPointType<Fp>;
|
||||
(message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
|
||||
(message: ProjPointType<Fp>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp>;
|
||||
};
|
||||
verify: (
|
||||
signature: Hex | ProjPointType<Fp2>,
|
||||
|
@ -2,7 +2,7 @@
|
||||
import type { Group, GroupConstructor, AffinePoint } from './curve.js';
|
||||
import { mod, IField } from './modular.js';
|
||||
import type { CHash } from './utils.js';
|
||||
import { bytesToNumberBE, isBytes, concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
||||
import { bytesToNumberBE, abytes, concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
||||
|
||||
/**
|
||||
* * `DST` is a domain separation tag, defined in section 2.2.5
|
||||
@ -22,12 +22,6 @@ export type Opts = {
|
||||
hash: CHash;
|
||||
};
|
||||
|
||||
function validateDST(dst: UnicodeOrBytes): Uint8Array {
|
||||
if (isBytes(dst)) return dst;
|
||||
if (typeof dst === 'string') return utf8ToBytes(dst);
|
||||
throw new Error('DST must be Uint8Array or string');
|
||||
}
|
||||
|
||||
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
||||
const os2ip = bytesToNumberBE;
|
||||
|
||||
@ -52,10 +46,7 @@ function strxor(a: Uint8Array, b: Uint8Array): Uint8Array {
|
||||
return arr;
|
||||
}
|
||||
|
||||
function abytes(item: unknown): void {
|
||||
if (!isBytes(item)) throw new Error('Uint8Array expected');
|
||||
}
|
||||
function isNum(item: unknown): void {
|
||||
function anum(item: unknown): void {
|
||||
if (!Number.isSafeInteger(item)) throw new Error('number expected');
|
||||
}
|
||||
|
||||
@ -69,7 +60,7 @@ export function expand_message_xmd(
|
||||
): Uint8Array {
|
||||
abytes(msg);
|
||||
abytes(DST);
|
||||
isNum(lenInBytes);
|
||||
anum(lenInBytes);
|
||||
// https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
|
||||
if (DST.length > 255) DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST));
|
||||
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
||||
@ -103,7 +94,7 @@ export function expand_message_xof(
|
||||
): Uint8Array {
|
||||
abytes(msg);
|
||||
abytes(DST);
|
||||
isNum(lenInBytes);
|
||||
anum(lenInBytes);
|
||||
// https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
|
||||
// DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8));
|
||||
if (DST.length > 255) {
|
||||
@ -141,8 +132,8 @@ export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bi
|
||||
});
|
||||
const { p, k, m, hash, expand, DST: _DST } = options;
|
||||
abytes(msg);
|
||||
isNum(count);
|
||||
const DST = validateDST(_DST);
|
||||
anum(count);
|
||||
const DST = typeof _DST === 'string' ? utf8ToBytes(_DST) : _DST;
|
||||
const log2p = p.toString(2).length;
|
||||
const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
|
||||
const len_in_bytes = count * m * L;
|
||||
|
@ -23,6 +23,10 @@ export function isBytes(a: unknown): a is Uint8Array {
|
||||
);
|
||||
}
|
||||
|
||||
export function abytes(item: unknown): void {
|
||||
if (!isBytes(item)) throw new Error('Uint8Array expected');
|
||||
}
|
||||
|
||||
// Array where index 0xf0 (240) is mapped to string 'f0'
|
||||
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
|
||||
i.toString(16).padStart(2, '0')
|
||||
@ -31,7 +35,7 @@ const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
|
||||
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
||||
*/
|
||||
export function bytesToHex(bytes: Uint8Array): string {
|
||||
if (!isBytes(bytes)) throw new Error('Uint8Array expected');
|
||||
abytes(bytes);
|
||||
// pre-caching improves the speed 6x
|
||||
let hex = '';
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
@ -86,7 +90,7 @@ export function bytesToNumberBE(bytes: Uint8Array): bigint {
|
||||
return hexToNumber(bytesToHex(bytes));
|
||||
}
|
||||
export function bytesToNumberLE(bytes: Uint8Array): bigint {
|
||||
if (!isBytes(bytes)) throw new Error('Uint8Array expected');
|
||||
abytes(bytes);
|
||||
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
||||
}
|
||||
|
||||
@ -138,7 +142,7 @@ export function concatBytes(...arrays: Uint8Array[]): Uint8Array {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < arrays.length; i++) {
|
||||
const a = arrays[i];
|
||||
if (!isBytes(a)) throw new Error('Uint8Array expected');
|
||||
abytes(a);
|
||||
sum += a.length;
|
||||
}
|
||||
const res = new Uint8Array(sum);
|
||||
@ -194,9 +198,9 @@ export function bitGet(n: bigint, pos: number) {
|
||||
/**
|
||||
* Sets single bit at position.
|
||||
*/
|
||||
export const bitSet = (n: bigint, pos: number, value: boolean) => {
|
||||
export function bitSet(n: bigint, pos: number, value: boolean) {
|
||||
return n | ((value ? _1n : _0n) << BigInt(pos));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
||||
|
@ -27,7 +27,7 @@ export type BasicWCurve<T> = BasicCurve<T> & {
|
||||
clearCofactor?: (c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>;
|
||||
};
|
||||
|
||||
type Entropy = Hex | true;
|
||||
type Entropy = Hex | boolean;
|
||||
export type SignOpts = { lowS?: boolean; extraEntropy?: Entropy; prehash?: boolean };
|
||||
export type VerOpts = { lowS?: boolean; prehash?: boolean };
|
||||
|
||||
@ -158,7 +158,7 @@ export const DER = {
|
||||
// parse DER signature
|
||||
const { Err: E } = DER;
|
||||
const data = typeof hex === 'string' ? h2b(hex) : hex;
|
||||
if (!ut.isBytes(data)) throw new Error('ui8a expected');
|
||||
ut.abytes(data);
|
||||
let l = data.length;
|
||||
if (l < 2 || data[0] != 0x30) throw new E('Invalid signature tag');
|
||||
if (data[1] !== l - 2) throw new E('Invalid signature: incorrect length');
|
||||
@ -977,7 +977,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
const d = normPrivateKeyToScalar(privateKey); // validate private key, convert to bigint
|
||||
const seedArgs = [int2octets(d), int2octets(h1int)];
|
||||
// extraEntropy. RFC6979 3.6: additional k' (optional).
|
||||
if (ent != null) {
|
||||
if (ent != null && ent !== false) {
|
||||
// K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
|
||||
const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is
|
||||
seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes
|
||||
|
@ -1364,7 +1364,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
||||
fromHex(hex: Hex): ProjPointType<Fp2> {
|
||||
const { infinity, sort, value } = parseMask(ensureBytes('signatureHex', hex));
|
||||
const P = Fp.ORDER;
|
||||
const half = hex.length / 2;
|
||||
const half = value.length / 2;
|
||||
if (half !== 48 && half !== 96)
|
||||
throw new Error('Invalid compressed signature length, must be 96 or 192');
|
||||
const z1 = bytesToNumberBE(value.slice(0, half));
|
||||
|
3
src/package.json
Normal file
3
src/package.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
@ -2,7 +2,7 @@ import { deepStrictEqual, throws } from 'assert';
|
||||
import { should, describe } from 'micro-should';
|
||||
import * as fc from 'fast-check';
|
||||
import * as mod from '../esm/abstract/modular.js';
|
||||
import { bytesToHex as toHex } from '../esm/abstract/utils.js';
|
||||
import { bytesToHex, isBytes, bytesToHex as toHex } from '../esm/abstract/utils.js';
|
||||
// Generic tests for all curves in package
|
||||
import { secp192r1, secp224r1 } from './_more-curves.helpers.js';
|
||||
import { secp256r1 } from '../esm/p256.js';
|
||||
@ -595,6 +595,18 @@ for (const name in CURVES) {
|
||||
{ numRuns: NUM_RUNS }
|
||||
)
|
||||
);
|
||||
should('.verify() should verify random signatures in hex', () =>
|
||||
fc.assert(
|
||||
fc.property(fc.hexaString({ minLength: 64, maxLength: 64 }), (msg) => {
|
||||
const priv = toHex(C.utils.randomPrivateKey());
|
||||
const pub = toHex(C.getPublicKey(priv));
|
||||
const sig = C.sign(msg, priv);
|
||||
let sighex = isBytes(sig) ? toHex(sig) : sig.toCompactHex();
|
||||
deepStrictEqual(C.verify(sighex, msg, pub), true, `priv=${priv},pub=${pub},msg=${msg}`);
|
||||
}),
|
||||
{ numRuns: NUM_RUNS }
|
||||
)
|
||||
);
|
||||
should('.verify() should verify empty signatures', () => {
|
||||
const msg = new Uint8Array([]);
|
||||
const priv = C.utils.randomPrivateKey();
|
||||
|
@ -1173,6 +1173,8 @@ describe('verify()', () => {
|
||||
const pub = bls.getPublicKey(priv);
|
||||
const res = bls.verify(sig, msg, pub);
|
||||
deepStrictEqual(res, true, `${priv}-${msg}`);
|
||||
const resHex = bls.verify(bytesToHex(sig), msg, pub);
|
||||
deepStrictEqual(resHex, true, `${priv}-${msg}-hex`);
|
||||
}
|
||||
});
|
||||
should('not verify signature with wrong message', () => {
|
||||
@ -1193,6 +1195,8 @@ describe('verify()', () => {
|
||||
const invPub = bls.getPublicKey(invPriv);
|
||||
const res = bls.verify(sig, msg, invPub);
|
||||
deepStrictEqual(res, false);
|
||||
const resHex = bls.verify(bytesToHex(sig), msg, invPub);
|
||||
deepStrictEqual(resHex, false);
|
||||
}
|
||||
});
|
||||
should('verify signed message (short signatures)', () => {
|
||||
@ -1202,6 +1206,8 @@ describe('verify()', () => {
|
||||
const pub = bls.getPublicKeyForShortSignatures(priv);
|
||||
const res = bls.verifyShortSignature(sig, msg, pub);
|
||||
deepStrictEqual(res, true, `${priv}-${msg}`);
|
||||
const resHex = bls.verifyShortSignature(bytesToHex(sig), msg, pub);
|
||||
deepStrictEqual(resHex, true, `${priv}-${msg}`);
|
||||
}
|
||||
});
|
||||
should('not verify signature with wrong message (short signatures)', () => {
|
||||
@ -1212,6 +1218,8 @@ describe('verify()', () => {
|
||||
const pub = bls.getPublicKeyForShortSignatures(priv);
|
||||
const res = bls.verifyShortSignature(sig, invMsg, pub);
|
||||
deepStrictEqual(res, false);
|
||||
const resHex = bls.verifyShortSignature(bytesToHex(sig), invMsg, pub);
|
||||
deepStrictEqual(resHex, false);
|
||||
}
|
||||
});
|
||||
should('not verify signature with wrong key', () => {
|
||||
@ -1222,6 +1230,8 @@ describe('verify()', () => {
|
||||
const invPub = bls.getPublicKeyForShortSignatures(invPriv);
|
||||
const res = bls.verifyShortSignature(sig, msg, invPub);
|
||||
deepStrictEqual(res, false);
|
||||
const resHex = bls.verifyShortSignature(bytesToHex(sig), msg, invPub);
|
||||
deepStrictEqual(resHex, false);
|
||||
}
|
||||
});
|
||||
describe('batch', () => {
|
||||
@ -1234,6 +1244,10 @@ describe('verify()', () => {
|
||||
const signatures = messages.map((message, i) => bls.sign(message, privateKeys[i]));
|
||||
const aggregatedSignature = bls.aggregateSignatures(signatures);
|
||||
deepStrictEqual(bls.verifyBatch(aggregatedSignature, messages, publicKey), true);
|
||||
deepStrictEqual(
|
||||
bls.verifyBatch(bytesToHex(aggregatedSignature), messages, publicKey),
|
||||
true
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -1252,6 +1266,10 @@ describe('verify()', () => {
|
||||
bls.verifyBatch(aggregatedSignature, wrongMessages, publicKey),
|
||||
messages.every((m, i) => m === wrongMessages[i])
|
||||
);
|
||||
deepStrictEqual(
|
||||
bls.verifyBatch(bytesToHex(aggregatedSignature), wrongMessages, publicKey),
|
||||
messages.every((m, i) => m === wrongMessages[i])
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -1274,6 +1292,10 @@ describe('verify()', () => {
|
||||
bls.verifyBatch(aggregatedSignature, messages, wrongPublicKeys),
|
||||
wrongPrivateKeys.every((p, i) => p === privateKeys[i])
|
||||
);
|
||||
deepStrictEqual(
|
||||
bls.verifyBatch(bytesToHex(aggregatedSignature), messages, wrongPublicKeys),
|
||||
wrongPrivateKeys.every((p, i) => p === privateKeys[i])
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
@ -1287,6 +1309,10 @@ describe('verify()', () => {
|
||||
const aggregatedSignature = bls.aggregateSignatures(signatures);
|
||||
const aggregatedPublicKey = bls.aggregatePublicKeys(publicKey);
|
||||
deepStrictEqual(bls.verify(aggregatedSignature, message, aggregatedPublicKey), true);
|
||||
deepStrictEqual(
|
||||
bls.verify(bytesToHex(aggregatedSignature), message, aggregatedPublicKey),
|
||||
true
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -1302,6 +1328,10 @@ describe('verify()', () => {
|
||||
bls.verify(aggregatedSignature, wrongMessage, aggregatedPublicKey),
|
||||
message === wrongMessage
|
||||
);
|
||||
deepStrictEqual(
|
||||
bls.verify(bytesToHex(aggregatedSignature), wrongMessage, aggregatedPublicKey),
|
||||
message === wrongMessage
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -1,25 +1,9 @@
|
||||
{
|
||||
"extends": "@paulmillr/jsbt/tsconfigs/esm.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2020",
|
||||
"lib": ["es2020"],
|
||||
"strict": true,
|
||||
"sourceMap": true,
|
||||
"allowSyntheticDefaultImports": false,
|
||||
"allowUnreachableCode": false,
|
||||
"esModuleInterop": false,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUncheckedIndexedAccess": false,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@noble/hashes/crypto": ["src/crypto"]
|
||||
},
|
||||
"module": "es2020",
|
||||
"outDir": "esm",
|
||||
"moduleResolution": "bundler"
|
||||
"target": "ES2015"
|
||||
},
|
||||
"include": ["src"],
|
||||
"include": ["index.ts", "src"],
|
||||
"exclude": ["node_modules", "lib"]
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.esm.json",
|
||||
"extends": "@paulmillr/jsbt/tsconfigs/cjs.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node10",
|
||||
"outDir": ".",
|
||||
"declaration": true,
|
||||
"declarationMap": true
|
||||
}
|
||||
"target": "ES2015"
|
||||
},
|
||||
"include": ["index.ts", "src"],
|
||||
"exclude": ["node_modules", "lib"]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user