UNPKG

@waku/rln

Version:

RLN (Rate Limiting Nullifier) implementation for Waku

77 lines (74 loc) 3.15 kB
import { EC as EC$1 } from './elliptic.js'; import { splitSignature, arrayify, hexlify, hexDataLength, hexZeroPad } from '../../bytes/lib.esm/index.js'; import { defineReadOnly } from '../../properties/lib.esm/index.js'; import { Logger } from '../../logger/lib.esm/index.js'; import { version } from './_version.js'; const logger = new Logger(version); let _curve = null; function getCurve() { if (!_curve) { _curve = new EC$1("secp256k1"); } return _curve; } class SigningKey { constructor(privateKey) { defineReadOnly(this, "curve", "secp256k1"); defineReadOnly(this, "privateKey", hexlify(privateKey)); if (hexDataLength(this.privateKey) !== 32) { logger.throwArgumentError("invalid private key", "privateKey", "[[ REDACTED ]]"); } const keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey)); defineReadOnly(this, "publicKey", "0x" + keyPair.getPublic(false, "hex")); defineReadOnly(this, "compressedPublicKey", "0x" + keyPair.getPublic(true, "hex")); defineReadOnly(this, "_isSigningKey", true); } _addPoint(other) { const p0 = getCurve().keyFromPublic(arrayify(this.publicKey)); const p1 = getCurve().keyFromPublic(arrayify(other)); return "0x" + p0.pub.add(p1.pub).encodeCompressed("hex"); } signDigest(digest) { const keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey)); const digestBytes = arrayify(digest); if (digestBytes.length !== 32) { logger.throwArgumentError("bad digest length", "digest", digest); } const signature = keyPair.sign(digestBytes, { canonical: true }); return splitSignature({ recoveryParam: signature.recoveryParam, r: hexZeroPad("0x" + signature.r.toString(16), 32), s: hexZeroPad("0x" + signature.s.toString(16), 32), }); } computeSharedSecret(otherKey) { const keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey)); const otherKeyPair = getCurve().keyFromPublic(arrayify(computePublicKey(otherKey))); return hexZeroPad("0x" + keyPair.derive(otherKeyPair.getPublic()).toString(16), 32); } static isSigningKey(value) { return !!(value && value._isSigningKey); } } function recoverPublicKey(digest, signature) { const sig = splitSignature(signature); const rs = { r: arrayify(sig.r), s: arrayify(sig.s) }; return "0x" + getCurve().recoverPubKey(arrayify(digest), rs, sig.recoveryParam).encode("hex", false); } function computePublicKey(key, compressed) { const bytes = arrayify(key); if (bytes.length === 32) { const signingKey = new SigningKey(bytes); return signingKey.publicKey; } else if (bytes.length === 33) { return "0x" + getCurve().keyFromPublic(bytes).getPublic(false, "hex"); } else if (bytes.length === 65) { { return hexlify(bytes); } } return logger.throwArgumentError("invalid public or private key", "key", "[REDACTED]"); } export { SigningKey, computePublicKey, recoverPublicKey };