diff --git a/backend/contracts/TotpAuthenticator.sol b/backend/contracts/TotpAuthenticator.sol index 46b0d4c..493a4d8 100644 --- a/backend/contracts/TotpAuthenticator.sol +++ b/backend/contracts/TotpAuthenticator.sol @@ -9,17 +9,11 @@ struct AuthData { // fist five digits of the 6-digit totp code tail-padded with a zero and finally parsed to a single number uint256 totp5; // Teh sha256 hash of the complete code parsed to a single number. - uint256 totp6hash; + bytes32 totp6hash; // time-stamp of TOTP code creation. uint256 time; } -struct AuthResponse { - // Has it already been validated. Defaults to false - bool isValidated; - AuthData response; -} - struct Authentication { bool isValid; uint256 time; @@ -32,7 +26,7 @@ contract TotpAuthenticator is Ownable { // Maps a requestId to the requestor/validator and to the auth requested address mapping(uint256 => address[2]) requests; // Maps a requestId to a address and its response. - mapping(uint256 => mapping(address => AuthResponse)) responses; + mapping(uint256 => mapping(address => AuthData)) responses; // // Maps a requestId to a list of address which have already responded (blocklist) // mapping(uint256 => address[]) blocklists; // Maps requestId to completes authentication @@ -43,14 +37,14 @@ contract TotpAuthenticator is Ownable { event EventAuthResponse( address responder, uint256 requestId, - AuthResponse response + AuthData response ); event EventAuthValid(uint256 requestId, Authentication authentication); event EventResetContract(uint256 time); // Create a request for a wallet to authenticate. function setRequest(address _target) public { - uint256 memory _currentCount = reqestCounter; + uint256 _currentCount = requestCounter; requests[_currentCount] = [msg.sender, _target]; requestCounter++; @@ -61,15 +55,15 @@ contract TotpAuthenticator is Ownable { function setResponse( uint256 _requestId, uint256 _totp5, - uint256 _totp5hash, + bytes32 _totp6hash, uint256 _time ) public { require( - responses[_requestId][msg.sender] > 0, + responses[_requestId][msg.sender].totp5 > 0, 'Response already submitted' ); - AuthData _authData = AuthData(_totp5, _totp6hash, _time); + AuthData memory _authData = AuthData(_totp5, _totp6hash, _time); responses[_requestId][msg.sender] = _authData; emit EventAuthResponse(msg.sender, _requestId, _authData); @@ -78,7 +72,6 @@ contract TotpAuthenticator is Ownable { // The Requestor can get the repsonse data. Preferably though the event indexer graph function getResponses(uint256 _requestId, address _responder) public - view returns (AuthData memory) { // Assert that caller created the AuthRequest @@ -90,19 +83,15 @@ contract TotpAuthenticator is Ownable { // @param _requestId the id of the request // @_responseAddress the address which submitted the valid response function authenticate( - uint256 _resquestId, + uint256 _requestId, uint256 _lastDigit, address _responseAddress ) public { // Assert that caller created the AuthRequest require(isValidator(_requestId), 'Validation only by requestor'); - AuthData memory _authData = responses[_responseId][_responseAddress]; - bool memory _isValid = checkHash( - _authData.totp5, - _lastDigit, - _authData.totp6hash - ); + AuthData memory _authData = responses[_requestId][_responseAddress]; + bool _isValid = checkHash(_authData.totp5, _lastDigit, _authData.totp6hash); require(_isValid, 'Onchain validation failed'); Authentication memory authentication = Authentication( @@ -110,7 +99,7 @@ contract TotpAuthenticator is Ownable { block.timestamp, _responseAddress ); - completedAuth[_resquestId] = authentication; + completedAuth[_requestId] = authentication; emit EventAuthValid(_requestId, authentication); } @@ -119,7 +108,7 @@ contract TotpAuthenticator is Ownable { function getAuthentication(uint256 _requestId) public view - returns (Authentication) + returns (Authentication memory) { return completedAuth[_requestId]; } @@ -133,17 +122,24 @@ contract TotpAuthenticator is Ownable { // Check if the sender also submitted the request function isValidator(uint256 _requestId) private returns (bool) { - return msg.sender = requests[_requestId][0]; + return msg.sender == requests[_requestId][0]; + } + + function toBytes(uint256 x) private returns (bytes memory b) { + b = new bytes(32); + assembly { + mstore(add(b, 32), x) + } } // Multiply the 5 didgit response by 10 (smiliar to padding with zero) and add the 6st digit. Then compare the hashes. function checkHash( uint256 _totp5, uint256 _lastDigit, - uint256 _totp6hash + bytes32 _totp6hash ) private returns (bool) { - uint256 memory _totp6 = _totp5 * 10 + _lastDigit; + uint256 _totp6 = _totp5 * 10 + _lastDigit; // Not sure if this returns a bool? - return sha256(_totp6) == _totp6hash; + return sha256(toBytes(_totp6)) == _totp6hash; } } diff --git a/backend/package.json b/backend/package.json index 38fc211..379a7d6 100644 --- a/backend/package.json +++ b/backend/package.json @@ -7,6 +7,8 @@ "@nomicfoundation/hardhat-toolbox": "^1.0.2", "@openzeppelin/contracts": "^4.7.3", "hardhat": "^2.11.1", - "prettier": "^2.7.1" + "prettier": "^2.7.1", + "ts-node": "^10.9.1", + "typescript": "^4.8.3" } } diff --git a/backend/scripts/deploy.ts b/backend/scripts/deploy.ts index 5313c55..39f107c 100644 --- a/backend/scripts/deploy.ts +++ b/backend/scripts/deploy.ts @@ -15,8 +15,17 @@ async function main() { console.log( `Lock with 1 ETH and unlock timestamp ${unlockTime} deployed to ${lock.address}` ) + testTotp() } +async function testTotp() { + const Totp = await ethers.getContractFactory("TotpAuthenticator") + const totp = await Totp.deploy() + + await totp.deployed() + + console.log(`Totp successfully deployed to ${lock.address}`) +} // We recommend this pattern to be able to use async/await everywhere // and properly handle errors. main().catch((error) => {