forked from tornado-packages/noble-curves
readme
This commit is contained in:
parent
e1cb8549e8
commit
2902b0299a
60
README.md
60
README.md
@ -125,7 +125,7 @@ import { ed25519ctx, ed25519ph } from '@noble/curves/ed25519';
|
|||||||
import { x25519 } from '@noble/curves/ed25519';
|
import { x25519 } from '@noble/curves/ed25519';
|
||||||
const priv = 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4';
|
const priv = 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4';
|
||||||
const pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';
|
const pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';
|
||||||
x25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub);
|
x25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub); // aliases
|
||||||
x25519.getPublicKey(priv) === x25519.scalarMultBase(priv);
|
x25519.getPublicKey(priv) === x25519.scalarMultBase(priv);
|
||||||
|
|
||||||
// hash-to-curve
|
// hash-to-curve
|
||||||
@ -183,6 +183,7 @@ console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
|
|||||||
|
|
||||||
// Pairings
|
// Pairings
|
||||||
// bls.pairing(PointG1, PointG2)
|
// bls.pairing(PointG1, PointG2)
|
||||||
|
// Also, check out hash-to-curve examples below.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Abstract API
|
## Abstract API
|
||||||
@ -216,7 +217,7 @@ For this you will need `hmac` & `hash`, which in our implementations is provided
|
|||||||
If you're using different hashing library, make sure to wrap it in the following interface:
|
If you're using different hashing library, make sure to wrap it in the following interface:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
export type CHash = {
|
type CHash = {
|
||||||
(message: Uint8Array): Uint8Array;
|
(message: Uint8Array): Uint8Array;
|
||||||
blockLen: number;
|
blockLen: number;
|
||||||
outputLen: number;
|
outputLen: number;
|
||||||
@ -235,7 +236,7 @@ export type CHash = {
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
// T is usually bigint, but can be something else like complex numbers in BLS curves
|
// T is usually bigint, but can be something else like complex numbers in BLS curves
|
||||||
export interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
||||||
readonly px: T;
|
readonly px: T;
|
||||||
readonly py: T;
|
readonly py: T;
|
||||||
readonly pz: T;
|
readonly pz: T;
|
||||||
@ -251,7 +252,7 @@ export interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
|||||||
toHex(isCompressed?: boolean): string;
|
toHex(isCompressed?: boolean): string;
|
||||||
}
|
}
|
||||||
// Static methods for 3d XYZ points
|
// Static methods for 3d XYZ points
|
||||||
export interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
|
interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
|
||||||
new (x: T, y: T, z: T): ProjPointType<T>;
|
new (x: T, y: T, z: T): ProjPointType<T>;
|
||||||
fromAffine(p: AffinePoint<T>): ProjPointType<T>;
|
fromAffine(p: AffinePoint<T>): ProjPointType<T>;
|
||||||
fromHex(hex: Hex): ProjPointType<T>;
|
fromHex(hex: Hex): ProjPointType<T>;
|
||||||
@ -262,7 +263,7 @@ export interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
|
|||||||
**ECDSA signatures** are represented by `Signature` instances and can be described by the interface:
|
**ECDSA signatures** are represented by `Signature` instances and can be described by the interface:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
export interface SignatureType {
|
interface SignatureType {
|
||||||
readonly r: bigint;
|
readonly r: bigint;
|
||||||
readonly s: bigint;
|
readonly s: bigint;
|
||||||
readonly recovery?: number;
|
readonly recovery?: number;
|
||||||
@ -274,9 +275,14 @@ export interface SignatureType {
|
|||||||
toCompactRawBytes(): Uint8Array;
|
toCompactRawBytes(): Uint8Array;
|
||||||
toCompactHex(): string;
|
toCompactHex(): string;
|
||||||
// DER-encoded
|
// DER-encoded
|
||||||
toDERRawBytes(isCompressed?: boolean): Uint8Array;
|
toDERRawBytes(): Uint8Array;
|
||||||
toDERHex(isCompressed?: boolean): string;
|
toDERHex(): string;
|
||||||
}
|
}
|
||||||
|
type SignatureConstructor = {
|
||||||
|
new (r: bigint, s: bigint): SignatureType;
|
||||||
|
fromCompact(hex: Hex): SignatureType;
|
||||||
|
fromDER(hex: Hex): SignatureType;
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Example implementing [secq256k1](https://personaelabs.org/posts/spartan-ecdsa) (NOT secp256k1)
|
Example implementing [secq256k1](https://personaelabs.org/posts/spartan-ecdsa) (NOT secp256k1)
|
||||||
@ -307,9 +313,10 @@ secq256k1.getPublicKey(priv); // Convert private key to public.
|
|||||||
const sig = secq256k1.sign(msg, priv); // Sign msg with private key.
|
const sig = secq256k1.sign(msg, priv); // Sign msg with private key.
|
||||||
secq256k1.verify(sig, msg, priv); // Verify if sig is correct.
|
secq256k1.verify(sig, msg, priv); // Verify if sig is correct.
|
||||||
|
|
||||||
const point = secq256k1.Point.BASE; // Elliptic curve Point class and BASE point static var.
|
const Point = secq256k1.ProjectivePoint;
|
||||||
|
const point = Point.BASE; // Elliptic curve Point class and BASE point static var.
|
||||||
point.add(point).equals(point.double()); // add(), equals(), double() methods
|
point.add(point).equals(point.double()); // add(), equals(), double() methods
|
||||||
point.subtract(point).equals(secq256k1.Point.ZERO); // subtract() method, ZERO static var
|
point.subtract(point).equals(Point.ZERO); // subtract() method, ZERO static var
|
||||||
point.negate(); // Flips point over x/y coordinate.
|
point.negate(); // Flips point over x/y coordinate.
|
||||||
point.multiply(31415n); // Multiplication of Point by scalar.
|
point.multiply(31415n); // Multiplication of Point by scalar.
|
||||||
|
|
||||||
@ -319,12 +326,17 @@ point.toAffine(); // Converts to 2d affine xy coordinates
|
|||||||
secq256k1.CURVE.n;
|
secq256k1.CURVE.n;
|
||||||
secq256k1.CURVE.Fp.mod();
|
secq256k1.CURVE.Fp.mod();
|
||||||
secq256k1.CURVE.hash();
|
secq256k1.CURVE.hash();
|
||||||
|
|
||||||
|
// precomputes
|
||||||
|
const fast = secq256k1.utils.precompute(8, Point.fromHex(someonesPubKey));
|
||||||
|
fast.multiply(privKey); // much faster ECDH now
|
||||||
```
|
```
|
||||||
|
|
||||||
`weierstrass()` returns `CurveFn`:
|
`weierstrass()` returns `CurveFn`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
export type CurveFn = {
|
type SignOpts = { lowS?: boolean; prehash?: boolean; extraEntropy: boolean | Uint8Array };
|
||||||
|
type CurveFn = {
|
||||||
CURVE: ReturnType<typeof validateOpts>;
|
CURVE: ReturnType<typeof validateOpts>;
|
||||||
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
|
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
|
||||||
getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
|
getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
|
||||||
@ -338,8 +350,10 @@ export type CurveFn = {
|
|||||||
ProjectivePoint: ProjectivePointConstructor;
|
ProjectivePoint: ProjectivePointConstructor;
|
||||||
Signature: SignatureConstructor;
|
Signature: SignatureConstructor;
|
||||||
utils: {
|
utils: {
|
||||||
|
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
||||||
isValidPrivateKey(privateKey: PrivKey): boolean;
|
isValidPrivateKey(privateKey: PrivKey): boolean;
|
||||||
randomPrivateKey: () => Uint8Array;
|
randomPrivateKey: () => Uint8Array;
|
||||||
|
precompute: (windowSize?: number, point?: ProjPointType<bigint>) => ProjPointType<bigint>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
@ -362,7 +376,7 @@ For EdDSA signatures, `hash` param required. `adjustScalarBytes` which instructs
|
|||||||
7. Have `isTorsionFree()`, `clearCofactor()` and `isSmallOrder()` utilities to handle torsions
|
7. Have `isTorsionFree()`, `clearCofactor()` and `isSmallOrder()` utilities to handle torsions
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
export interface ExtPointType extends Group<ExtPointType> {
|
interface ExtPointType extends Group<ExtPointType> {
|
||||||
readonly ex: bigint;
|
readonly ex: bigint;
|
||||||
readonly ey: bigint;
|
readonly ey: bigint;
|
||||||
readonly ez: bigint;
|
readonly ez: bigint;
|
||||||
@ -376,7 +390,7 @@ export interface ExtPointType extends Group<ExtPointType> {
|
|||||||
toAffine(iz?: bigint): AffinePoint<bigint>;
|
toAffine(iz?: bigint): AffinePoint<bigint>;
|
||||||
}
|
}
|
||||||
// Static methods of Extended Point with coordinates in X, Y, Z, T
|
// Static methods of Extended Point with coordinates in X, Y, Z, T
|
||||||
export interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
|
interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
|
||||||
new (x: bigint, y: bigint, z: bigint, t: bigint): ExtPointType;
|
new (x: bigint, y: bigint, z: bigint, t: bigint): ExtPointType;
|
||||||
fromAffine(p: AffinePoint<bigint>): ExtPointType;
|
fromAffine(p: AffinePoint<bigint>): ExtPointType;
|
||||||
fromHex(hex: Hex): ExtPointType;
|
fromHex(hex: Hex): ExtPointType;
|
||||||
@ -388,13 +402,14 @@ Example implementing edwards25519:
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { twistedEdwards } from '@noble/curves/abstract/edwards';
|
import { twistedEdwards } from '@noble/curves/abstract/edwards';
|
||||||
import { div } from '@noble/curves/abstract/modular';
|
import { Field, div } from '@noble/curves/abstract/modular';
|
||||||
import { sha512 } from '@noble/hashes/sha512';
|
import { sha512 } from '@noble/hashes/sha512';
|
||||||
|
|
||||||
|
const Fp = Field(2n ** 255n - 19n);
|
||||||
const ed25519 = twistedEdwards({
|
const ed25519 = twistedEdwards({
|
||||||
a: -1n,
|
a: -1n,
|
||||||
d: div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
|
d: Fp.div(-121665n, 121666n), // -121665n/121666n mod p
|
||||||
P: 2n ** 255n - 19n,
|
Fp,
|
||||||
n: 2n ** 252n + 27742317777372353535851937790883648493n,
|
n: 2n ** 252n + 27742317777372353535851937790883648493n,
|
||||||
h: 8n,
|
h: 8n,
|
||||||
Gx: 15112221349535400772501151409588531511454012693041857206046113283949847762202n,
|
Gx: 15112221349535400772501151409588531511454012693041857206046113283949847762202n,
|
||||||
@ -414,13 +429,12 @@ const ed25519 = twistedEdwards({
|
|||||||
`twistedEdwards()` returns `CurveFn` of following type:
|
`twistedEdwards()` returns `CurveFn` of following type:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
export type CurveFn = {
|
type CurveFn = {
|
||||||
CURVE: ReturnType<typeof validateOpts>;
|
CURVE: ReturnType<typeof validateOpts>;
|
||||||
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
|
getPublicKey: (privateKey: Hex) => Uint8Array;
|
||||||
sign: (message: Hex, privateKey: Hex) => Uint8Array;
|
sign: (message: Hex, privateKey: Hex, context?: Hex) => Uint8Array;
|
||||||
verify: (sig: SigType, message: Hex, publicKey: PubKey, context?: Hex) => boolean;
|
verify: (sig: SigType, message: Hex, publicKey: Hex, context?: Hex) => boolean;
|
||||||
ExtendedPoint: ExtendedPointConstructor;
|
ExtendedPoint: ExtPointConstructor;
|
||||||
Signature: SignatureConstructor;
|
|
||||||
utils: {
|
utils: {
|
||||||
randomPrivateKey: () => Uint8Array;
|
randomPrivateKey: () => Uint8Array;
|
||||||
getExtendedPublicKey: (key: PrivKey) => {
|
getExtendedPublicKey: (key: PrivKey) => {
|
||||||
@ -438,13 +452,13 @@ export type CurveFn = {
|
|||||||
|
|
||||||
The module contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748. Proper Elliptic Curve Points are not implemented yet.
|
The module contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748. Proper Elliptic Curve Points are not implemented yet.
|
||||||
|
|
||||||
You must specify curve field, `a24` special variable, `montgomeryBits`, `nByteLength`, and coordinate `u` of generator point.
|
You must specify curve params `Fp`, `a`, `Gu` coordinate of u, `montgomeryBits` and `nByteLength`.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { montgomery } from '@noble/curves/abstract/montgomery';
|
import { montgomery } from '@noble/curves/abstract/montgomery';
|
||||||
|
|
||||||
const x25519 = montgomery({
|
const x25519 = montgomery({
|
||||||
P: 2n ** 255n - 19n,
|
Fp: Field(2n ** 255n - 19n),
|
||||||
a: 486662n,
|
a: 486662n,
|
||||||
Gu: 9n,
|
Gu: 9n,
|
||||||
montgomeryBits: 255,
|
montgomeryBits: 255,
|
||||||
|
Loading…
Reference in New Issue
Block a user