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

TEP: Data signatures #104

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open

Conversation

oleganza
Copy link

@oleganza oleganza commented Dec 14, 2022

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 oleganza changed the title Data signatures proposal TEP: Data signatures Dec 14, 2022
@oleganza oleganza mentioned this pull request Dec 14, 2022
@oleganza
Copy link
Author

oleganza commented Dec 14, 2022

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
Copy link
Author

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
Copy link
Author

oleganza commented Dec 14, 2022

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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.

@EmelyanenkoK
Copy link
Member

LGTM

@talkol
Copy link

talkol commented Dec 20, 2022

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

@oleganza
Copy link
Author

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.

@mr-tron
Copy link

mr-tron commented Dec 22, 2022

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.

@ex3ndr
Copy link

ex3ndr commented Dec 22, 2022

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.

@oleganza
Copy link
Author

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
Copy link
Author

oleganza commented Jan 12, 2023

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
Copy link
Author

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).

@mr-tron
Copy link

mr-tron commented Aug 2, 2024

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.

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

Successfully merging this pull request may close these issues.

5 participants