@noble/bls12-381
Advanced tools
Comparing version 1.1.2 to 1.2.0
@@ -26,2 +26,3 @@ /*! noble-bls12-381 - MIT License (c) Paul Miller (paulmillr.com) */ | ||
hashToField: hash_to_field, | ||
bytesToHex, | ||
randomBytes: (bytesLength = 32) => { | ||
@@ -79,6 +80,7 @@ if (crypto.web) { | ||
} | ||
const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0')); | ||
function bytesToHex(uint8a) { | ||
let hex = ''; | ||
for (let i = 0; i < uint8a.length; i++) { | ||
hex += uint8a[i].toString(16).padStart(2, '0'); | ||
hex += hexes[uint8a[i]]; | ||
} | ||
@@ -96,3 +98,9 @@ return hex; | ||
const j = i * 2; | ||
array[i] = Number.parseInt(hex.slice(j, j + 2), 16); | ||
const hexByte = hex.slice(j, j + 2); | ||
if (hexByte.length !== 2) | ||
throw new Error('Invalid byte sequence'); | ||
const byte = Number.parseInt(hexByte, 16); | ||
if (Number.isNaN(byte)) | ||
throw new Error('Invalid byte sequence'); | ||
array[i] = byte; | ||
} | ||
@@ -310,3 +318,4 @@ return array; | ||
clearCofactor() { | ||
return this.multiplyUnsafe(CURVE.h); | ||
const t = this.mulCurveMinusX(); | ||
return t.add(this); | ||
} | ||
@@ -325,11 +334,16 @@ isOnCurve() { | ||
} | ||
phi() { | ||
const cubicRootOfUnityModP = 0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen; | ||
return new PointG1(this.x.multiply(cubicRootOfUnityModP), this.y, this.z); | ||
} | ||
mulCurveX() { | ||
return this.multiplyUnsafe(CURVE.x).negate(); | ||
} | ||
mulCurveMinusX() { | ||
return this.multiplyUnsafe(CURVE.x); | ||
} | ||
isTorsionFree() { | ||
const c1 = 0x396c8c005555e1560000000055555555n; | ||
const P = this; | ||
const S = P.sigma(); | ||
const Q = S.double(); | ||
const S2 = S.sigma(); | ||
const left = Q.subtract(P).subtract(S2).multiplyUnsafe(c1); | ||
const C = left.subtract(S2); | ||
return C.isZero(); | ||
const xP = this.mulCurveX(); | ||
const u2P = xP.mulCurveMinusX(); | ||
return u2P.equals(this.phi()); | ||
} | ||
@@ -411,3 +425,4 @@ } | ||
const sum = POW_2_383 + POW_2_382; | ||
return toPaddedHex(sum, PUBLIC_KEY_LENGTH) + toPaddedHex(0n, PUBLIC_KEY_LENGTH); | ||
const h = toPaddedHex(sum, PUBLIC_KEY_LENGTH) + toPaddedHex(0n, PUBLIC_KEY_LENGTH); | ||
return hexToBytes(h); | ||
} | ||
@@ -419,3 +434,3 @@ const [[x0, x1], [y0, y1]] = this.toAffine().map((a) => a.values); | ||
const z2 = x0; | ||
return toPaddedHex(z1, PUBLIC_KEY_LENGTH) + toPaddedHex(z2, PUBLIC_KEY_LENGTH); | ||
return hexToBytes(toPaddedHex(z1, PUBLIC_KEY_LENGTH) + toPaddedHex(z2, PUBLIC_KEY_LENGTH)); | ||
} | ||
@@ -456,3 +471,3 @@ toRawBytes(isCompressed = false) { | ||
} | ||
mulNegX() { | ||
mulCurveX() { | ||
return this.multiplyUnsafe(CURVE.x).negate(); | ||
@@ -462,3 +477,3 @@ } | ||
const P = this; | ||
let t1 = P.mulNegX(); | ||
let t1 = P.mulCurveX(); | ||
let t2 = P.psi(); | ||
@@ -469,3 +484,3 @@ let t3 = P.double(); | ||
t2 = t1.add(t2); | ||
t2 = t2.mulNegX(); | ||
t2 = t2.mulCurveX(); | ||
t3 = t3.add(t2); | ||
@@ -485,6 +500,3 @@ t3 = t3.subtract(t1); | ||
const P = this; | ||
const psi2 = P.psi2(); | ||
const psi3 = psi2.psi(); | ||
const zPsi3 = psi3.mulNegX(); | ||
return zPsi3.subtract(psi2).add(P).isZero(); | ||
return P.mulCurveX().equals(P.psi()); | ||
} | ||
@@ -524,4 +536,3 @@ [Symbol.for('nodejs.util.inspect.custom')]() { | ||
export function getPublicKey(privateKey) { | ||
const bytes = PointG1.fromPrivateKey(privateKey).toRawBytes(true); | ||
return typeof privateKey === 'string' ? bytesToHex(bytes) : bytes; | ||
return PointG1.fromPrivateKey(privateKey).toRawBytes(true); | ||
} | ||
@@ -534,4 +545,3 @@ export async function sign(message, privateKey) { | ||
return sigPoint; | ||
const hex = sigPoint.toSignature(); | ||
return typeof message === 'string' ? hex : hexToBytes(hex); | ||
return sigPoint.toSignature(); | ||
} | ||
@@ -554,6 +564,3 @@ export async function verify(signature, message, publicKey) { | ||
return agg.assertValidity(); | ||
const bytes = agg.toRawBytes(true); | ||
if (publicKeys[0] instanceof Uint8Array) | ||
return bytes; | ||
return bytesToHex(bytes); | ||
return agg.toRawBytes(true); | ||
} | ||
@@ -566,6 +573,3 @@ export function aggregateSignatures(signatures) { | ||
return agg.assertValidity(); | ||
const bytes = agg.toSignature(); | ||
if (signatures[0] instanceof Uint8Array) | ||
return hexToBytes(bytes); | ||
return bytes; | ||
return agg.toSignature(); | ||
} | ||
@@ -572,0 +576,0 @@ export async function verifyBatch(signature, messages, publicKeys) { |
@@ -8,2 +8,3 @@ /*! noble-bls12-381 - MIT License (c) Paul Miller (paulmillr.com) */ | ||
hashToField: typeof hash_to_field; | ||
bytesToHex: typeof bytesToHex; | ||
randomBytes: (bytesLength?: number) => Uint8Array; | ||
@@ -16,2 +17,3 @@ randomPrivateKey: () => Uint8Array; | ||
}; | ||
declare function bytesToHex(uint8a: Uint8Array): string; | ||
declare function hash_to_field(msg: Uint8Array, count: number, options?: {}): Promise<bigint[][]>; | ||
@@ -28,5 +30,8 @@ export declare class PointG1 extends ProjectivePoint<Fp> { | ||
millerLoop(P: PointG2): Fp12; | ||
clearCofactor(): this; | ||
clearCofactor(): PointG1; | ||
private isOnCurve; | ||
private sigma; | ||
private phi; | ||
private mulCurveX; | ||
private mulCurveMinusX; | ||
private isTorsionFree; | ||
@@ -43,3 +48,3 @@ } | ||
static fromPrivateKey(privateKey: PrivateKey): PointG2; | ||
toSignature(): string; | ||
toSignature(): Uint8Array; | ||
toRawBytes(isCompressed?: boolean): Uint8Array; | ||
@@ -50,3 +55,3 @@ toHex(isCompressed?: boolean): string; | ||
private psi2; | ||
private mulNegX; | ||
private mulCurveX; | ||
clearCofactor(): PointG2; | ||
@@ -61,14 +66,10 @@ private isOnCurve; | ||
declare type G2Hex = Bytes | PointG2; | ||
export declare function getPublicKey(privateKey: Uint8Array | bigint): Uint8Array; | ||
export declare function getPublicKey(privateKey: string): string; | ||
export declare function sign(message: Uint8Array, privateKey: PrivateKey): Promise<Uint8Array>; | ||
export declare function sign(message: string, privateKey: PrivateKey): Promise<string>; | ||
export declare function getPublicKey(privateKey: PrivateKey): Uint8Array; | ||
export declare function sign(message: Bytes, privateKey: PrivateKey): Promise<Uint8Array>; | ||
export declare function sign(message: PointG2, privateKey: PrivateKey): Promise<PointG2>; | ||
export declare function verify(signature: G2Hex, message: G2Hex, publicKey: G1Hex): Promise<boolean>; | ||
export declare function aggregatePublicKeys(publicKeys: Uint8Array[]): Uint8Array; | ||
export declare function aggregatePublicKeys(publicKeys: string[]): string; | ||
export declare function aggregatePublicKeys(publicKeys: Bytes[]): Uint8Array; | ||
export declare function aggregatePublicKeys(publicKeys: PointG1[]): PointG1; | ||
export declare function aggregateSignatures(signatures: Uint8Array[]): Uint8Array; | ||
export declare function aggregateSignatures(signatures: string[]): string; | ||
export declare function aggregateSignatures(signatures: Bytes[]): Uint8Array; | ||
export declare function aggregateSignatures(signatures: PointG2[]): PointG2; | ||
export declare function verifyBatch(signature: G2Hex, messages: G2Hex[], publicKeys: G1Hex[]): Promise<boolean>; |
@@ -36,2 +36,3 @@ "use strict"; | ||
hashToField: hash_to_field, | ||
bytesToHex, | ||
randomBytes: (bytesLength = 32) => { | ||
@@ -89,6 +90,7 @@ if (crypto.web) { | ||
} | ||
const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0')); | ||
function bytesToHex(uint8a) { | ||
let hex = ''; | ||
for (let i = 0; i < uint8a.length; i++) { | ||
hex += uint8a[i].toString(16).padStart(2, '0'); | ||
hex += hexes[uint8a[i]]; | ||
} | ||
@@ -106,3 +108,9 @@ return hex; | ||
const j = i * 2; | ||
array[i] = Number.parseInt(hex.slice(j, j + 2), 16); | ||
const hexByte = hex.slice(j, j + 2); | ||
if (hexByte.length !== 2) | ||
throw new Error('Invalid byte sequence'); | ||
const byte = Number.parseInt(hexByte, 16); | ||
if (Number.isNaN(byte)) | ||
throw new Error('Invalid byte sequence'); | ||
array[i] = byte; | ||
} | ||
@@ -320,3 +328,4 @@ return array; | ||
clearCofactor() { | ||
return this.multiplyUnsafe(math_js_1.CURVE.h); | ||
const t = this.mulCurveMinusX(); | ||
return t.add(this); | ||
} | ||
@@ -335,11 +344,16 @@ isOnCurve() { | ||
} | ||
phi() { | ||
const cubicRootOfUnityModP = 0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen; | ||
return new PointG1(this.x.multiply(cubicRootOfUnityModP), this.y, this.z); | ||
} | ||
mulCurveX() { | ||
return this.multiplyUnsafe(math_js_1.CURVE.x).negate(); | ||
} | ||
mulCurveMinusX() { | ||
return this.multiplyUnsafe(math_js_1.CURVE.x); | ||
} | ||
isTorsionFree() { | ||
const c1 = 0x396c8c005555e1560000000055555555n; | ||
const P = this; | ||
const S = P.sigma(); | ||
const Q = S.double(); | ||
const S2 = S.sigma(); | ||
const left = Q.subtract(P).subtract(S2).multiplyUnsafe(c1); | ||
const C = left.subtract(S2); | ||
return C.isZero(); | ||
const xP = this.mulCurveX(); | ||
const u2P = xP.mulCurveMinusX(); | ||
return u2P.equals(this.phi()); | ||
} | ||
@@ -422,3 +436,4 @@ } | ||
const sum = POW_2_383 + POW_2_382; | ||
return toPaddedHex(sum, PUBLIC_KEY_LENGTH) + toPaddedHex(0n, PUBLIC_KEY_LENGTH); | ||
const h = toPaddedHex(sum, PUBLIC_KEY_LENGTH) + toPaddedHex(0n, PUBLIC_KEY_LENGTH); | ||
return hexToBytes(h); | ||
} | ||
@@ -430,3 +445,3 @@ const [[x0, x1], [y0, y1]] = this.toAffine().map((a) => a.values); | ||
const z2 = x0; | ||
return toPaddedHex(z1, PUBLIC_KEY_LENGTH) + toPaddedHex(z2, PUBLIC_KEY_LENGTH); | ||
return hexToBytes(toPaddedHex(z1, PUBLIC_KEY_LENGTH) + toPaddedHex(z2, PUBLIC_KEY_LENGTH)); | ||
} | ||
@@ -467,3 +482,3 @@ toRawBytes(isCompressed = false) { | ||
} | ||
mulNegX() { | ||
mulCurveX() { | ||
return this.multiplyUnsafe(math_js_1.CURVE.x).negate(); | ||
@@ -473,3 +488,3 @@ } | ||
const P = this; | ||
let t1 = P.mulNegX(); | ||
let t1 = P.mulCurveX(); | ||
let t2 = P.psi(); | ||
@@ -480,3 +495,3 @@ let t3 = P.double(); | ||
t2 = t1.add(t2); | ||
t2 = t2.mulNegX(); | ||
t2 = t2.mulCurveX(); | ||
t3 = t3.add(t2); | ||
@@ -496,6 +511,3 @@ t3 = t3.subtract(t1); | ||
const P = this; | ||
const psi2 = P.psi2(); | ||
const psi3 = psi2.psi(); | ||
const zPsi3 = psi3.mulNegX(); | ||
return zPsi3.subtract(psi2).add(P).isZero(); | ||
return P.mulCurveX().equals(P.psi()); | ||
} | ||
@@ -537,4 +549,3 @@ [Symbol.for('nodejs.util.inspect.custom')]() { | ||
function getPublicKey(privateKey) { | ||
const bytes = PointG1.fromPrivateKey(privateKey).toRawBytes(true); | ||
return typeof privateKey === 'string' ? bytesToHex(bytes) : bytes; | ||
return PointG1.fromPrivateKey(privateKey).toRawBytes(true); | ||
} | ||
@@ -548,4 +559,3 @@ exports.getPublicKey = getPublicKey; | ||
return sigPoint; | ||
const hex = sigPoint.toSignature(); | ||
return typeof message === 'string' ? hex : hexToBytes(hex); | ||
return sigPoint.toSignature(); | ||
} | ||
@@ -570,6 +580,3 @@ exports.sign = sign; | ||
return agg.assertValidity(); | ||
const bytes = agg.toRawBytes(true); | ||
if (publicKeys[0] instanceof Uint8Array) | ||
return bytes; | ||
return bytesToHex(bytes); | ||
return agg.toRawBytes(true); | ||
} | ||
@@ -583,6 +590,3 @@ exports.aggregatePublicKeys = aggregatePublicKeys; | ||
return agg.assertValidity(); | ||
const bytes = agg.toSignature(); | ||
if (signatures[0] instanceof Uint8Array) | ||
return hexToBytes(bytes); | ||
return bytes; | ||
return agg.toSignature(); | ||
} | ||
@@ -589,0 +593,0 @@ exports.aggregateSignatures = aggregateSignatures; |
{ | ||
"name": "@noble/bls12-381", | ||
"version": "1.1.2", | ||
"version": "1.2.0", | ||
"description": "Fastest JS implementation of BLS12-381. Auditable, secure, 0-dependency aggregated signatures & pairings", | ||
@@ -19,3 +19,3 @@ "files": [ | ||
"author": "Paul Miller (https://paulmillr.com)", | ||
"homepage": "https://github.com/paulmillr/noble-bls12-381", | ||
"homepage": "https://paulmillr.com/noble/", | ||
"repository": { | ||
@@ -40,3 +40,3 @@ "type": "git", | ||
"ts-jest": "^27", | ||
"typescript": "^4.4" | ||
"typescript": "4.5.4" | ||
}, | ||
@@ -43,0 +43,0 @@ "keywords": [ |
@@ -25,3 +25,3 @@ # noble-bls12-381 ![Node CI](https://github.com/paulmillr/noble-secp256k1/workflows/Node%20CI/badge.svg) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) | ||
- All releases are signed with PGP keys | ||
- Check out all libraries: | ||
- Check out [homepage](https://paulmillr.com/noble/) & all libraries: | ||
[secp256k1](https://github.com/paulmillr/noble-secp256k1), | ||
@@ -120,4 +120,3 @@ [ed25519](https://github.com/paulmillr/noble-ed25519), | ||
```typescript | ||
function getPublicKey(privateKey: Uint8Array | bigint): Uint8Array; | ||
function getPublicKey(privateKey: string): string; | ||
function getPublicKey(privateKey: Uint8Array | string | bigint): Uint8Array; | ||
``` | ||
@@ -133,4 +132,3 @@ - `privateKey: Uint8Array | string | bigint` will be used to generate public key. | ||
```typescript | ||
function sign(message: Uint8Array, privateKey: Uint8Array): Promise<Uint8Array>; | ||
function sign(message: string, privateKey: string): Promise<Uint8Array>; | ||
function sign(message: Uint8Array | string, privateKey: Uint8Array | string): Promise<Uint8Array>; | ||
function sign(message: PointG2, privateKey: Uint8Array | string | bigint): Promise<PointG2>; | ||
@@ -159,4 +157,3 @@ ``` | ||
```typescript | ||
function aggregatePublicKeys(publicKeys: Uint8Array[]): Uint8Array; | ||
function aggregatePublicKeys(publicKeys: string[]): string; | ||
function aggregatePublicKeys(publicKeys: (Uint8Array | string)[]): Uint8Array; | ||
function aggregatePublicKeys(publicKeys: PointG1[]): PointG1; | ||
@@ -169,4 +166,3 @@ ``` | ||
```typescript | ||
function aggregateSignatures(signatures: Uint8Array[]): Uint8Array; | ||
function aggregateSignatures(signatures: string[]): string; | ||
function aggregateSignatures(signatures: (Uint8Array | string)[]): Uint8Array; | ||
function aggregateSignatures(signatures: PointG2[]): PointG2; | ||
@@ -205,2 +201,4 @@ ``` | ||
Use `utils.bytesToHex(str)` to convert byte output to hexademical string. | ||
```typescript | ||
@@ -280,20 +278,20 @@ // characteristic; z + (z⁴ - z² + 1)(z - 1)²/3 | ||
``` | ||
getPublicKey x 598 ops/sec @ 1ms/op | ||
sign x 36 ops/sec @ 27ms/op | ||
verify x 28 ops/sec @ 35ms/op | ||
pairing x 69 ops/sec @ 14ms/op | ||
aggregatePublicKeys/8 x 84 ops/sec @ 11ms/op | ||
aggregateSignatures/8 x 40 ops/sec @ 24ms/op | ||
getPublicKey x 737 ops/sec @ 1ms/op | ||
sign x 37 ops/sec @ 26ms/op | ||
verify x 28 ops/sec @ 34ms/op | ||
pairing x 70 ops/sec @ 14ms/op | ||
aggregatePublicKeys/8 x 102 ops/sec @ 9ms/op | ||
aggregateSignatures/8 x 39 ops/sec @ 25ms/op | ||
with compression / decompression disabled: | ||
sign/nc x 54 ops/sec @ 18ms/op | ||
sign/nc x 52 ops/sec @ 18ms/op | ||
verify/nc x 47 ops/sec @ 21ms/op | ||
aggregatePublicKeys/32 x 787 ops/sec @ 1ms/op | ||
aggregatePublicKeys/128 x 558 ops/sec @ 1ms/op | ||
aggregatePublicKeys/512 x 256 ops/sec @ 3ms/op | ||
aggregatePublicKeys/2048 x 81 ops/sec @ 12ms/op | ||
aggregateSignatures/32 x 452 ops/sec @ 2ms/op | ||
aggregateSignatures/128 x 240 ops/sec @ 4ms/op | ||
aggregatePublicKeys/32 x 1,014 ops/sec @ 986μs/op | ||
aggregatePublicKeys/128 x 662 ops/sec @ 1ms/op | ||
aggregatePublicKeys/512 x 278 ops/sec @ 3ms/op | ||
aggregatePublicKeys/2048 x 84 ops/sec @ 11ms/op | ||
aggregateSignatures/32 x 444 ops/sec @ 2ms/op | ||
aggregateSignatures/128 x 236 ops/sec @ 4ms/op | ||
aggregateSignatures/512 x 81 ops/sec @ 12ms/op | ||
aggregateSignatures/2048 x 22 ops/sec @ 43ms/op | ||
aggregateSignatures/2048 x 22 ops/sec @ 44ms/op | ||
``` | ||
@@ -300,0 +298,0 @@ |
147316
3713
318