CosmWasm / cosmwasm

Framework for building smart contracts in Wasm for the Cosmos SDK
https://www.cosmwasm.com/
Apache License 2.0
1.06k stars 334 forks source link

Define Crypto API (meta) #751

Closed ethanfrey closed 3 years ago

ethanfrey commented 3 years ago

There have been a number of requests for suporting various signature verification as "pre-compiles", such as #583 as well as a number of requests in chats. This is an overview ticket to work out what APIs we would like to support. Each individual algorithm should be a separate PR (and maybe a breakout issue). You may also want to address #602 to allow more complex return values in these APIs.

Very important:

Serious Consideration:

Bonus Points:

ethanfrey commented 3 years ago

Decision was made to:

  1. Focus on supporting the "must-haves" with clean APIs and a gas metering strategy
  2. Look into bls12-381 pairing operations after (when there is time)
  3. Add other signature verification algorithms only when strong need/clear request (but the pattern is laid out)
  4. Not worry about hashes - those work fine compiled into wasm, we need a clear case when those are an issue
maurolacy commented 3 years ago

Some comments regarding these signature verification schemes.

All these schemes(except for the Cosmos alternative), use secp256k1.

My question is: At which level our API must handle signature verification for the different blockchains? That is, what are the formats for message, pubkey, and signature, that we must support as inputs in each case?

Moreover: From which sources do you recommend obtaining (or how to generate) messages, signatures and pubkeys that are compatible / valid for each blockchain? So that I can build test examples on how to deserialize them? The issue here seems to be more about deserialization formats and encodings for messages, keys, and signatures, than anything else.

After that, it will be easy for me to wrap and organize the needed methods / structures (probably from different crates), so that this verification functionality is readily available for contracts.

ethanfrey commented 3 years ago

@webmaster128 had made the proposal that we just define one canonical secp256k1 verify function. And the mapping from chain-specific format to this canonical format happen in the wasm contract. If we can produce some examples that do that for Cosmos SDK, Ethereum, and BTC, then I am happy.

One API function, a sample contract with 2 different calls, mapping the various chain formats to the underlying curve

ethanfrey commented 3 years ago

Moreover: From which sources do you recommend obtaining (or how to generate) messages, signatures and pubkeys that are compatible / valid for each blockchain? So that I can build test examples on how to deserialize them? The issue here seems to be more about deserialization formats and encodings for messages, keys, and signatures, than anything else.

Many of us can get a good Cosmos example. Ask in discord, someone in the team may be able to give good Eth or BTC reference data

maurolacy commented 3 years ago

Thanks for the answers. I'll work in the Cosmos example then (after getting some useful data / examples).

By the way, I've found some data in https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/keeper/testdata/genesis.json#L157-L163. I guess the signature is for the json encoded message, above, but I'm not sure. Wonder if this could be useful for tests.

webmaster128 commented 3 years ago

Here you find good set of secp256k1 signatures to test the verification: https://github.com/cosmos/cosmjs/blob/v0.24.0-alpha.22/packages/crypto/src/secp256k1.spec.ts#L195-L517. message is the encoded transaction data. It goes through sha256 (the prehash) in order to be small enough to fit on the elliptic curve. How message is created on different chains does not matter to the signature verification API.

webmaster128 commented 3 years ago

Here you find good set of secp256k1 signatures to test the verification: https://github.com/cosmos/cosmjs/blob/v0.24.0-alpha.22/packages/crypto/src/secp256k1.spec.ts#L195-L517.

Unfortunately those do not directly show the public key. It must be calculated from the private key. But I can do that later today.

ethanfrey commented 3 years ago

There is also https://github.com/cosmos/cosmjs/blob/d0833a34f48733407c9947fafb5c773bca8850d6/packages/proto-signing/src/testutils.spec.ts

which is mainly targeting signing, but it has compressed pubkey, signBytes, and signature for 3 test cases. (The pubkey is on the top line outside the test cases, and base64 encoded not hex)

webmaster128 commented 3 years ago

@maurolacy signBytes is the same as message from my comment. sha256(signBytes)/sha256(message) is what goes into the raw secp256k1 verify algorithm.

webmaster128 commented 3 years ago

Here are the test vectors for the plain contract-vm interface: https://gist.github.com/webmaster128/919f5b505b2f89844f28b90f0c0cf858

secp256k1_verify(message_hash, signature, pubkey)

with

joe-bowman commented 3 years ago

As discussed with @ethanfrey, adding batch verify for ed25519 (supported by ed25519-zebra rust crate) would be super useful for the Cosmos IBC Wasm light-client support.

ethanfrey commented 3 years ago

Let's tackle that with ticket #755 First the single verification, then the batch verification (claim up to 20x speedup).

webmaster128 commented 3 years ago

Thank you @joe-bowman. Batch verification of ed25519 signatures has its own ticket now, listed under serious considerations above: #781

webmaster128 commented 3 years ago

This is done. We implemented seck256k1 and Ed25519. If we want to add more algorithms in the future, let's open specific tickets for those. Great jobs and thanks everyone ✌️