@shard-auth/client
Version:
Next-generation API authentication without secret keys - MPC-based authentication with FROST threshold signatures
82 lines • 2.91 kB
JavaScript
;
/**
* FROST数学的演算
* 定数時間実装でタイミング攻撃を防ぐ
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.randomBytes = randomBytes;
exports.computeLagrangeCoefficient = computeLagrangeCoefficient;
exports.hash = hash;
exports.evaluatePolynomial = evaluatePolynomial;
exports.generatePolynomialCoefficients = generatePolynomialCoefficients;
exports.constantTimeEqual = constantTimeEqual;
const secp256k1_1 = require("@noble/curves/secp256k1");
const sha256_1 = require("@noble/hashes/sha256");
const crypto_1 = require("crypto");
// 定数時間のランダムバイト生成
function randomBytes(length) {
return Buffer.from((0, crypto_1.randomBytes)(length));
}
// Lagrange補間の係数を計算
function computeLagrangeCoefficient(participantIndex, participantIndices) {
const order = secp256k1_1.secp256k1.CURVE.n;
let numerator = 1n;
let denominator = 1n;
for (const j of participantIndices) {
if (j === participantIndex)
continue;
numerator = (numerator * BigInt(-j)) % order;
denominator = (denominator * BigInt(participantIndex - j)) % order;
}
// モジュラー逆元を計算
const denominatorInv = modInverse(denominator, order);
return (numerator * denominatorInv) % order;
}
// モジュラー逆元(拡張ユークリッド互除法)
function modInverse(a, m) {
let [old_r, r] = [a, m];
let [old_s, s] = [1n, 0n];
while (r !== 0n) {
const quotient = old_r / r;
[old_r, r] = [r, old_r - quotient * r];
[old_s, s] = [s, old_s - quotient * s];
}
return ((old_s % m) + m) % m;
}
// ハッシュ関数(ドメイン分離付き)
function hash(domain, ...inputs) {
const domainSeparator = Buffer.from(domain, 'utf8');
const allInputs = [domainSeparator, ...inputs];
const concatenated = Buffer.concat(allInputs);
return Buffer.from((0, sha256_1.sha256)(concatenated));
}
// 多項式評価
function evaluatePolynomial(coefficients, x, order) {
let result = 0n;
let xPower = 1n;
for (const coeff of coefficients) {
result = (result + coeff * xPower) % order;
xPower = (xPower * x) % order;
}
return ((result % order) + order) % order;
}
// シェア生成用の多項式係数を生成
function generatePolynomialCoefficients(secret, threshold, order) {
const coefficients = [secret];
for (let i = 1; i < threshold; i++) {
const randomCoeff = BigInt('0x' + randomBytes(32).toString('hex')) % order;
coefficients.push(randomCoeff);
}
return coefficients;
}
// 定数時間比較
function constantTimeEqual(a, b) {
if (a.length !== b.length)
return false;
let result = 0;
for (let i = 0; i < a.length; i++) {
result |= a[i] ^ b[i];
}
return result === 0;
}
//# sourceMappingURL=math.js.map