Skip to content

Two different versions of hash_g2 being used #26

@iancoleman

Description

@iancoleman

There are two different hash_g2 being used. This issue is to track whether we should move to just a single one.

The first one is used for encrypt and decrypt, which is hash_g2 in lib.rs from when we forked threshold_crypto. The team at poanetwork/threshold_crypto wrote this version of hash_g2.

As the code comment says, this Returns a hash of the given message in G2.

It's a kind of preprocessing to convert any arbitrary bytes (eg a message to sign or encrypt) into a G2, which can then be used for signing/verifying or encrypting/decrypting.

The second one is used for sign and verify, which is within blst (contained within the call to blst_sk.sign and blst_sig.verify).

The simplest way to see this second version of hash_g2 is in blsbs which has a util function wrapping it all up pretty neatly: hash_g2_with_dst. Note this requires use of unsafe.

These two different ways of converting arbitrary bytes to G2 are incompatible (same input bytes produces a different output G2). Maybe we should consolidate.

The blst version follows an Internet Research Task Force standard, see blst/bindings/vectors/hash_to_curve and draft-irtf-cfrg-hash-to-curve. The threshold_crypto/blsttc version does not.

There's also an irtf/blst compatible implementation of hash_g2 in the javascript library noble-bls12-381, see hashToCurve. Sometimes the javascript can be easier to understand than other lower level languages and is a good alternative to know about.

We could potentially keep encrypt/decrypt using the non-standard hash_g2 since no other library implements bls encrypt/decrypt, all other libs only implement sign/verify (which we are compatible with because we use blst for those operations). This means we're free to do what we like with encrypt/decrypt, nobody is following us and there is nobody else to follow.

But it seems to make sense to me that we follow standards as best we can and should avoid doubling up with two incompatible implementations.

So I propose we remove the non-standard hash_g2 and only use the irtf standard hash_g2_with_dst

Two downsides to this change are

  1. the blst version requires us to use unsafe in blsttc. We may be able to avoid this by adding it as a helper method to blst itself, like uniq. This keeps all unsafe in blst.

  2. this is a breaking change so any old ciphertexts won't decrypt with the new hash_g2. Should we rename the non-standard hash_g2 to hash_g2_nonstandard or _legacy or something like that? I personally feel we should remove the non-standard hash_g2 since we have no other users of blsttc (to my knowledge, see stats chart at the bottom of crates.io/blsttc and dependents which are all maidsafe).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions