Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cryptographically Secure Delegated Signing Authority for Validators #18

Open
blueslurpee opened this issue Dec 27, 2021 · 3 comments
Open

Comments

@blueslurpee
Copy link
Contributor

Hey Guys,

Hope everyone has been having a nice holiday season.

I believe I have a solution for the delegated signing problem which involves encrypting a delegated signing key, and storing it on chain.

I am working on a proof of concept and hope to be able to demonstrate it in the next few days. A few different libraries need to be tied together to make it work, unfortunately they all implement the encryption differently.

Corey

@blueslurpee
Copy link
Contributor Author

blueslurpee commented Jan 2, 2022

Using Metamask we can retrieve the encryption public key of the user:

requestEncryptionKey = async (address: string) => {
        return await ethereum.request({
            method: 'eth_getEncryptionPublicKey',
            params: [address],
        })
    }

Once we have the encrpytion public key, we can then encrypt messages with the help of the eth-sig-util library.

Notice we are encrypting a randomly generated private signing key. (The "signer key")

const sigUtil = require("eth-sig-util");

encryptMessage = async (address: string) => {
        const encryptionPublicKey =  await this.requestEncryptionKey(address)
        const signerKey = ethers.Wallet.createRandom().privateKey

        const cipherText = ethUtil.bufferToHex(
          Buffer.from(
            JSON.stringify(
              sigUtil.encrypt(
                encryptionPublicKey,
                { data: signerKey },
                'x25519-xsalsa20-poly1305'
              )
            ),
            'utf8'
          )
        );

        return [cipherText, address]
    }

The cipher text is returned. According to what I have read so far, this encrypted cipher text can only be successfully decrypted by the holder of the encryption public key. So it is thus safe to store on-chain, which is our only truly persistent storage.

Afterwards, the user can query the chain and then decrypt the signer key via:

    decryptMessage = async (cipherText: string, address: string) => {
        return await ethereum.request({
            method: 'eth_decrypt',
            params: [cipherText, address],
        })
    }

Then the use can use this signer key to sign matching transactions. We will build a seamless user flow to incorporate the various elements. (i.e. the user will need to periodically send the signer key wallet ether to pay gas).

I made some good progress and I believe this is the best way to move forward with a cryptographically secure implementation of the problem. There are still lots of implementation details that need to be ironed out. @tejareddy8888 Perhaps you could prepare our contracts to incorporate this?

@Sinaniya @Ankan0011 @tejareddy8888

I will turn my attention to the history problem using the Graph protocol. Expect another issue on that in the next few days.

Hope you guys had a wonderful holiday.

@tejareddy8888
Copy link
Contributor

tejareddy8888 commented Jan 2, 2022

@blueslurpee ,

I am okay with this implementation and I can think of what changes does the contract need to adapt to this.

Just to give a gist, I also had a different Idea of doing this via using Gelato(https://docs.gelato.network/introduction/master) for automated transaction execution with polywrap resolver. Where we can automate/ schedule the smart contract function and where the automated call queries the data using the polywrap resolver with the HTTP plugin in it.

Regarding the Graph Protocol, I have already built a subgraph on multiple Contracts earlier, I have a good idea about it.

The graph protocol's testnet for decentralized approach is in Rinkeby only which is a limitation. So, we can stick to a centralized approach here for two reasons. First, the data we are handling here is publicly viewable and it's immutable, just that we are viewing in a queriable way. Second, Centralized Approach is quite fast and we don't need any GRT tokens or being any network participant in the graph Protocol.

https://github.com/blockchain-etl/ethereum-etl have a look at this Blockchain ETL approach

Happy New Year and hope you had a great vacation.

@blueslurpee
Copy link
Contributor Author

Thanks will look into both of these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants