Skip to content

crypto/ed25519: Caching public key decompression #1784

@ValarDragon

Description

@ValarDragon

For a new node syncing to the chain, they have to process many signatures from the same validators. The same applies to full nodes verifying signatures. Under Ed25519, these public keys have to undergo a point decompression. This point decompression can be trivially cached (see tendermint/ed25519#8). Benchmarking on that PR, caching this point decompression saves 10% of computation time per verify, for all verifications after the first one. (The first verify takes the same exact amount of time)

If we ever implement Ed25519 batch verification, this savings becomes > 20% of the batch verify time, since batch verification doesn't do anything for the point decompression employed.

It has been decided to hold off on integrating this into tendermint, until sync times become a problem for people. For reference, Ed25519 signature verification takes 65% of the time of a CheckTx + DeliverTx combination, implying that it is significant even when accounting for the account mapper / state reads.

The way this would likely be implemented is by changing the internal type of Ed25519 to be a struct with the relevant cached values. The alternative is adding a cache method to every public key type -- I'm not opposed to this as it avoids the extra temporary memory cost of most keys, and I think more key types will benefit from this caching paradigm in a way that shouldn't be ran on keys that are used only once, unlike ed25519. The downside of the cache method is that its confusing / API we have to maintain. (Not that confusing imo though). The downsides of switching Ed25519 to a struct is that every Ed25519 public key in memory is going to take an extra 64 bytes. (It will still marshal the same way, and therefore be the exact same in state). Arguably that isn't an issue, since this provides more significant computational savings if the key is ever reused, and if it isn't reused it will be garbage collected almost immediately. However it must be cautioned then whenever public keys are encoded for being put into state, only the marshalled version is encoded. (I believe this is already the case, so there isn't any concern)

In general, this is a relatively easy optimization we can take advantage of, once we want more speed out of our signature verifications.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions