RGB-WG / rgb-core

RGB Core Library: consensus validation for private & scalable client-validated smart contracts on Bitcoin & Lightning
https://spec.rgb.tech
Apache License 2.0
207 stars 52 forks source link

Remove human readable words from contract ID #170

Closed fedsten closed 1 year ago

fedsten commented 1 year ago

In v0.10 three human readable words have been introduced as a checksum in the contract ID. While this may help to detect fake assets, I believe it presents also a few drawbacks:

  1. Human readable words may carry unwanted and embarrassing meaning that the contract issuer may prefer to avoid. E.g. imagine a speculative asset getting as the checksum in the contract ID the words Price Always Dump, or more generally terminology that doesn't fit well with the image of the company issuing the asset. A workaround to this problem can be to brute-force the asset ID until a likeable checksum is produced, but this affects negatively the user experience of issuing an asset, and it may be hard to do on non powerful devices.
  2. On mobile devices with small screens, the contract ID often needs to be truncated while displayed in the UI. With limited space, the user may end up seeing only the three words and a few bech32 characters, which can put the user more at risk of fraud as three words are easier to brute-force by an attacker than the 15-20 bech32 extra characters that could be displayed in the same space.

Moreover, I believe that protecting users from fake asset ID can be better done at the wallet level by providing extra features such as generating an image based on the asset id, similarly to GitHub default avatars. This solution has already been implemented in Iris Wallet and works quite well.

For these reasons I believe that simple bech32 contract IDs are preferable, and I propose to remove the human readable words from the ID as it was in v0.9. Let me know your thoughts on this.

dr-orlovsky commented 1 year ago

I think pt.1 is quite reasonable.

BTW we do not use bech32 (which is space-inefficient w/o real benefits) but Base58 (prefixed by those words which are the checksum).

So instead of words, should we put a checksum as a HEX-encoded 8 chars in front?

Basically, w/o checksum users must compare at least 1/4 of the string (11 chars) to prevent actual brute force attacks (i.e. 64 bits of security, requiring in average 9 Exa-OPS to brute force) - which nobody would do in practice. Checking just checksum will be equivalent to checking 1/8 of the string (i.e. hacker will need the same computing resource to "mine" checksum as to mine 1/8-similar string, i.e. 32 bits of security or 4 Tera-OPS to brute force). Checking checksum + two initial chars (6+2 chars) gives us 32*2=64 bits of security - i.e. the same safety as checking 1/4 string and this is doable in practice. Thus, the checksum is really important and I think in the UI both the checksum and the two chars after it must be highlighted.

Summary of options:

No of chars to check Bits of security Bruteforce computational requirement
no checksum 11 chars 64 bit 9 Exa-hashes
just checksum 6 chars 32 bit 4 Tera-hashes
32-bit checksum + 2 chars 8 chars 64 bit 9 Exa-hashes
24-bit checksum + 8-bit checksum 6 chars 192 bit uncomputable
2 different 16-bit checksums 8 chars 256 bit uncomputable
cryptoquick commented 1 year ago

Yes, we should use a 4-byte checksum in square brackets, like [f8dc5903], like how it's typically used to make a fingerprint for descriptors.

ripemd160(sha256(input))[0:4]

I realize this is just for a contract id and not a key, but it's sometimes better to do it like an existing way than to do it a new way.

cryptoquick commented 1 year ago

I just learned, checksums are different than fingerprints https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums

An 8 character checksum is better, I can see what you're saying now.

fedsten commented 1 year ago

HEX-encoded 8 chars in front sounds good to me.

dr-orlovsky commented 1 year ago

Two PRs:

I did some extensive tests (covering up to 24 bit checksum, since 32 bit my desktop can't crack) which had shown that overall any n bits can be cracked with O(2^n) hash operations. My best result I was able to achieve by combining two different hashes is O(2^(n+2)) operations (see https://github.com/UBIDECO/rust-baid58/pull/4).

Thus, two main conclusions:

Thus, with those PRs the new contract IDs for RGB will look like rgb:2dzcCoX9c65gi1GoJ1LFzb5FcQ9pAc8o3Pj8TpcH2mkAdMLCpP

fedsten commented 1 year ago

ACK

cryptoquick commented 1 year ago

ACK the format rgb:2dzcCoX9c65gi1GoJ1LFzb5FcQ9pAc8o3Pj8TpcH2mkAdMLCpP

dr-orlovsky commented 1 year ago

Closed with #171