TEPs icon indicating copy to clipboard operation
TEPs copied to clipboard

TEP: Data signatures

Open oleganza opened this issue 3 years ago • 15 comments

This proposal is an evolution of @ex3ndr's safe-signing proposal.

Highlights:

  • "Invalid cell representation" trick is not necessary because we are signing a differently-sized message.
  • Separate schemas for plaintext messages and binary messages. User can explicitly check all the data they are signing.
  • Mandatory binding to a timestamp.
  • Support for binding to smart contract address and domain name.
  • Possibility for future extensions with detailed schemas retaining backwards compatibility with the wallets.

Rendered specification:

oleganza avatar Dec 14 '22 08:12 oleganza

Received a number of suggestions from @EmelyanenkoK:

  1. Plain text signatures are safer to implement without any hidden binary payload. "What you see is what you get". I agree, will amend the spec to reflect that.
  2. Instead of incremental schema versions we could use crc32 of the TL-B description of the payload.
  3. We could combine both domain and address together in one schema. In case you have both the service and the target contract to use the data with.

oleganza avatar Dec 14 '22 11:12 oleganza

Another suggestion by @ex3ndr is to compose this extension with TEP/PR93.

I'm a bit hesitant to do that because TEP/PR93 by itself is not a safe usable scheme and if we use it as-is, then timestamp and schema prefix would have to eat the space out of the payload cell, making composition with its TL-B scheme harder.

oleganza avatar Dec 14 '22 11:12 oleganza

I have updated the spec based on feedback from @EmelyanenkoK & @mr-tron.

  • Plaintext messages use chunked text encoding;
  • Schemes 1+2 are merged: one may use both the contract address and the domain name;
  • Explicit specification for the domain name encoding;
  • Domain name is also chunk-encoded for consistency and to avoid unnecessary length limits.

oleganza avatar Dec 14 '22 14:12 oleganza

Based on feedback by @tolya-yanot replaced chunked encoding with SHA256. This comes at no tradeoff for domain names: they are transmitted or known explicitly anyway.

As for the plaintext string: it is unlikely that smart contracts would verify complex text strings, and yet it is possible to hash them or introduce a dedicated TL-B scheme for that purpose in the future. For short "command" strings the contracts could verify sha256 images directly against the built-in constants.

oleganza avatar Dec 14 '22 15:12 oleganza

One more update: @mr-tron pointed out two things:

  1. Cells already provide hashing by themselves, so it would be prudent to use snake format (as in TEP-64) for text message and domain.
  2. It is not necessary to perform the "invalid cell representation" hack if we avoid extra hashing before computing/verifying the signature. We could simply send 352-bit message into Ed25519 as-is and that would provide enough separation from any wallet transaction (that use 256-bit cell hash as a message in the Ed25519 protocol).

oleganza avatar Dec 14 '22 20:12 oleganza

A couple of minor tweaks:

  1. Domain name is embedded into cell to allow replacing its explicit content with its hash: might be handy in some situations.
  2. There was an idea to embed TL-B description of the payload and automatically display it to the user, but this requires more time to design, so we are adding ext:(Maybe ^Cell) for such future extension.

oleganza avatar Dec 15 '22 09:12 oleganza

LGTM

EmelyanenkoK avatar Dec 16 '22 13:12 EmelyanenkoK

LGTM, thanks all for the hard work to finalize this as part of TC2

talkol avatar Dec 20 '22 13:12 talkol

Do we need to explicitly bind these signatures to the network ID (-239 for mainnet, -3 for testnet) to avoid ambiguity between networks?

Also: in TON Connect there is custom "address proof" scheme that we may want to replace with this scheme for consistency.

oleganza avatar Dec 22 '22 16:12 oleganza

Your wallet is already have subwallet id inside address which should be first 4 bytes of zero state hash. https://github.com/ton-blockchain/ton/blob/4b940f8bad9c2d3bf44f196f6995963c7cee9cc3/tonlib/tonlib/TonlibClient.cpp#L2420 I don't see any sense to add another network id which everyone will ignore.

mr-tron avatar Dec 22 '22 19:12 mr-tron

I am reserving the prefix of plaintext text:Slice = PayloadCell == 96890e83 for ledger signatures. It differs in that it just signs a hash of a string instead of a cell, also doesn't have an expiration date, etc. It is challenging to implement time verification anyway.

ex3ndr avatar Dec 22 '22 23:12 ex3ndr

Your wallet is already have subwallet id inside address which should be first 4 bytes of zero state hash. https://github.com/ton-blockchain/ton/blob/4b940f8bad9c2d3bf44f196f6995963c7cee9cc3/tonlib/tonlib/TonlibClient.cpp#L2420 I don't see any sense to add another network id which everyone will ignore.

Do you mean using the same 4 bytes of the zero state hash as an identifier? Note that the current proposal does not bind signatures to any wallet address (which is bound to the network id as you described).

oleganza avatar Jan 12 '23 14:01 oleganza

I am reserving the prefix of plaintext text:Slice = PayloadCell == 96890e83 for ledger signatures. It differs in that it just signs a hash of a string instead of a cell, also doesn't have an expiration date, etc. It is challenging to implement time verification anyway.

I don't understand the use-case. The snake format effectively compresses any string to a hash (for the tail).

Anyway, I'd suggest to name this something like "hashsig hash:Slice = PayloadCell" to make the difference clear. But then it's only useful if you don't plan to display the contents of the text to user, which would be weird and insecure.

Note that the timestamp exists outside the payloads. If you want to make an eternal signature you may use all-zero timestamp and if it's important, the clockless HSM may check that the time is all-zero so that you know it's not going to have an expiration time. However, even such HSM may format the time and display it for sanity check to the user.

oleganza avatar Jan 12 '23 14:01 oleganza

Re: binding to the network. These signatures are going to be used also offchain, so we can delegate to the dapps to embed additional binding in their custom payloads and not include the network ID in this standard. E.g. if a signed message operates a smart contract on a certain network, then it may be enough to bind through a contract address (that should be different on a testnet).

oleganza avatar Jan 13 '23 13:01 oleganza

I think should add standard prefix to any signed payload which contains ton connect magic prefix (like version maybe), ton connect domain and signing timestamp for avoid reusing signature in other projects. Something like current proof inside ton connect.

mr-tron avatar Aug 02 '24 18:08 mr-tron