@hpke/dhkem-x25519
Version:
A Hybrid Public Key Encryption (HPKE) module extension for X25519
81 lines (80 loc) • 3.27 kB
JavaScript
/**
* This file is based on noble-curves (https://github.com/paulmillr/noble-curves).
*
* noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com)
*
* The original file is located at:
* https://github.com/paulmillr/noble-curves/blob/b9d49d2b41d550571a0c5be443ecb62109fa3373/src/ed25519.ts
*/
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "@hpke/common"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.x25519 = void 0;
/**
* ed25519 Twisted Edwards curve with following addons:
* - X25519 ECDH
* - Ristretto cofactor elimination
* - Elligator hash-to-group / point indistinguishability
* @module
*/
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
const common_1 = require("@hpke/common");
const _1n = 1n;
const _2n = 2n;
const _3n = 3n;
const _5n = 5n;
// P = 2n**255n - 19n
const ed25519_CURVE_p = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn;
function ed25519_pow_2_252_3(x) {
const _10n = 10n;
const _20n = 20n;
const _40n = 40n;
const _80n = 80n;
const P = ed25519_CURVE_p;
const x2 = (x * x) % P;
const b2 = (x2 * x) % P; // x^3, 11
const b4 = ((0, common_1.pow2)(b2, _2n, P) * b2) % P; // x^15, 1111
const b5 = ((0, common_1.pow2)(b4, _1n, P) * x) % P; // x^31
const b10 = ((0, common_1.pow2)(b5, _5n, P) * b5) % P;
const b20 = ((0, common_1.pow2)(b10, _10n, P) * b10) % P;
const b40 = ((0, common_1.pow2)(b20, _20n, P) * b20) % P;
const b80 = ((0, common_1.pow2)(b40, _40n, P) * b40) % P;
const b160 = ((0, common_1.pow2)(b80, _80n, P) * b80) % P;
const b240 = ((0, common_1.pow2)(b160, _80n, P) * b80) % P;
const b250 = ((0, common_1.pow2)(b240, _10n, P) * b10) % P;
const pow_p_5_8 = ((0, common_1.pow2)(b250, _2n, P) * x) % P;
// ^ To pow to (p+3)/8, multiply it by x.
return { pow_p_5_8, b2 };
}
function adjustScalarBytes(bytes) {
// Section 5: For X25519, in order to decode 32 random bytes as an integer scalar,
// set the three least significant bits of the first byte
bytes[0] &= 248; // 0b1111_1000
// and the most significant bit of the last to zero,
bytes[31] &= 127; // 0b0111_1111
// set the second most significant bit of the last byte to 1
bytes[31] |= 64; // 0b0100_0000
return bytes;
}
exports.x25519 = (() => {
const P = ed25519_CURVE_p;
return (0, common_1.montgomery)({
P,
type: "x25519",
powPminus2: (x) => {
// x^(p-2) aka x^(2^255-21)
const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
return (0, common_1.mod)((0, common_1.pow2)(pow_p_5_8, _3n, P) * b2, P);
},
adjustScalarBytes,
});
})();
});