near / NEPs

The Near Enhancement Proposals repository
https://nomicon.io
216 stars 138 forks source link

Chain Signatures #503

Open DavidM-D opened 1 year ago

DavidM-D commented 1 year ago

The purpose of this issue is to explain product requirements of Chain Signatures. We don't go into implementation details because those are changeable.

Description

Chain Signatures allow for a smart contract to call an async method

async sign(payload: Bytes) -> Signature

The signature is of the paylaod provided using a key unique to the caller. The output will always be the same if the caller and payload remain the same. The signature is an ECDSA signature on the Secp256k1 curve.

Use cases

For the sake of clarity I've broken down the use cases into simple component parts, but practically we're going to be using all of these use cases in a single application.

Oauth controlled Etherium accounts

On-boarding is a huge problem for decentralized applications. If we want widespread adoption we can't expect people to keep seed phrases safe in order to use an application.

An attractive way of managing Web3 accounts is to use existing Web2 accounts to on-board users. This can be done in the following way:

  1. Deploy a NEAR contract that allows the bearer of a users JWT token to sign an Etherium transactions
  2. The user validates their identity with a third party receiving a JWT Token
  3. The user uses that JWT token[^3] to interact with Etherium applications via the NEAR contract for for the duration of it's validity

Any method of controlling a NEAR account can also be used to control a cross chain account.

Keypom on Polygon

Keypom provides zero friction onboarding and transactions for NEAR. They are generally used for NFT drops, FT drops and ticketing.

They uses unique features of the NEAR account model to allow for easier user on-boarding:

  1. The developer creates a restricted NEAR account
  2. The account is funded with NEAR
  3. The user is give a key with limited control of the account
  4. The user uses the funded account to call controlled endpoints on NEAR
  5. The user returns the remaining funds to the developer and their account is unlocked

This allows easy on-boarding to decentralized apps. The accounts are initially restricted to prevent the user being able to simply withdraw the NEAR from the account.

With Chain Signatures you can do the same thing but across many chains, for example Polygon:

  1. The developer creates a restricted NEAR account with a key
  2. The account is funded with NEAR and MATIC
  3. The user is give a key with limited control of the account
  4. The user uses the funded account to sign payloads calling controlled endpoints on Polygon
  5. The user returns the remaining funds to the developer and their account is unlocked

This allows developers to pay for users to use arbitrary contracts on arbitrary chains.

Decentralized Clients

One of the big problems in decentralized applications is that while the smart contracts are tamper-proof, the clients that access them generally aren't. This allows practically complete control over any users account provided they are using the frontend assets that you serve. This has security, trust and regulatory implications.

When smart contracts can sign payloads you can start using signed exchanges (or polyfills) to require HTTP exchanges to be signed by a certain key. If it is not signed with this key the SSL certificate is considered invalid. This means that individual users cannot be served invalid frontends without it being generally observable and non repudiable.

Communication with private NEAR Shards

Currently companies like Calimero make private NEAR shards. Currently sending messages to and from these NEAR shards is a pain. If each shard had the ability to sign their message queues, they could be securely sent from one shard to another. Thus you could communicate bidirectionally with any shard as easily as you can with a contract on your own shard.

Furthermore this could dramatically simplify the sharding model of NEAR, by treating each NEAR shard like one would a private shard.

Future use cases

Chain decryptable messages [^1]

Certain on chain keys allow the following flow:

  1. The sender sends encrypted data onto the chain
  2. When a receiver proves they have a right to the data it is re-encrypted with their key
  3. The receiver then decrypts the data

This is useful for paid content, whatsapp messages and any private data on chain.

Apart from the obvious this also enables:

On Chain Domain Control[^2]

It may be possible to use DNSSEC & email signatures to control the DNS record and the sending of emails from a domain.

There are practical issues

[^1]: This might require BLS signatures and further work description of one implementation exists here [^2]: This is speculative [^3]: JSON Web Tokens are a standard RFC 7519 method for representing claims securely between two parties. They are used in this example to represent the claim that someone is the owner of an Oauth account.

DavidM-D commented 1 year ago

I'll clean this up tomorrow

akhi3030 commented 1 year ago

@DavidM-D:

volovyks commented 1 year ago

@akhi3030 We are using JWT Tokens to authenticate users on the MPC Recovery server. It's a JSON object issued and signed by an auth provider (in our case it's Firebase). More info:

volovyks commented 1 year ago

More about Keypom: https://keypom-docs.pages.dev/

walnut-the-cat commented 1 year ago

Deploy a NEAR contract that allows the bearer of a users JWT token to sign an Etherium transactions

I assume 'bearer' here is multiple entities each owning 'part of private key'?

Keypom on Polygon

Do we imagine chain signature to completely replace keypom in the long term?

ilblackdragon commented 1 year ago

Questions:

async sign(payload: Bytes) -> Signature

Only one curve is supported? That will be limiting given only EVMs and Bitcoin are using Secp256k1 and the rest are using ed25519

Additionally, it's helpful to have multiple public keys per each network.

a smart contract to call an async method

If it is async method, is it going to return a Promise<Signature>? What is the point of returning value here, as smart contract won't be able to use it, right?

May be expanding on how would this payload + signature be routed to another chain would be helpful to understand the interface.


There are people with existing addresses that they would want to connect their existing addresses to their NEAR account. Would there be a way to support that and what interface this would look like.

DavidM-D commented 1 year ago

@ilblackdragon

async sign(payload: Bytes) -> Signature

Is mainly for brevity, practically it'd likely be more like:

async sign(payload: Bytes, derivation_path: [u8; 32], ecdsa_Curve: Curve) -> Signature 

The derivation path depends on us doing per key derivation rather than generation but it allows contracts to have an unlimited number of keys without a cost overhead.

Only one curve is supported?

It's relatively simple for us to be curve agnostic (Secp256k1, Secp256r1) but hard for us to be signature scheme agnostic (ECDSA, Ed25519).

What is the point of returning value here, as smart contract won't be able to use it, right?

I'm not married to this, but there are use cases. If you have a commonly called function for example serving index.html you can cache the signature of the response in the smart contract. This allows you to make a verifiable view call to any indexer as the response can be signed. If the cache doesn't exist you have to generate the response going through the blockchain.

This is of course possible with FE/Indexer magic but it's a bit more of a faff for developers.

That will be limiting given only EVMs and Bitcoin are using Secp256k1 and the rest are using ed25519

Going down CMC top L1/L2s ECDSA support: Name Supports ECDSA
Bitcoin
Etherium
BNB
Ripple
Cardano ❌[^1]
Solana ❌[^1]
Tron
TON
Polkadot
Polygon
Stellar
Avalanche
Monero
Cosmos
Hedera
Filecoin
Internet Computer
Mantle
Cronos
Aptos
VeChain
NEAR

It's not terrible but not perfect.

There are people with existing addresses that they would want to connect their existing addresses to their NEAR account.

One option is to get them to keep storing the keys the way they currently are, for example in MetaMask and including an interface to sign payloads with these keys on the frontend of applications.

Another more involved one is to put your encrypted key on chain using Chain decryptable messages, but we'd need to have a think about whether that's safe. This gives you access to the key whenever you have access to your NEAR account, but since the key is rebuilt you lose restricted accounts and client side key extraction is possible.

[^1]: But there is a builtin function to verify ECDSA signatures

bowenwang1996 commented 1 year ago

@DavidM-D is there a separate thread to discuss implementation ideas?