ethereumproject / ECIPs

The Ethereum Classic Improvement Proposal
55 stars 40 forks source link

Utilizing a second authentication method to prove ownership and facilitate fund recovery in the event of a theft #70

Open pyskell opened 7 years ago

pyskell commented 7 years ago

ECIP: TBD Title: Utilizing a second authentication method to prove ownership and facilitate fund recovery in the event of a theft Status: Draft Type: Security Author: Pyskell Created: 2017-07-21

Abstract

We essentially live in the wild west of currency, we have no central authority, and therefore we need to be able to provide users with adequate means to protect themselves.

Issue

When a wallet's private key is stolen it becomes very hard or impossible to prove ownership of the stolen funds because both the attacker and the legitimate owner now control the private key and there is no way to prove legitimate ownership.

Solution

Provide a secondary means of authentication via a contract on the Ethereum Classic blockchain. This secondary authentication will serve solely to prove ownership, and is in no way used for transferring or accessing funds.

Current Scenario

SecondAuth Scenario

pyskell commented 7 years ago

I also got a bit ahead of myself when writing this up so here's some additional points to hopefully facilitate discussion:

Possible Concerns

Additional Thoughts

Sample Contract Code

pragma solidity ^0.4.13;
contract SecondAuth {
    struct HashData{
        // Stores one of a keccak256, sha3, sha256, ripemd160, 
        // or any other hash which fits inside 32 bytes
        bytes32 byteHash;
        // Stores the block number when the hash for an address was committed
        uint hashCommitBlock;
    }

    // Both the event and public hashData are provided because events, 
    // although free to read, are not guaranteed to exist forever in the blockchain

    // ~500 gas to read / 0.000002 ETC (@4Gwei)
    mapping(address => HashData) public hashData;
    event StoreHash(address sender, bytes32 byteHash, uint hashCommitBlock);

    // ~66000 gas / 0.000264 ETC (@4 Gwei)
    function setHash(bytes32 byteHash) returns (bool success){
        if (hashData[msg.sender].byteHash == 0){
            hashData[msg.sender].byteHash = byteHash;
            hashData[msg.sender].hashCommitBlock = block.number;

            StoreHash(msg.sender, byteHash, block.number);

            return true;
        }

        return false;
    }
}
elaineo commented 7 years ago

What about building the 2FA into the wallet, rather than storing the hash separately? (eg, @Dexaran example here: https://github.com/Dexaran/Secret/blob/master/Secret.sol)

the password could still be added after the fact. Something like:

contract Bad_Guy_Owner{
    bytes32 public secret;
    bool locked = false;
    address public owner = msg.sender;
    function() payable
    {

    }
    function set_secret(bytes32  _secret)
    {
        if(msg.sender == owner && !locked) {
             secret = _secret;
             locked = true;
       } else {
           throw;
       }
    }

    function give_Me_Money(string _data)
    {
        if(msg.sender == owner && sha3(_data) == secret)
        {
            owner.send(this.balance);
        }
    }

}
elaineo commented 7 years ago

i guess the use case you're describing is pretty different, because it's a case where stolen funds have ended up at an exchange.

pyskell commented 7 years ago

Yeah, this is for proving ownership of stolen funds with the goal being to have it as cheap and simple for an end user and the exchange as possible. While also being easy to implement for wallet software.

Edit: It's also not simply for exchanges, but any legitimate business where stolen funds can end up.

realcodywburns commented 7 years ago

It seems like using 'raw' accounts as a general practice is a bad habit. If accounts are only used to manage contracts instead of holding funds they are less of a problem.

pyskell commented 7 years ago

@realcodywburns By raw accounts do you mean accounts that directly hold funds?