Skip to content

Commit

Permalink
Add support for EIP-2098 compact signatures (#2246).
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmoo committed Feb 18, 2022
1 parent eb91d70 commit f26074b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
4 changes: 3 additions & 1 deletion docs.wrm/api/utils/bytes.wrm
Original file line number Diff line number Diff line change
Expand Up @@ -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\>\>>

Expand Down
36 changes: 28 additions & 8 deletions packages/bytes/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export interface Signature {

recoveryParam: number;
v: number;

yParityAndS: string
compact: string;
}

///////////////////////////////
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -448,6 +465,9 @@ export function splitSignature(signature: SignatureLike): Signature {
}
}

result.yParityAndS = result._vs;
result.compact = result.r + result.yParityAndS.substring(2);

return result;
}

Expand Down

0 comments on commit f26074b

Please sign in to comment.