Signature Verification
Source: Verifying Signature, solidity-by-example.org [7].
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Yul {
function splitSignature(bytes memory signature) public pure returns (
bytes32 r,
bytes32 s,
uint8 v
) {
// Signatures are 65 bytes in length. r => 32, s => 32, v => 1.
// Although some signatures can be packed into 64 bytes.
if (signature.length != 65) revert();
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
}
function verifySignature(
address signer,
bytes32 hash,
bytes memory sig
) public pure returns (bool) {
(bytes32 r, bytes32 s, uint8 v) = splitSignature(sig);
address recovered = ecrecover(hash, v, r, s);
return (recovered != address(0) && recovered == signer);
}
}
byte(a, b) retrieves a single byte at position a in a 32-byte memory word, b. In our case, we are simply saying "Return the first byte in the 32-byte location at add(signature, 0x60)."
ecrecover(a, b, c, d) returns the address of a signer when given four arguments, a, the hash that was signed and b, c, d being the v, r and s components of the signature, respectively.