ethers.js/lib.commonjs/crypto/signature.js

225 lines
8.2 KiB
JavaScript
Raw Normal View History

2022-09-05 23:57:11 +03:00
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Signature = void 0;
const index_js_1 = require("../constants/index.js");
const index_js_2 = require("../utils/index.js");
// Constants
const BN_0 = BigInt(0);
const BN_1 = BigInt(1);
const BN_2 = BigInt(2);
const BN_27 = BigInt(27);
const BN_28 = BigInt(28);
const BN_35 = BigInt(35);
const _guard = {};
class Signature {
#props;
get r() { return (0, index_js_2.getStore)(this.#props, "r"); }
set r(value) {
if ((0, index_js_2.dataLength)(value) !== 32) {
2022-09-16 05:58:45 +03:00
(0, index_js_2.throwArgumentError)("invalid r", "value", value);
2022-09-05 23:57:11 +03:00
}
(0, index_js_2.setStore)(this.#props, "r", (0, index_js_2.hexlify)(value));
}
get s() { return (0, index_js_2.getStore)(this.#props, "s"); }
set s(value) {
if ((0, index_js_2.dataLength)(value) !== 32) {
2022-09-16 05:58:45 +03:00
(0, index_js_2.throwArgumentError)("invalid r", "value", value);
2022-09-05 23:57:11 +03:00
}
2022-09-16 05:58:45 +03:00
else if ((0, index_js_2.getBytes)(value)[0] & 0x80) {
(0, index_js_2.throwArgumentError)("non-canonical s", "value", value);
2022-09-05 23:57:11 +03:00
}
(0, index_js_2.setStore)(this.#props, "s", (0, index_js_2.hexlify)(value));
}
get v() { return (0, index_js_2.getStore)(this.#props, "v"); }
set v(value) {
2022-09-16 05:58:45 +03:00
const v = (0, index_js_2.getNumber)(value, "value");
2022-09-05 23:57:11 +03:00
if (v !== 27 && v !== 28) {
throw new Error("@TODO");
}
(0, index_js_2.setStore)(this.#props, "v", v);
}
get networkV() { return (0, index_js_2.getStore)(this.#props, "networkV"); }
get legacyChainId() {
const v = this.networkV;
if (v == null) {
return null;
}
return Signature.getChainId(v);
}
get yParity() {
2022-10-20 12:03:32 +03:00
return (this.v === 27) ? 0 : 1;
2022-09-05 23:57:11 +03:00
}
get yParityAndS() {
// The EIP-2098 compact representation
2022-09-16 05:58:45 +03:00
const yParityAndS = (0, index_js_2.getBytes)(this.s);
2022-09-05 23:57:11 +03:00
if (this.yParity) {
yParityAndS[0] |= 0x80;
}
return (0, index_js_2.hexlify)(yParityAndS);
}
get compactSerialized() {
return (0, index_js_2.concat)([this.r, this.yParityAndS]);
}
get serialized() {
return (0, index_js_2.concat)([this.r, this.s, (this.yParity ? "0x1c" : "0x1b")]);
}
constructor(guard, r, s, v) {
2022-09-16 05:58:45 +03:00
(0, index_js_2.assertPrivate)(guard, _guard, "Signature");
2022-09-05 23:57:11 +03:00
this.#props = { r, s, v, networkV: null };
}
[Symbol.for('nodejs.util.inspect.custom')]() {
return `Signature { r: "${this.r}", s: "${this.s}", yParity: ${this.yParity}, networkV: ${this.networkV} }`;
}
clone() {
const clone = new Signature(_guard, this.r, this.s, this.v);
if (this.networkV) {
(0, index_js_2.setStore)(clone.#props, "networkV", this.networkV);
}
return clone;
}
freeze() {
Object.freeze(this.#props);
return this;
}
isFrozen() {
return Object.isFrozen(this.#props);
}
toJSON() {
const networkV = this.networkV;
return {
_type: "signature",
networkV: ((networkV != null) ? networkV.toString() : null),
r: this.r, s: this.s, v: this.v,
};
}
2022-10-20 12:03:32 +03:00
//static create(): Signature {
// return new Signature(_guard, ZeroHash, ZeroHash, 27);
//}
2022-09-05 23:57:11 +03:00
// Get the chain ID from an EIP-155 v
static getChainId(v) {
2022-09-16 05:58:45 +03:00
const bv = (0, index_js_2.getBigInt)(v, "v");
2022-09-05 23:57:11 +03:00
// The v is not an EIP-155 v, so it is the unspecified chain ID
if ((bv == BN_27) || (bv == BN_28)) {
return BN_0;
}
// Bad value for an EIP-155 v
if (bv < BN_35) {
2022-09-16 05:58:45 +03:00
(0, index_js_2.throwArgumentError)("invalid EIP-155 v", "v", v);
2022-09-05 23:57:11 +03:00
}
return (bv - BN_35) / BN_2;
}
// Get the EIP-155 v transformed for a given chainId
static getChainIdV(chainId, v) {
2022-09-16 05:58:45 +03:00
return ((0, index_js_2.getBigInt)(chainId) * BN_2) + BigInt(35 + v - 27);
2022-09-05 23:57:11 +03:00
}
// Convert an EIP-155 v into a normalized v
static getNormalizedV(v) {
2022-09-16 05:58:45 +03:00
const bv = (0, index_js_2.getBigInt)(v);
2022-09-05 23:57:11 +03:00
if (bv == BN_0) {
return 27;
}
if (bv == BN_1) {
return 28;
}
// Otherwise, EIP-155 v means odd is 27 and even is 28
return (bv & BN_1) ? 27 : 28;
}
static from(sig) {
2022-10-20 12:03:32 +03:00
if (sig == null) {
return new Signature(_guard, index_js_1.ZeroHash, index_js_1.ZeroHash, 27);
}
2022-09-05 23:57:11 +03:00
const throwError = (message) => {
2022-09-16 05:58:45 +03:00
return (0, index_js_2.throwArgumentError)(message, "signature", sig);
2022-09-05 23:57:11 +03:00
};
if (typeof (sig) === "string") {
2022-09-16 05:58:45 +03:00
const bytes = (0, index_js_2.getBytes)(sig, "signature");
2022-09-05 23:57:11 +03:00
if (bytes.length === 64) {
const r = (0, index_js_2.hexlify)(bytes.slice(0, 32));
const s = bytes.slice(32, 64);
const v = (s[0] & 0x80) ? 28 : 27;
s[0] &= 0x7f;
return new Signature(_guard, r, (0, index_js_2.hexlify)(s), v);
}
2022-10-20 12:03:32 +03:00
if (bytes.length === 65) {
const r = (0, index_js_2.hexlify)(bytes.slice(0, 32));
2022-09-05 23:57:11 +03:00
const s = bytes.slice(32, 64);
if (s[0] & 0x80) {
throwError("non-canonical s");
}
const v = Signature.getNormalizedV(bytes[64]);
return new Signature(_guard, r, (0, index_js_2.hexlify)(s), v);
}
return throwError("invlaid raw signature length");
}
if (sig instanceof Signature) {
return sig.clone();
}
// Get r
const r = sig.r;
if (r == null) {
throwError("missing r");
}
if (!(0, index_js_2.isHexString)(r, 32)) {
throwError("invalid r");
}
// Get s; by any means necessary (we check consistency below)
const s = (function (s, yParityAndS) {
if (s != null) {
if (!(0, index_js_2.isHexString)(s, 32)) {
throwError("invalid s");
}
return s;
}
if (yParityAndS != null) {
if (!(0, index_js_2.isHexString)(yParityAndS, 32)) {
throwError("invalid yParityAndS");
}
2022-09-16 05:58:45 +03:00
const bytes = (0, index_js_2.getBytes)(yParityAndS);
2022-09-05 23:57:11 +03:00
bytes[0] &= 0x7f;
return (0, index_js_2.hexlify)(bytes);
}
return throwError("missing s");
})(sig.s, sig.yParityAndS);
2022-09-16 05:58:45 +03:00
if ((0, index_js_2.getBytes)(s)[0] & 0x80) {
2022-09-05 23:57:11 +03:00
throwError("non-canonical s");
}
// Get v; by any means necessary (we check consistency below)
const { networkV, v } = (function (_v, yParityAndS, yParity) {
if (_v != null) {
2022-09-16 05:58:45 +03:00
const v = (0, index_js_2.getBigInt)(_v);
2022-09-05 23:57:11 +03:00
return {
networkV: ((v >= BN_35) ? v : undefined),
v: Signature.getNormalizedV(v)
};
}
if (yParityAndS != null) {
if (!(0, index_js_2.isHexString)(yParityAndS, 32)) {
throwError("invalid yParityAndS");
}
2022-09-16 05:58:45 +03:00
return { v: (((0, index_js_2.getBytes)(yParityAndS)[0] & 0x80) ? 28 : 27) };
2022-09-05 23:57:11 +03:00
}
if (yParity != null) {
switch (yParity) {
case 0: return { v: 27 };
case 1: return { v: 28 };
}
return throwError("invalid yParity");
}
return throwError("missing v");
})(sig.v, sig.yParityAndS, sig.yParity);
const result = new Signature(_guard, r, s, v);
if (networkV) {
(0, index_js_2.setStore)(result.#props, "networkV", networkV);
}
// If multiple of v, yParity, yParityAndS we given, check they match
if ("yParity" in sig && sig.yParity !== result.yParity) {
throwError("yParity mismatch");
}
else if ("yParityAndS" in sig && sig.yParityAndS !== result.yParityAndS) {
throwError("yParityAndS mismatch");
}
return result;
}
}
exports.Signature = Signature;
//# sourceMappingURL=signature.js.map