keybase / keybase-issues

A single repo for managing publicly recognized issues with the keybase client, installer, and website.
901 stars 37 forks source link

integration discussion - blockchain address and contract proofs #2542

Open brandoncurtis opened 8 years ago

brandoncurtis commented 8 years ago

What follows are a bunch of random thoughts I had while reading other discussions about Bitcoin and Ethereum proofs.

@pipermerriam originally suggested Ethereum address ownership verification in #518 in September 2015, in the form of "a blessed contract with published and audited source code that users could send a transaction with a signed blob of data to it, which could then be independently verified by anyone running an ethereum node."

I can think of four ways that an Ethereum address proof could be executed:

  1. One-Way Verification by signing the Ethereum public address. Demonstrates that you CLAIM ownership of the address. This is how the Bitcoin address verification currently works.
  2. Two-Way Verification by signing a proof statement with the Ethereum private key, then signing the signed proof statement with your signed PGP key and publishing it somewhere; should be possible using web3.js, as discussed in ethereum/web3.js#392
  3. Two-Way Verification by transacting with The Official Verification Contract. The prover sends a signed blob of data to the contract.
  4. Two-Way Verification by transacting with an address that is generated, e.g. from the prover's key and keybase username or something:
keybaseuser="brandoncurtis"
ethaddress="0xd19FDa898E1e1F3b1e372Bf131257e0f4a9EF7DB"
shasum=`printf '%s' "$ethaddress""$keybaseuser" | sha256sum | cut -d ' ' -f 1`
etheverificationaddress=`python3 -c "print(hex(int(format(int('$shasum',16),'b')[:160],2)))"`
geth attach --exec "eth.sendTransaction( { from: $ethaddress, to: $ethverificationaddress, value: 1 } )"

Likewise, there are at least two ways that this proof could be machine-verified:

  1. By hooking into an Ethereum client via JSON-RPC and parsing the blockchain itself;
  2. By using the API of a service like Etherchain, which does the blockchain scraping for you. (this service could lie to you, so this adds another link to the trust chain)

In the case of Ethereum, what you're proving is actually kind of tricky. The logic chain for a two-way verification on a cryptocurrency address based on a transaction is something like this:

User A transacts from Address X ∴ User A has transact authority from Address X ∴ User A holds the private key for Address X

Unlike Bitcoin where the links in this chain generally hold, Ethereum is designed to be an ecosystem where contracts call other contracts call other contracts. If I receive a transaction at Address Y from Address X, all that demonstrates is that User A has a mechanism for getting Address X to transact with Address Y, and says nothing about whether User A 'owns' Address X or holds the Address X private key.

Perhaps even more interesting is the prospect of proving ownership of an Ethereum contract itself. This would probably involve hashing and signing something and publishing it right into the contract at creation.

cjb commented 8 years ago

There's a tough trade-off here, where trusting Etherchain breaks the Keybase model where your client directly talks to e.g. Twitter, and doesn't trust any intermediary including Keybase itself; but verifying with JSON-RPC introduces a new (and idiosyncratic) proof type, thus enlarging the attack surface against Keybase clients. We don't want to add lots of new proof types.

So it feels to me like neither solution is attractive.

brandoncurtis commented 8 years ago

Thanks @cjb. I see this component of the issue is being discussed in #2523, "Reducing attack surface of local client's proof verification code".

pipermerriam commented 8 years ago

@cjb can you expand a bit on how you feel this would increase the attack surface? It feels the same as the HTTP request parsing that other proof types use.

On Mon, Sep 5, 2016, 9:02 AM Brandon Curtis notifications@github.com wrote:

Thanks @cjb https://github.com/cjb. I see this component of the issue is being discussed in #2523 https://github.com/keybase/keybase-issues/issues/2523, "Reducing attack surface of local client's proof verification code".

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/keybase/keybase-issues/issues/2542#issuecomment-244766847, or mute the thread https://github.com/notifications/unsubscribe-auth/AAyTgj_KtBDe06Fcu1Vd1ityvF6OxuZcks5qnC8agaJpZM4J0rmv .

cjb commented 8 years ago

@pipermerriam It means every Keybase client doing proof checking now has to know how to speak JSON-RPC. In theory, there could be a vulnerability in the JSON-RPC library that's remotely exploitable. So we've expanded the attack surface of Keybase clients to include having to worry about JSON-RPC, as well as the existing HTTP handlers.

I agree that it's similar to HTTP technically. But there's still reason not to add so many HTTP-like protocols.

pipermerriam commented 8 years ago

The JSON-RPC interaction necessary to do the ethereum verification is an HTTP request that returns JSON so I am still failing to see how this would increase attack surface. Could you expand more on how this increases attack surface (beyond the increased surface of another HTTP based verification)

On Mon, Sep 5, 2016, 12:32 PM Chris Ball notifications@github.com wrote:

@pipermerriam https://github.com/pipermerriam It means every Keybase client doing proof checking now has to know how to speak JSON-RPC. In theory, there could be a vulnerability in the JSON-RPC library that's remotely exploitable. So we've expanded the attack surface of Keybase clients to include having to worry about JSON-RPC, as well as the existing HTTP handlers.

I agree that it's similar to HTTP technically. But there's still reason not to add so many HTTP-like protocols.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/keybase/keybase-issues/issues/2542#issuecomment-244796732, or mute the thread https://github.com/notifications/unsubscribe-auth/AAyTguF4deIJufuCw1EXMdi9RwPmEh42ks5qnGA5gaJpZM4J0rmv .

cjb commented 8 years ago

Oh! I'm sorry, I thought it was a separate TCP protocol. That's interesting.

pipermerriam commented 8 years ago

No problem. Glad to clear up any misunderstanding.

On Mon, Sep 5, 2016, 12:41 PM Chris Ball notifications@github.com wrote:

Oh! I'm sorry, I thought it was a separate TCP protocol. That's interesting.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/keybase/keybase-issues/issues/2542#issuecomment-244797623, or mute the thread https://github.com/notifications/unsubscribe-auth/AAyTgoXAf3OFpHkTR8EXbIemV0f6in8aks5qnGJXgaJpZM4J0rmv .

luisivan commented 7 years ago

Any update on this? Just One-Way verification alone would be a huge feature for Ethereum apps.

rabbit commented 7 years ago

I would use this. designing around trust is kinda the point. only thing etherchain could do is falsely claim no proof or contract exists, a vulnerability that can be removed by any mirror including localhost.

after weighing your options I think simplest route, @brandoncurtis mentioned as option 3, would be a well-known registry contract that updates signed blobs. only the user can update their proof however any signed tx can be relayed. a thoughtful implementation would take advantage of ENS so your registry could live at keybase.eth and resolve [username].keybase.eth to their ethereum address.

alternatively, here's a naive untested implementation to keep things rolling:

contract KeybaseRegistry {
    mapping (address => bytes) proof;

    // owner of the account can only change their proof
    function submit(bytes signed) {
        proof[msg.sender] = signed;
    }

    function resolve(address id) constant returns (bytes) {
        return proof[id];
    }
}
kbreg = web3.eth.contract(abi).at(registry);
kbreg.submit(myProof);
kbreg.resolve(myAddress); // => myProof
rabbit commented 7 years ago

just to note I left out reverse lookup on purpose as keybase is the authority on that namespace (use keybase to lookup on usernames). if you wanted to do name lookup from the ethereum side you would either need to index by keybase key+username and anticipate false claims or have keybase deploy a contract they manage that reports the kb username + eth address pair reliably. The advantage there being that if keybase is compromised they can trash their reverse lookup contract without impacting any of the published proofs.

jmlubin commented 7 years ago

I would be grateful and thankful if the keybase team implemented ethereum based verifications. We at ConsenSys would be happy to discuss collaboration on this if you'd like.