@ethersproject/bytes
Advanced tools
Comparing version 5.0.0-beta.121 to 5.0.0-beta.122
@@ -10,7 +10,15 @@ export declare type Bytes = ArrayLike<number>; | ||
} | ||
export declare type SignatureLike = { | ||
r: string; | ||
s?: string; | ||
_vs?: string; | ||
recoveryParam?: number; | ||
v?: number; | ||
} | BytesLike; | ||
export interface Signature { | ||
r: string; | ||
s: string; | ||
recoveryParam?: number; | ||
v?: number; | ||
_vs: string; | ||
recoveryParam: number; | ||
v: number; | ||
} | ||
@@ -31,3 +39,3 @@ export declare function isBytesLike(value: any): value is BytesLike; | ||
export declare function hexZeroPad(value: BytesLike, length: number): string; | ||
export declare function splitSignature(signature: BytesLike | Signature): Signature; | ||
export declare function splitSignature(signature: SignatureLike): Signature; | ||
export declare function joinSignature(signature: Signature): string; |
137
index.js
@@ -257,42 +257,117 @@ "use strict"; | ||
exports.hexZeroPad = hexZeroPad; | ||
function isSignature(value) { | ||
return (value && value.r != null && value.s != null); | ||
} | ||
function splitSignature(signature) { | ||
var v = 0; | ||
var r = "0x", s = "0x"; | ||
if (isSignature(signature)) { | ||
if (signature.v == null && signature.recoveryParam == null) { | ||
errors.throwError("at least on of recoveryParam or v must be specified", errors.INVALID_ARGUMENT, { argument: "signature", value: signature }); | ||
var result = { | ||
r: "0x", | ||
s: "0x", | ||
_vs: "0x", | ||
recoveryParam: 0, | ||
v: 0 | ||
}; | ||
if (isBytesLike(signature)) { | ||
var bytes = arrayify(signature); | ||
if (bytes.length !== 65) { | ||
errors.throwArgumentError("invalid signature string; must be 65 bytes", "signature", signature); | ||
} | ||
r = hexZeroPad(signature.r, 32); | ||
s = hexZeroPad(signature.s, 32); | ||
v = signature.v; | ||
if (typeof (v) === "string") { | ||
v = parseInt(v, 16); | ||
// Get the r and s | ||
result.r = hexlify(bytes.slice(0, 32)); | ||
result.s = hexlify(bytes.slice(32, 64)); | ||
// Reduce v to the canonical 27 or 28 | ||
result.v = bytes[64]; | ||
if (result.v !== 27 && result.v !== 28) { | ||
result.v = 27 + (result.v % 2); | ||
} | ||
var recoveryParam = signature.recoveryParam; | ||
if (recoveryParam == null && signature.v != null) { | ||
recoveryParam = 1 - (v % 2); | ||
// Compute recoveryParam from v | ||
result.recoveryParam = (result.v - 27); | ||
// Compute _vs from recoveryParam and s | ||
if (result.recoveryParam) { | ||
bytes[32] |= 0x80; | ||
} | ||
v = 27 + recoveryParam; | ||
result._vs = hexlify(bytes.slice(32, 64)); | ||
} | ||
else { | ||
var bytes = arrayify(signature); | ||
if (bytes.length !== 65) { | ||
throw new Error("invalid signature"); | ||
result.r = signature.r; | ||
result.s = signature.s; | ||
result.v = signature.v; | ||
result.recoveryParam = signature.recoveryParam; | ||
result._vs = signature._vs; | ||
// Normalize v into a canonical 27 or 28 | ||
if (result.v != null && !(result.v == 27 || result.v == 28)) { | ||
result.v = 27 + (result.v % 2); | ||
} | ||
r = hexlify(bytes.slice(0, 32)); | ||
s = hexlify(bytes.slice(32, 64)); | ||
v = bytes[64]; | ||
if (v !== 27 && v !== 28) { | ||
v = 27 + (v % 2); | ||
// Populate a missing v or recoveryParam if possible | ||
if (result.recoveryParam == null && result.v != null) { | ||
result.recoveryParam = 1 - (result.v % 2); | ||
} | ||
else if (result.recoveryParam != null && result.v == null) { | ||
result.v = 27 + result.recoveryParam; | ||
} | ||
else if (result.recoveryParam != null && result.v != null) { | ||
if (result.v !== 27 + result.recoveryParam) { | ||
errors.throwArgumentError("signature v mismatch recoveryParam", "signature", signature); | ||
} | ||
} | ||
// Make sure r and s are padded properly | ||
if (result.r != null) { | ||
result.r = hexZeroPad(result.r, 32); | ||
} | ||
if (result.s != null) { | ||
result.s = hexZeroPad(result.s, 32); | ||
} | ||
// If the _vs is available, use it to populate missing s, v and recoveryParam | ||
// and verify non-missing s, v and recoveryParam | ||
if (result._vs != null) { | ||
result._vs = hexZeroPad(result._vs, 32); | ||
if (result._vs.length > 66) { | ||
errors.throwArgumentError("signature _vs overflow", "signature", signature); | ||
} | ||
var vs = arrayify(result._vs); | ||
var recoveryParam = ((vs[0] >= 128) ? 1 : 0); | ||
var v = 27 + result.recoveryParam; | ||
// Use _vs to compute s | ||
vs[0] &= 0x7f; | ||
var s = hexlify(vs); | ||
// Check _vs aggress with other parameters | ||
if (result.s == null) { | ||
result.s = s; | ||
} | ||
else if (result.s !== s) { | ||
errors.throwArgumentError("signature v mismatch _vs", "signature", signature); | ||
} | ||
if (result.v == null) { | ||
result.v = v; | ||
} | ||
else if (result.v !== v) { | ||
errors.throwArgumentError("signature v mismatch _vs", "signature", signature); | ||
} | ||
if (recoveryParam == null) { | ||
result.recoveryParam = recoveryParam; | ||
} | ||
else if (result.recoveryParam !== recoveryParam) { | ||
errors.throwArgumentError("signature recoveryParam mismatch _vs", "signature", signature); | ||
} | ||
} | ||
// After all populating, both v and recoveryParam are still missing... | ||
if (result.v == null && result.recoveryParam == null) { | ||
errors.throwArgumentError("signature requires at least one of recoveryParam, v or _vs", "signature", signature); | ||
} | ||
// Check for canonical v | ||
if (result.v !== 27 && result.v !== 28) { | ||
errors.throwArgumentError("signature v not canonical", "signature", signature); | ||
} | ||
// Check that r and s are in range | ||
if (result.r.length > 66 || result.s.length > 66) { | ||
errors.throwArgumentError("signature overflow r or s", "signature", signature); | ||
} | ||
if (result._vs == null) { | ||
var vs = arrayify(result.s); | ||
if (vs[0] >= 128) { | ||
errors.throwArgumentError("signature s out of range", "signature", signature); | ||
} | ||
if (result.recoveryParam) { | ||
vs[0] |= 0x80; | ||
} | ||
result._vs = hexlify(vs); | ||
} | ||
} | ||
return { | ||
r: r, | ||
s: s, | ||
recoveryParam: (v - 27), | ||
v: v | ||
}; | ||
return result; | ||
} | ||
@@ -299,0 +374,0 @@ exports.splitSignature = splitSignature; |
{ | ||
"name": "@ethersproject/bytes", | ||
"version": "5.0.0-beta.121", | ||
"version": "5.0.0-beta.122", | ||
"description": "Bytes utility functions for ethers.", | ||
@@ -23,3 +23,3 @@ "main": "index.js", | ||
}, | ||
"tarballHash": "0x2e2303404d5404c13d89982247ab689730f78864da05085cd17287b9c0f98c1d" | ||
"tarballHash": "0x989109a9daa33fcbcde72cd8b44e686b3b342585ae60d066cb49f0d613c16af9" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16189
421