forked from tornado-packages/noble-curves
Edwards: prohibit number scalars, only allow bigints
This commit is contained in:
parent
055147f1be
commit
11e78aadbf
@ -170,16 +170,21 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|||||||
* https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
* https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
||||||
*/
|
*/
|
||||||
class ExtendedPoint implements ExtendedPointType {
|
class ExtendedPoint implements ExtendedPointType {
|
||||||
constructor(readonly x: bigint, readonly y: bigint, readonly z: bigint, readonly t: bigint) {}
|
constructor(
|
||||||
|
readonly x: bigint,
|
||||||
|
readonly y: bigint,
|
||||||
|
readonly z = _1n,
|
||||||
|
readonly t = modP(x * y)
|
||||||
|
) {}
|
||||||
|
|
||||||
static BASE = new ExtendedPoint(CURVE.Gx, CURVE.Gy, _1n, modP(CURVE.Gx * CURVE.Gy));
|
static BASE = new ExtendedPoint(CURVE.Gx, CURVE.Gy);
|
||||||
static ZERO = new ExtendedPoint(_0n, _1n, _1n, _0n);
|
static ZERO = new ExtendedPoint(_0n, _1n); // 0, 1, 1, 0
|
||||||
static fromAffine(p: Point): ExtendedPoint {
|
static fromAffine(p: Point): ExtendedPoint {
|
||||||
if (!(p instanceof Point)) {
|
if (!(p instanceof Point)) {
|
||||||
throw new TypeError('ExtendedPoint#fromAffine: expected Point');
|
throw new TypeError('ExtendedPoint#fromAffine: expected Point');
|
||||||
}
|
}
|
||||||
if (p.equals(Point.ZERO)) return ExtendedPoint.ZERO;
|
if (p.equals(Point.ZERO)) return ExtendedPoint.ZERO;
|
||||||
return new ExtendedPoint(p.x, p.y, _1n, modP(p.x * p.y));
|
return new ExtendedPoint(p.x, p.y);
|
||||||
}
|
}
|
||||||
// Takes a bunch of Jacobian Points but executes only one
|
// Takes a bunch of Jacobian Points but executes only one
|
||||||
// invert on all of them. invert is very slow operation,
|
// invert on all of them. invert is very slow operation,
|
||||||
@ -306,8 +311,9 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|||||||
// It's faster, but should only be used when you don't care about
|
// It's faster, but should only be used when you don't care about
|
||||||
// an exposed private key e.g. sig verification.
|
// an exposed private key e.g. sig verification.
|
||||||
multiplyUnsafe(scalar: number | bigint): ExtendedPoint {
|
multiplyUnsafe(scalar: number | bigint): ExtendedPoint {
|
||||||
let n = normalizeScalar(scalar, CURVE_ORDER, false);
|
|
||||||
const P0 = ExtendedPoint.ZERO;
|
const P0 = ExtendedPoint.ZERO;
|
||||||
|
if (scalar === _0n) return P0;
|
||||||
|
let n = normalizeScalar(scalar, CURVE_ORDER, false);
|
||||||
if (n === _0n) return P0;
|
if (n === _0n) return P0;
|
||||||
if (this.equals(P0) || n === _1n) return this;
|
if (this.equals(P0) || n === _1n) return this;
|
||||||
if (this.equals(ExtendedPoint.BASE)) return this.wNAF(n);
|
if (this.equals(ExtendedPoint.BASE)) return this.wNAF(n);
|
||||||
@ -542,7 +548,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|||||||
const groupLen = CURVE.nByteLength;
|
const groupLen = CURVE.nByteLength;
|
||||||
// Normalize bigint / number / string to Uint8Array
|
// Normalize bigint / number / string to Uint8Array
|
||||||
const keyb =
|
const keyb =
|
||||||
typeof key === 'bigint' || typeof key === 'number'
|
typeof key === 'bigint'
|
||||||
? ut.numberToBytesLE(normalizeScalar(key, maxGroupElement), groupLen)
|
? ut.numberToBytesLE(normalizeScalar(key, maxGroupElement), groupLen)
|
||||||
: key;
|
: key;
|
||||||
// Hash private key with curve's hash function to produce uniformingly random input
|
// Hash private key with curve's hash function to produce uniformingly random input
|
||||||
|
@ -7,7 +7,7 @@ const _2n = BigInt(2);
|
|||||||
// We accept hex strings besides Uint8Array for simplicity
|
// We accept hex strings besides Uint8Array for simplicity
|
||||||
export type Hex = Uint8Array | string;
|
export type Hex = Uint8Array | string;
|
||||||
// Very few implementations accept numbers, we do it to ease learning curve
|
// Very few implementations accept numbers, we do it to ease learning curve
|
||||||
export type PrivKey = Hex | bigint | number;
|
export type PrivKey = Hex | bigint;
|
||||||
export type CHash = {
|
export type CHash = {
|
||||||
(message: Uint8Array | string): Uint8Array;
|
(message: Uint8Array | string): Uint8Array;
|
||||||
blockLen: number;
|
blockLen: number;
|
||||||
|
@ -87,7 +87,7 @@ describe('ed25519', () => {
|
|||||||
deepStrictEqual(ed.verify(signature, msg, publicKey), true);
|
deepStrictEqual(ed.verify(signature, msg, publicKey), true);
|
||||||
});
|
});
|
||||||
should('not verify signature with wrong public key', () => {
|
should('not verify signature with wrong public key', () => {
|
||||||
const publicKey = ed.getPublicKey(12);
|
const publicKey = ed.getPublicKey(12n);
|
||||||
const signature = ed.sign(msg, privKey);
|
const signature = ed.sign(msg, privKey);
|
||||||
deepStrictEqual(ed.verify(signature, msg, publicKey), false);
|
deepStrictEqual(ed.verify(signature, msg, publicKey), false);
|
||||||
});
|
});
|
||||||
@ -104,7 +104,7 @@ describe('ed25519', () => {
|
|||||||
deepStrictEqual(ed.verify(signature, msg, publicKey), true);
|
deepStrictEqual(ed.verify(signature, msg, publicKey), true);
|
||||||
});
|
});
|
||||||
should('not verify signature with wrong public key', () => {
|
should('not verify signature with wrong public key', () => {
|
||||||
const publicKey = ed.getPublicKey(12);
|
const publicKey = ed.getPublicKey(12n);
|
||||||
const signature = ed.sign(msg, privKey);
|
const signature = ed.sign(msg, privKey);
|
||||||
deepStrictEqual(ed.verify(signature, msg, publicKey), false);
|
deepStrictEqual(ed.verify(signature, msg, publicKey), false);
|
||||||
});
|
});
|
||||||
|
@ -382,7 +382,7 @@ describe('ed448', () => {
|
|||||||
deepStrictEqual(ed.verify(signature, msg, publicKey), true);
|
deepStrictEqual(ed.verify(signature, msg, publicKey), true);
|
||||||
});
|
});
|
||||||
should('not verify signature with wrong public key', () => {
|
should('not verify signature with wrong public key', () => {
|
||||||
const publicKey = ed.getPublicKey(12);
|
const publicKey = ed.getPublicKey(12n);
|
||||||
const signature = ed.sign(msg, privKey);
|
const signature = ed.sign(msg, privKey);
|
||||||
deepStrictEqual(ed.verify(signature, msg, publicKey), false);
|
deepStrictEqual(ed.verify(signature, msg, publicKey), false);
|
||||||
});
|
});
|
||||||
@ -392,19 +392,18 @@ describe('ed448', () => {
|
|||||||
deepStrictEqual(ed.verify(signature, wrongMsg, publicKey), false);
|
deepStrictEqual(ed.verify(signature, wrongMsg, publicKey), false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('sync methods', () => {
|
describe('sync methods', () => {
|
||||||
should('sign and verify', () => {
|
should('sign and verify', () => {
|
||||||
const publicKey = ed.getPublicKey(privKey);
|
const publicKey = ed.getPublicKey(privKey);
|
||||||
const signature = ed.sign(msg, privKey);
|
const signature = ed.sign(msg, privKey);
|
||||||
deepStrictEqual(ed.verify(signature, msg, publicKey), true);
|
deepStrictEqual(ed.verify(signature, msg, publicKey), true);
|
||||||
});
|
});
|
||||||
should('not verify signature with wrong public key', async () => {
|
should('not verify signature with wrong public key', () => {
|
||||||
const publicKey = ed.getPublicKey(12);
|
const publicKey = ed.getPublicKey(12n);
|
||||||
const signature = ed.sign(msg, privKey);
|
const signature = ed.sign(msg, privKey);
|
||||||
deepStrictEqual(ed.verify(signature, msg, publicKey), false);
|
deepStrictEqual(ed.verify(signature, msg, publicKey), false);
|
||||||
});
|
});
|
||||||
should('not verify signature with wrong hash', async () => {
|
should('not verify signature with wrong hash', () => {
|
||||||
const publicKey = ed.getPublicKey(privKey);
|
const publicKey = ed.getPublicKey(privKey);
|
||||||
const signature = ed.sign(msg, privKey);
|
const signature = ed.sign(msg, privKey);
|
||||||
deepStrictEqual(ed.verify(signature, wrongMsg, publicKey), false);
|
deepStrictEqual(ed.verify(signature, wrongMsg, publicKey), false);
|
||||||
|
Loading…
Reference in New Issue
Block a user