x25519/x448: swap arguments

This commit is contained in:
Paul Miller 2022-12-27 01:02:37 +00:00
parent 135e69bd7b
commit 6ffe656871
No known key found for this signature in database
GPG Key ID: 697079DA6878B89B
3 changed files with 30 additions and 21 deletions

@ -454,7 +454,7 @@ const rfc7748Mul = [
for (let i = 0; i < rfc7748Mul.length; i++) {
const v = rfc7748Mul[i];
should(`RFC7748: scalarMult (${i})`, () => {
deepStrictEqual(hex(x25519.scalarMult(v.u, v.scalar)), v.outputU);
deepStrictEqual(hex(x25519.scalarMult(v.scalar, v.u)), v.outputU);
});
}
@ -467,7 +467,7 @@ for (let i = 0; i < rfc7748Iter.length; i++) {
const { scalar, iters } = rfc7748Iter[i];
should(`RFC7748: scalarMult iteration (${i})`, () => {
let k = x25519.Gu;
for (let i = 0, u = k; i < iters; i++) [k, u] = [x25519.scalarMult(u, k), k];
for (let i = 0, u = k; i < iters; i++) [k, u] = [x25519.scalarMult(k, u), k];
deepStrictEqual(hex(k), scalar);
});
}
@ -480,8 +480,8 @@ should('RFC7748 getSharedKey', () => {
const shared = '4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742';
deepStrictEqual(alicePublic, hex(x25519.getPublicKey(alicePrivate)));
deepStrictEqual(bobPublic, hex(x25519.getPublicKey(bobPrivate)));
deepStrictEqual(hex(x25519.scalarMult(bobPublic, alicePrivate)), shared);
deepStrictEqual(hex(x25519.scalarMult(alicePublic, bobPrivate)), shared);
deepStrictEqual(hex(x25519.scalarMult(alicePrivate, bobPublic)), shared);
deepStrictEqual(hex(x25519.scalarMult(bobPrivate, alicePublic)), shared);
});
// should('X25519/getSharedSecret() should be commutative', () => {
@ -514,7 +514,7 @@ should('RFC7748 getSharedKey', () => {
const comment = `(${i}, ${v.result}) ${v.comment}`;
if (v.result === 'valid' || v.result === 'acceptable') {
try {
const shared = hex(x25519.scalarMult(v.public, v.private));
const shared = hex(x25519.scalarMult(v.private, v.public));
deepStrictEqual(shared, v.shared, comment);
} catch (e) {
// We are more strict
@ -525,7 +525,7 @@ should('RFC7748 getSharedKey', () => {
} else if (v.result === 'invalid') {
let failed = false;
try {
x25519.scalarMult(v.public, v.private);
x25519.scalarMult(v.private, v.public);
} catch (error) {
failed = true;
}

@ -480,7 +480,7 @@ const rfc7748Mul = [
for (let i = 0; i < rfc7748Mul.length; i++) {
const v = rfc7748Mul[i];
should(`RFC7748: scalarMult (${i})`, () => {
deepStrictEqual(hex(x448.scalarMult(v.u, v.scalar)), v.outputU);
deepStrictEqual(hex(x448.scalarMult(v.scalar, v.u)), v.outputU);
});
}
@ -501,7 +501,7 @@ for (let i = 0; i < rfc7748Iter.length; i++) {
const { scalar, iters } = rfc7748Iter[i];
should(`RFC7748: scalarMult iteration (${i})`, () => {
let k = x448.Gu;
for (let i = 0, u = k; i < iters; i++) [k, u] = [x448.scalarMult(u, k), k];
for (let i = 0, u = k; i < iters; i++) [k, u] = [x448.scalarMult(k, u), k];
deepStrictEqual(hex(k), scalar);
});
}
@ -519,8 +519,8 @@ should('RFC7748 getSharedKey', () => {
'07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d';
deepStrictEqual(alicePublic, hex(x448.getPublicKey(alicePrivate)));
deepStrictEqual(bobPublic, hex(x448.getPublicKey(bobPrivate)));
deepStrictEqual(hex(x448.scalarMult(bobPublic, alicePrivate)), shared);
deepStrictEqual(hex(x448.scalarMult(alicePublic, bobPrivate)), shared);
deepStrictEqual(hex(x448.scalarMult(alicePrivate, bobPublic)), shared);
deepStrictEqual(hex(x448.scalarMult(bobPrivate, alicePublic)), shared);
});
{
@ -531,7 +531,7 @@ should('RFC7748 getSharedKey', () => {
const index = `(${i}, ${v.result}) ${v.comment}`;
if (v.result === 'valid' || v.result === 'acceptable') {
try {
const shared = hex(x448.scalarMult(v.public, v.private));
const shared = hex(x448.scalarMult(v.private, v.public));
deepStrictEqual(shared, v.shared, index);
} catch (e) {
// We are more strict
@ -543,7 +543,7 @@ should('RFC7748 getSharedKey', () => {
} else if (v.result === 'invalid') {
let failed = false;
try {
x448.scalarMult(v.public, v.private);
x448.scalarMult(v.private, v.public);
} catch (error) {
failed = true;
}

@ -24,8 +24,9 @@ export type CurveType = {
Gu: string;
};
export type CurveFn = {
scalarMult: (u: Hex, scalar: Hex) => Uint8Array;
scalarMult: (scalar: Hex, u: Hex) => Uint8Array;
scalarMultBase: (scalar: Hex) => Uint8Array;
getSharedSecret: (privateKeyA: Hex, publicKeyB: Hex) => Uint8Array;
getPublicKey: (privateKey: Hex) => Uint8Array;
Gu: string;
};
@ -186,8 +187,14 @@ export function montgomery(curveDef: CurveType): CurveFn {
throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
return bytesToNumberLE(adjustScalarBytes(bytes));
}
// Multiply point u by scalar
function scalarMult(u: Hex, scalar: Hex): Uint8Array {
/**
* Computes shared secret between private key "scalar" and public key's "u" (x) coordinate.
* We can get 'y' coordinate from 'u',
* but Point.fromHex also wants 'x' coordinate oddity flag,
* and we cannot get 'x' without knowing 'v'.
* Need to add generic conversion between twisted edwards and complimentary curve for JubJub.
*/
function scalarMult(scalar: Hex, u: Hex): Uint8Array {
const pointU = decodeUCoordinate(u);
const _scalar = decodeScalar(scalar);
const pu = montgomeryLadder(pointU, _scalar);
@ -196,18 +203,20 @@ export function montgomery(curveDef: CurveType): CurveFn {
if (pu === _0n) throw new Error('Invalid private or public key received');
return encodeUCoordinate(pu);
}
// Multiply base point by scalar
/**
* Computes public key from private.
* Executes scalar multiplication of curve's base point by scalar.
* @param scalar private key
* @returns new public key
*/
function scalarMultBase(scalar: Hex): Uint8Array {
return scalarMult(CURVE.Gu, scalar);
return scalarMult(scalar, CURVE.Gu);
}
return {
// NOTE: we can get 'y' coordinate from 'u', but Point.fromHex also wants 'x' coordinate oddity flag, and we cannot get 'x' without knowing 'v'
// Need to add generic conversion between twisted edwards and complimentary curve for JubJub
scalarMult,
scalarMultBase,
// NOTE: these function work on complimentary montgomery curve
// getSharedSecret: (privateKey: Hex, publicKey: Hex) => scalarMult(publicKey, privateKey),
getSharedSecret: (privateKey: Hex, publicKey: Hex) => scalarMult(privateKey, publicKey),
getPublicKey: (privateKey: Hex): Uint8Array => scalarMultBase(privateKey),
Gu: CURVE.Gu,
};