Skip to content

CosmosArbitrary optimisations #7

@kromsten

Description

@kromsten

As an continuation of great optimisation initiatives brought up in #5 it will be great to have ability of not relying on bech32 and ripemd crates when it's not necessary

Having the whole data being ready for hashing is already possibly using the Secp256k1 credential. So far it's only been available under curves feature tag which also includes a very bulkySecp256r1. With the upcoming release of 0.26.0 the bulkiness of the latter (+passkeys) is getting fixed in cosmwasm (v2.0) environment. It also becomes possible to include any of the available credentials separately including the former mention using secp256k1

As for CosmosArbitrary since we are required to use the envelopes defined in 036 due to security reasons (and to differentiate from raw Secp256k1) the only possible optimisation vector lies is when we go from public keys to bech32 encoded addresses

The issue introduces a core proposition explaining the mechanism and nature of changes and then cover the possible options of how to approach it all in practice.

Core Proposition

The primary suggestion is adding an optional address field to the credential type. It can be used directly if specified and in case if it isnät we can fall back to the existing logic of manually deriving it ourselves.

struct CosmosArbitrary {
    pub pubkey:    Binary,
    pub signature: Binary,
    pub message:   Binary,
    pub address:   Option<String>, // or even Option<Addr>. for wasmic VMs
    pub hrp:       Option<String>
}

Additionally we could set the value ourselves at any point as in caching and avoid the need for re-computing it every single time afterwards. It's valid for utility methods like this one but also every single time we reconstruct the credential. Most often we use the Credentialnfo from storage or a data account and merge it with new signed payload . In case if the address is set the hrp wlll be ignored (or overriden)

Security

As part of the envelope addresses are already used in the process of generating the signatures so in any scenario we can guarantee that the owner of an associated private key have authorised the specific address being passed

What we can't guarantee without manual derivation is that the address is indeed coming from the given pubkey. In theory the owner could use any possible string value. This is not a security violation per se but can be an issue for those expecting cosmos_address() to be linked with the keys

The problem is slightly diminished by the fact that most commonly the signatures are produces by browser extension wallets that don't allow customisation of the address in the envelope and do enforce the match with the public key

Required Changes

  • Extra field in CredentialInfo as well, which is a light but breaking change
  • Might be useful in AuthPayload. We can't get new addresses from one common public key while using the same prefix but can pass the whole address for alternative networks (using same coin type)
  • to make the address settable when the address is derived it might take the changes immutability of methods like verify and cosmos_address()
  • new definitions, features tags and tests

Effects

  • Significant improvements in performance and reduced (gas) costs
  • The changes caused by the implementation could be beneficial in other similar cases and for handling the addresses in general
  • No improvements in decreasing the bundle size as the dependencies are still included (except for case 2 below)

Implementation Variants

When it comes to the new address property a single credential can look and behave like one of the following:

  1. The credential has no address (current)

    • the most of computation (every single time we need an address)
    • guarantees the link between the keys and the address
  2. The credential has a non-optional address

    • no computation at all
    • no link guarantees at all
    • removing extra crates and decreasing the bundle
  3. The credential has an optional address (no validation if set)

    • same compute as 1 if set and 2 otherwise
    • no link guarantees
  4. The credential has an optional address (always validating once)

    • 1 the first time and 2 on all subsequents
    • guarantees the link

(5.) The 2 variant with a promise of a validation is Identical to 4 in almost all regards. The only difference is that the value is always unwrapped and is required to be set on the client side

When it comes to what is available to be used we can support any number of the above:
I. Modifying the same one credential using conditional compilation and feature tags
II. Defining multiple separate credentials with ability to mix them
III. Mix of the two: defining multiple and making customisable

Other considerations:

  • there should always be an option to enforce the pubkey --> address link, so ether 1 or 4 should always be available as an option
  • conditional compilation is possible, but number of tags can quickly become overwhelming for both usability and maintenance
    • adding a new credential is less clunky than modifying in place with following anticipation of different variants
    • there should only be a minimum of what's actually useful with reasoning / examples

Leaving it open for feedback gathering for a few days before starting to work on it. In the process came up with another useful feature and important feature that is relevant to the choice. Creating an issue about it and giving the opinion about the options in separate comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions