UNPKG

ox

Version:

Ethereum Standard Library

288 lines 9.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidVError = exports.InvalidYParityError = exports.InvalidSError = exports.InvalidRError = exports.MissingPropertiesError = exports.InvalidSerializedSizeError = void 0; exports.assert = assert; exports.fromBytes = fromBytes; exports.fromHex = fromHex; exports.extract = extract; exports.from = from; exports.fromDerBytes = fromDerBytes; exports.fromDerHex = fromDerHex; exports.fromLegacy = fromLegacy; exports.fromRpc = fromRpc; exports.fromTuple = fromTuple; exports.toBytes = toBytes; exports.toHex = toHex; exports.toDerBytes = toDerBytes; exports.toDerHex = toDerHex; exports.toLegacy = toLegacy; exports.toRpc = toRpc; exports.toTuple = toTuple; exports.validate = validate; exports.vToYParity = vToYParity; exports.yParityToV = yParityToV; const secp256k1_1 = require("@noble/curves/secp256k1"); const Bytes = require("./Bytes.js"); const Errors = require("./Errors.js"); const Hex = require("./Hex.js"); const Json = require("./Json.js"); const Solidity = require("./Solidity.js"); function assert(signature, options = {}) { const { recovered } = options; if (typeof signature.r === 'undefined') throw new MissingPropertiesError({ signature }); if (typeof signature.s === 'undefined') throw new MissingPropertiesError({ signature }); if (recovered && typeof signature.yParity === 'undefined') throw new MissingPropertiesError({ signature }); if (signature.r < 0n || signature.r > Solidity.maxUint256) throw new InvalidRError({ value: signature.r }); if (signature.s < 0n || signature.s > Solidity.maxUint256) throw new InvalidSError({ value: signature.s }); if (typeof signature.yParity === 'number' && signature.yParity !== 0 && signature.yParity !== 1) throw new InvalidYParityError({ value: signature.yParity }); } function fromBytes(signature) { return fromHex(Hex.fromBytes(signature)); } function fromHex(signature) { if (signature.length !== 130 && signature.length !== 132) throw new InvalidSerializedSizeError({ signature }); const r = BigInt(Hex.slice(signature, 0, 32)); const s = BigInt(Hex.slice(signature, 32, 64)); const yParity = (() => { const yParity = Number(`0x${signature.slice(130)}`); if (Number.isNaN(yParity)) return undefined; try { return vToYParity(yParity); } catch { throw new InvalidYParityError({ value: yParity }); } })(); if (typeof yParity === 'undefined') return { r, s, }; return { r, s, yParity, }; } function extract(value) { if (typeof value.r === 'undefined') return undefined; if (typeof value.s === 'undefined') return undefined; return from(value); } function from(signature) { const signature_ = (() => { if (typeof signature === 'string') return fromHex(signature); if (signature instanceof Uint8Array) return fromBytes(signature); if (typeof signature.r === 'string') return fromRpc(signature); if (signature.v) return fromLegacy(signature); return { r: signature.r, s: signature.s, ...(typeof signature.yParity !== 'undefined' ? { yParity: signature.yParity } : {}), }; })(); assert(signature_); return signature_; } function fromDerBytes(signature) { return fromDerHex(Hex.fromBytes(signature)); } function fromDerHex(signature) { const { r, s } = secp256k1_1.secp256k1.Signature.fromDER(Hex.from(signature).slice(2)); return { r, s }; } function fromLegacy(signature) { return { r: signature.r, s: signature.s, yParity: vToYParity(signature.v), }; } function fromRpc(signature) { const yParity = (() => { const v = signature.v ? Number(signature.v) : undefined; let yParity = signature.yParity ? Number(signature.yParity) : undefined; if (typeof v === 'number' && typeof yParity !== 'number') yParity = vToYParity(v); if (typeof yParity !== 'number') throw new InvalidYParityError({ value: signature.yParity }); return yParity; })(); return { r: BigInt(signature.r), s: BigInt(signature.s), yParity, }; } function fromTuple(tuple) { const [yParity, r, s] = tuple; return from({ r: r === '0x' ? 0n : BigInt(r), s: s === '0x' ? 0n : BigInt(s), yParity: yParity === '0x' ? 0 : Number(yParity), }); } function toBytes(signature) { return Bytes.fromHex(toHex(signature)); } function toHex(signature) { assert(signature); const r = signature.r; const s = signature.s; const signature_ = Hex.concat(Hex.fromNumber(r, { size: 32 }), Hex.fromNumber(s, { size: 32 }), typeof signature.yParity === 'number' ? Hex.fromNumber(yParityToV(signature.yParity), { size: 1 }) : '0x'); return signature_; } function toDerBytes(signature) { const sig = new secp256k1_1.secp256k1.Signature(signature.r, signature.s); return sig.toDERRawBytes(); } function toDerHex(signature) { const sig = new secp256k1_1.secp256k1.Signature(signature.r, signature.s); return `0x${sig.toDERHex()}`; } function toLegacy(signature) { return { r: signature.r, s: signature.s, v: yParityToV(signature.yParity), }; } function toRpc(signature) { const { r, s, yParity } = signature; return { r: Hex.fromNumber(r, { size: 32 }), s: Hex.fromNumber(s, { size: 32 }), yParity: yParity === 0 ? '0x0' : '0x1', }; } function toTuple(signature) { const { r, s, yParity } = signature; return [ yParity ? '0x01' : '0x', r === 0n ? '0x' : Hex.trimLeft(Hex.fromNumber(r)), s === 0n ? '0x' : Hex.trimLeft(Hex.fromNumber(s)), ]; } function validate(signature, options = {}) { try { assert(signature, options); return true; } catch { return false; } } function vToYParity(v) { if (v === 0 || v === 27) return 0; if (v === 1 || v === 28) return 1; if (v >= 35) return v % 2 === 0 ? 1 : 0; throw new InvalidVError({ value: v }); } function yParityToV(yParity) { if (yParity === 0) return 27; if (yParity === 1) return 28; throw new InvalidYParityError({ value: yParity }); } class InvalidSerializedSizeError extends Errors.BaseError { constructor({ signature }) { super(`Value \`${signature}\` is an invalid signature size.`, { metaMessages: [ 'Expected: 64 bytes or 65 bytes.', `Received ${Hex.size(Hex.from(signature))} bytes.`, ], }); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Signature.InvalidSerializedSizeError' }); } } exports.InvalidSerializedSizeError = InvalidSerializedSizeError; class MissingPropertiesError extends Errors.BaseError { constructor({ signature }) { super(`Signature \`${Json.stringify(signature)}\` is missing either an \`r\`, \`s\`, or \`yParity\` property.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Signature.MissingPropertiesError' }); } } exports.MissingPropertiesError = MissingPropertiesError; class InvalidRError extends Errors.BaseError { constructor({ value }) { super(`Value \`${value}\` is an invalid r value. r must be a positive integer less than 2^256.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Signature.InvalidRError' }); } } exports.InvalidRError = InvalidRError; class InvalidSError extends Errors.BaseError { constructor({ value }) { super(`Value \`${value}\` is an invalid s value. s must be a positive integer less than 2^256.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Signature.InvalidSError' }); } } exports.InvalidSError = InvalidSError; class InvalidYParityError extends Errors.BaseError { constructor({ value }) { super(`Value \`${value}\` is an invalid y-parity value. Y-parity must be 0 or 1.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Signature.InvalidYParityError' }); } } exports.InvalidYParityError = InvalidYParityError; class InvalidVError extends Errors.BaseError { constructor({ value }) { super(`Value \`${value}\` is an invalid v value. v must be 27, 28 or >=35.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Signature.InvalidVError' }); } } exports.InvalidVError = InvalidVError; //# sourceMappingURL=Signature.js.map