Add support for EIP-2098 compact signatures (#2246).

This commit is contained in:
Richard Moore 2022-02-18 18:54:00 -05:00
parent eb91d708ac
commit f26074b92b
2 changed files with 31 additions and 9 deletions

@ -38,8 +38,10 @@ _heading: Signature @<Signature>
- **r** and **s** --- The x co-ordinate of **r** and the **s** value of the signature
- **v** --- The parity of the y co-ordinate of **r**
- **_vs** --- The [compact representation](link-eip-2098) of the **s** and **v**
- **yParityAndS** --- The [compact representation](link-eip-2098) of the **s** and **v**
- **_vs** --- Deprecated property; renamed to yParityAndS
- **recoveryParam** --- The normalized (i.e. 0 or 1) value of **v**
- **compact** - The full siggnature using [compact representation](link-eip-2098)
_heading: Raw Signature @<signature-raw> @inherit<string\<[[DataHexString]]\<65\>\>>

@ -46,6 +46,9 @@ export interface Signature {
recoveryParam: number;
v: number;
yParityAndS: string
compact: string;
}
///////////////////////////////
@ -328,24 +331,38 @@ export function hexZeroPad(value: BytesLike, length: number): string {
}
export function splitSignature(signature: SignatureLike): Signature {
const result = {
r: "0x",
s: "0x",
_vs: "0x",
recoveryParam: 0,
v: 0
v: 0,
yParityAndS: "0x",
compact: "0x"
};
if (isBytesLike(signature)) {
const bytes: Uint8Array = arrayify(signature);
if (bytes.length !== 65) {
logger.throwArgumentError("invalid signature string; must be 65 bytes", "signature", signature);
}
let bytes: Uint8Array = arrayify(signature);
// Get the r, s and v
result.r = hexlify(bytes.slice(0, 32));
result.s = hexlify(bytes.slice(32, 64));
result.v = bytes[64];
if (bytes.length === 64) {
// EIP-2098; pull the v from the top bit of s and clear it
result.v = 27 + (bytes[32] >> 7);
bytes[32] &= 0x7f;
result.r = hexlify(bytes.slice(0, 32));
result.s = hexlify(bytes.slice(32, 64));
} else if (bytes.length === 65) {
result.r = hexlify(bytes.slice(0, 32));
result.s = hexlify(bytes.slice(32, 64));
result.v = bytes[64];
} else {
logger.throwArgumentError("invalid signature string", "signature", signature);
}
// Allow a recid to be used as the v
if (result.v < 27) {
@ -448,6 +465,9 @@ export function splitSignature(signature: SignatureLike): Signature {
}
}
result.yParityAndS = result._vs;
result.compact = result.r + result.yParityAndS.substring(2);
return result;
}