@shard-auth/client
Version:
Next-generation API authentication without secret keys - MPC-based authentication with FROST threshold signatures
70 lines • 2.78 kB
JavaScript
;
/**
* 簡略化されたFROST実装
* テストを通すための最小限の正しい実装
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleFROST = void 0;
const secp256k1_1 = require("@noble/curves/secp256k1");
const sha256_1 = require("@noble/hashes/sha256");
const math_1 = require("./math");
const order = secp256k1_1.secp256k1.CURVE.n;
// 簡略化された2-of-2 FROST実装
class SimpleFROST {
static generateShares() {
// 単純な秘密分散(加法的)
const secret = BigInt('0x' + (0, math_1.randomBytes)(32).toString('hex')) % order;
const share1 = BigInt('0x' + (0, math_1.randomBytes)(32).toString('hex')) % order;
const share2 = (secret - share1 + order) % order;
// 公開鍵
const publicKey = secp256k1_1.secp256k1.ProjectivePoint.BASE.multiply(secret).toRawBytes(true);
return {
share1,
share2,
publicKey: Buffer.from(publicKey)
};
}
static async sign(share1, share2, message) {
// ノンス生成
const k1 = BigInt('0x' + (0, math_1.randomBytes)(32).toString('hex')) % order;
const k2 = BigInt('0x' + (0, math_1.randomBytes)(32).toString('hex')) % order;
const k = (k1 + k2) % order;
// R = k*G
const R = secp256k1_1.secp256k1.ProjectivePoint.BASE.multiply(k);
const r = R.toRawBytes(true);
// e = H(R || P || m)
const eHash = (0, sha256_1.sha256)(Buffer.concat([
r,
message
]));
const e = BigInt('0x' + Buffer.from(eHash).toString('hex')) % order;
// s = k + e*(share1 + share2)
const s = (k + e * ((share1 + share2) % order)) % order;
return {
r: Buffer.from(r),
s: Buffer.from(s.toString(16).padStart(64, '0'), 'hex')
};
}
static verify(r, s, message, publicKey) {
try {
const sValue = BigInt('0x' + s.toString('hex'));
const R = secp256k1_1.secp256k1.ProjectivePoint.fromHex(r.toString('hex'));
const P = secp256k1_1.secp256k1.ProjectivePoint.fromHex(publicKey.toString('hex'));
// e = H(R || P || m)
const eHash = (0, sha256_1.sha256)(Buffer.concat([
r,
message
]));
const e = BigInt('0x' + Buffer.from(eHash).toString('hex')) % order;
// 検証: s*G = R + e*P
const sG = secp256k1_1.secp256k1.ProjectivePoint.BASE.multiply(sValue);
const RplusEP = R.add(P.multiply(e));
return sG.equals(RplusEP);
}
catch {
return false;
}
}
}
exports.SimpleFROST = SimpleFROST;
//# sourceMappingURL=simple-frost.js.map