montgomery: add randomPrivateKey. Add ecdh benchmark.
This commit is contained in:
parent
586e2ad5fb
commit
0fdd763dc7
19
README.md
19
README.md
@ -66,10 +66,6 @@ secp256k1.verify(sig, msg, pub) === true;
|
|||||||
|
|
||||||
const privHex = '46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c126236';
|
const privHex = '46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c126236';
|
||||||
const pub2 = secp256k1.getPublicKey(privHex); // keys & other inputs can be Uint8Array-s or hex strings
|
const pub2 = secp256k1.getPublicKey(privHex); // keys & other inputs can be Uint8Array-s or hex strings
|
||||||
|
|
||||||
// Follows hash-to-curve specification to encode arbitrary hashes to EC points
|
|
||||||
import { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1';
|
|
||||||
hashToCurve('0102abcd');
|
|
||||||
```
|
```
|
||||||
|
|
||||||
All curves:
|
All curves:
|
||||||
@ -180,10 +176,9 @@ const signatures3 = privateKeys.map((p, i) => bls.sign(messages[i], p));
|
|||||||
const aggSignature3 = bls.aggregateSignatures(signatures3);
|
const aggSignature3 = bls.aggregateSignatures(signatures3);
|
||||||
const isValid3 = bls.verifyBatch(aggSignature3, messages, publicKeys);
|
const isValid3 = bls.verifyBatch(aggSignature3, messages, publicKeys);
|
||||||
console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
|
console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
|
||||||
|
// bls.pairing(PointG1, PointG2) // pairings
|
||||||
|
|
||||||
// Pairings
|
// hash-to-curve examples can be seen below
|
||||||
// bls.pairing(PointG1, PointG2)
|
|
||||||
// Also, check out hash-to-curve examples below.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Abstract API
|
## Abstract API
|
||||||
@ -482,9 +477,11 @@ Every curve has exported `hashToCurve` and `encodeToCurve` methods:
|
|||||||
```ts
|
```ts
|
||||||
import { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1';
|
import { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1';
|
||||||
import { randomBytes } from '@noble/hashes/utils';
|
import { randomBytes } from '@noble/hashes/utils';
|
||||||
|
hashToCurve('0102abcd');
|
||||||
console.log(hashToCurve(randomBytes()));
|
console.log(hashToCurve(randomBytes()));
|
||||||
console.log(encodeToCurve(randomBytes()));
|
console.log(encodeToCurve(randomBytes()));
|
||||||
|
|
||||||
|
|
||||||
import { bls12_381 } from '@noble/curves/bls12-381';
|
import { bls12_381 } from '@noble/curves/bls12-381';
|
||||||
bls12_381.G1.hashToCurve(randomBytes(), { DST: 'another' });
|
bls12_381.G1.hashToCurve(randomBytes(), { DST: 'another' });
|
||||||
bls12_381.G2.hashToCurve(randomBytes(), { DST: 'custom' });
|
bls12_381.G2.hashToCurve(randomBytes(), { DST: 'custom' });
|
||||||
@ -674,6 +671,14 @@ pedersen x 884 ops/sec @ 1ms/op
|
|||||||
poseidon x 8,598 ops/sec @ 116μs/op
|
poseidon x 8,598 ops/sec @ 116μs/op
|
||||||
verify x 528 ops/sec @ 1ms/op
|
verify x 528 ops/sec @ 1ms/op
|
||||||
|
|
||||||
|
ecdh
|
||||||
|
├─x25519 x 1,337 ops/sec @ 747μs/op
|
||||||
|
├─secp256k1 x 461 ops/sec @ 2ms/op
|
||||||
|
├─P256 x 441 ops/sec @ 2ms/op
|
||||||
|
├─P384 x 179 ops/sec @ 5ms/op
|
||||||
|
├─P521 x 93 ops/sec @ 10ms/op
|
||||||
|
└─x448 x 496 ops/sec @ 2ms/op
|
||||||
|
|
||||||
bls12-381
|
bls12-381
|
||||||
init x 32 ops/sec @ 30ms/op
|
init x 32 ops/sec @ 30ms/op
|
||||||
getPublicKey 1-bit x 858 ops/sec @ 1ms/op
|
getPublicKey 1-bit x 858 ops/sec @ 1ms/op
|
||||||
|
19
benchmark/ecdh.js
Normal file
19
benchmark/ecdh.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { run, mark, compare, utils } from 'micro-bmark';
|
||||||
|
import { generateData } from './_shared.js';
|
||||||
|
import { secp256k1 } from '../secp256k1.js';
|
||||||
|
import { P256 } from '../p256.js';
|
||||||
|
import { P384 } from '../p384.js';
|
||||||
|
import { P521 } from '../p521.js';
|
||||||
|
import { x25519 } from '../ed25519.js';
|
||||||
|
import { x448 } from '../ed448.js';
|
||||||
|
|
||||||
|
run(async () => {
|
||||||
|
const curves = { x25519, secp256k1, P256, P384, P521, x448 };
|
||||||
|
const fns = {};
|
||||||
|
for (let [k, c] of Object.entries(curves)) {
|
||||||
|
const pubB = c.getPublicKey(c.utils.randomPrivateKey());
|
||||||
|
const privA = c.utils.randomPrivateKey();
|
||||||
|
fns[k] = () => c.getSharedSecret(privA, pubB);
|
||||||
|
}
|
||||||
|
await compare('ecdh', 1000, fns);
|
||||||
|
});
|
@ -12,7 +12,7 @@
|
|||||||
"*.d.ts.map"
|
"*.d.ts.map"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bench": "cd benchmark; node secp256k1.js; node curves.js; node stark.js; node bls.js",
|
"bench": "cd benchmark; node secp256k1.js; node curves.js; node ecdh.js; node stark.js; node bls.js",
|
||||||
"build": "tsc && tsc -p tsconfig.esm.json",
|
"build": "tsc && tsc -p tsconfig.esm.json",
|
||||||
"build:release": "rollup -c rollup.config.js",
|
"build:release": "rollup -c rollup.config.js",
|
||||||
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
|
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
|
||||||
|
@ -16,12 +16,14 @@ export type CurveType = {
|
|||||||
powPminus2?: (x: bigint) => bigint;
|
powPminus2?: (x: bigint) => bigint;
|
||||||
xyToU?: (x: bigint, y: bigint) => bigint;
|
xyToU?: (x: bigint, y: bigint) => bigint;
|
||||||
Gu: bigint;
|
Gu: bigint;
|
||||||
|
randomBytes?: (bytesLength?: number) => Uint8Array;
|
||||||
};
|
};
|
||||||
export type CurveFn = {
|
export type CurveFn = {
|
||||||
scalarMult: (scalar: Hex, u: Hex) => Uint8Array;
|
scalarMult: (scalar: Hex, u: Hex) => Uint8Array;
|
||||||
scalarMultBase: (scalar: Hex) => Uint8Array;
|
scalarMultBase: (scalar: Hex) => Uint8Array;
|
||||||
getSharedSecret: (privateKeyA: Hex, publicKeyB: Hex) => Uint8Array;
|
getSharedSecret: (privateKeyA: Hex, publicKeyB: Hex) => Uint8Array;
|
||||||
getPublicKey: (privateKey: Hex) => Uint8Array;
|
getPublicKey: (privateKey: Hex) => Uint8Array;
|
||||||
|
utils: { randomPrivateKey: () => Uint8Array; };
|
||||||
GuBytes: Uint8Array;
|
GuBytes: Uint8Array;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,6 +183,7 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
|||||||
scalarMultBase,
|
scalarMultBase,
|
||||||
getSharedSecret: (privateKey: Hex, publicKey: Hex) => scalarMult(privateKey, publicKey),
|
getSharedSecret: (privateKey: Hex, publicKey: Hex) => scalarMult(privateKey, publicKey),
|
||||||
getPublicKey: (privateKey: Hex): Uint8Array => scalarMultBase(privateKey),
|
getPublicKey: (privateKey: Hex): Uint8Array => scalarMultBase(privateKey),
|
||||||
|
utils: { randomPrivateKey: () => CURVE.randomBytes!(CURVE.nByteLength) },
|
||||||
GuBytes: GuBytes,
|
GuBytes: GuBytes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,7 @@ export const x25519 = montgomery({
|
|||||||
return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
|
return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
|
||||||
},
|
},
|
||||||
adjustScalarBytes,
|
adjustScalarBytes,
|
||||||
|
randomBytes,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
||||||
|
@ -134,6 +134,7 @@ export const x448 = montgomery({
|
|||||||
return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
|
return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
|
||||||
},
|
},
|
||||||
adjustScalarBytes,
|
adjustScalarBytes,
|
||||||
|
randomBytes,
|
||||||
// The 4-isogeny maps between the Montgomery curve and this Edwards
|
// The 4-isogeny maps between the Montgomery curve and this Edwards
|
||||||
// curve are:
|
// curve are:
|
||||||
// (u, v) = (y^2/x^2, (2 - x^2 - y^2)*y/x^3)
|
// (u, v) = (y^2/x^2, (2 - x^2 - y^2)*y/x^3)
|
||||||
|
Loading…
Reference in New Issue
Block a user