library ECDSA {
    /**
    * @dev Recovers the address of who signed the hash sent to the function
    * @param _fingerprint bytes32. Is the sha3 hash of document. Generated with web3.
    * @param _signature bytes. Signature of the sha3 fingerprint of the file.
    */
    function recoverAddress(bytes32 _fingerprint, bytes memory _signature) internal pure returns (address) {
        bytes32 r;
        bytes32 s;
        uint8 v;
        require(_signature.length == 65, "Invalid signature");

        // Divide the signature in r, s and v variables with inline assembly.
        assembly {
          r := mload(add(_signature, 0x20))
          s := mload(add(_signature, 0x40))
          v := byte(0, mload(add(_signature, 0x60)))
        }

        // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
        if (v < 27) {
          v += 27;
        }
        
        require(v == 27 || v == 28, "Invalid signature");
        return ecrecover(toEthSignedMessageHash(_fingerprint), v, r, s);
    }
    
    /**
    * toEthSignedMessageHash
    * @dev prefix a bytes32 value with "\x19Ethereum Signed Message:" and hash the result
    * @param _fingerprint bytes32. Is the sha3 hash of document. Generated with web3.
    */
    function toEthSignedMessageHash(bytes32 _fingerprint) internal pure returns (bytes32) {
        return keccak256(
            abi.encodePacked("\x19Ethereum Signed Message:\n32", _fingerprint)
        );
    } 
}
function recoverAddress(bytes32 _fingerprint, bytes memory _signature) internal pure returns (address) {
    bytes32 r;
    bytes32 s;
    uint8 v;
    require(_signature.length == 65, "Invalid signature");

    // Divide the signature in r, s and v variables with inline assembly.
    assembly {
      r := mload(add(_signature, 0x20))
      s := mload(add(_signature, 0x40))
      v := byte(0, mload(add(_signature, 0x60)))
    }

    // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
    if (v < 27) {
      v += 27;
    }
        
    require(v == 27 || v == 28, "Invalid signature");
    return ecrecover(toEthSignedMessageHash(_fingerprint), v, r, s);
}

/**
 * @dev Recovers the address of who signed the hash sent to the function
 * @param _fingerprint bytes32. Is the sha3 hash of document. Generated with web3.
 * @param _signature bytes. Signature of the sha3 fingerprint of the file.
 */