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

Update hash_to_g2 in BLS #1398

Closed
wants to merge 15 commits into from
Closed

Conversation

kirk-baird
Copy link
Contributor

The purpose of this PR is to update the hash_to_g2 function to match those specified in the BLS Standards. Riad has kindly already prepared the ciphersuite BLS12381G2-SHA256-SSWU-RO. It can be found in section 8.7 of the hash-to-curve standard. I've written a few extra notes in the hopes of assisting anyone implementing it.

Things worth noting:

  • The links are currently pointing at the draft of the standard which is changing and hence they will need to be updated once it is finalised.
  • Pseudo Code for clear_cofactor is currently being written and when it's complete we should point to that instead of the paper currently being pointed too.
  • The standard states that serialisation should be done the same as Zcash which ours is slightly different.

Let me know if you would like me to expand into more detail on any parts of hash_to_curve

Signed-off-by: = <=>
Copy link
Contributor

@hwwhww hwwhww left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the interpretation!

The document is for the latest version (draft-irtf-cfrg-hash-to-curve-04). Perhaps note the IETF version here so that we can keep this doc synced. :)


`modular_squareroot(x)` returns a solution `y` to `y**2 % q == x`, and `None` if none exists. If there are two solutions, the one with higher imaginary component is favored; if both solutions have equal imaginary component, the one with higher real component is favored (note that this is equivalent to saying that the single solution with either imaginary component > p/2 or imaginary component zero and real component > p/2 is favored).
* `hash_to_base` - Converting a message from bytes to a field point. The required constant parameters are: Security `k = 128` bits, Field Degree `m = 2` (i.e. Fp2), Length of HKDF `L = 64`, `H = SHA256`, Domain Separation Tag `DST = BLS12381G2-SHA256-SSWU-RO`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does HKDF-Extract function take parameter salt in bytes? Should we note that which encoding format for the DST value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep the salt for HKDF-Extract is DST. The standard has the type of salt as a string hence I left it as a string here. However my implementation (and I'm sure others will too) takes bytes so I would not be against also displaying it as bytes.

return multiply_in_G2((x_coordinate, y_coordinate), G2_cofactor)
x_coordinate += Fq2([1, 0]) # Add 1 and try again
def hash_to_G2(message_hash: Bytes32) -> Tuple[uint384, uint384]:
hash_to_curve(message_hash)
Copy link
Contributor

@hwwhww hwwhww Sep 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be

Suggested change
hash_to_curve(message_hash)
P = hash_to_curve(message_hash)

Can we just rename hash_to_G2 to hash_to_curve?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I've been spending too much time in rust land I've forgotten my return statements. I think it should be return hash_to_curve(message_hash)

I was very tempted to rename hash_to_g2 however as hash_to_g2 takes Bytes32 whereas hash_to_curve takes Bytes I decided to make the abstraction. What are your thoughts on this?

specs/bls_signature.md Outdated Show resolved Hide resolved
kirk-baird and others added 3 commits September 5, 2019 20:21
Co-Authored-By: Hsiao-Wei Wang <hwwang156@gmail.com>
Signed-off-by: = <=>
@benjaminion
Copy link
Contributor

The current signature of hash_to_G2 is hash_to_G2(message_hash: Bytes32, domain: Bytes8). This draft has hash_to_G2(message_hash: Bytes32). How should we handle the domain parameter?

@kirk-baird
Copy link
Contributor Author

The current signature of hash_to_G2 is hash_to_G2(message_hash: Bytes32, domain: Bytes8). This draft has hash_to_G2(message_hash: Bytes32). How should we handle the domain parameter?

At this point it looks like there will be a wrapper class around the message and domain which will do hash_tree_root and the hash of that wrapper object will be passed to BLS.

You can see here for the discussion about the wrapper object.

specs/bls_signature.md Outdated Show resolved Hide resolved
Signed-off-by: Kirk Baird <baird.k@outlook.com>
Signed-off-by: Kirk Baird <baird.k@outlook.com>
Signed-off-by: Kirk Baird <baird.k@outlook.com>
@kirk-baird kirk-baird changed the title [WIP] Update hash_to_g2 in BLS Update hash_to_g2 in BLS Nov 19, 2019
@kirk-baird
Copy link
Contributor Author

This has been updated to version 5 of the hash to curve draft and is ready for review :)

Let me know if you want more of less details on any sections.

p.s. I haven't made updates based on the bls signatures draft just the hash to curve draft.

specs/bls_signature.md Outdated Show resolved Hide resolved
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* `G2` refers to signatures on G2.
* `SHA256` is the hash function used.
* `SSWU` refers to the Simplified SWU Map from a finite field element to an elliptic curve point.
* `RO` refers to `hash-to-curve` function rather than `encode-to-curve`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could mention that "RO" stands for "random oracle"

@@ -33,6 +31,18 @@ The BLS12-381 curve parameters are defined [here](https://z.cash/blog/new-snark-

We represent points in the groups G1 and G2 following [zkcrypto/pairing](https://github.com/zkcrypto/pairing/tree/master/src/bls12_381). We denote by `q` the field modulus and by `i` the imaginary unit.

## Ciphersuite

We use the following Ciphersuite `BLS_SIG_BLS12381G2-SHA256-SSWU-RO_POP_`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this ciphersuite only be used for the proof of possession (deposit_data.signature)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the ciphersuite be BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_POP_ (notice the extra - after RO-)?

Copy link
Contributor

@CarlBeek CarlBeek Nov 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, the IETF spec has a hash_to_point definition for messages of this ciphersuite which is distinct from hash_pubkey_to_point. My understanding is that if you use the PoP defined by the IETF spec, you should use BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_POP_ or BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_NUL_ if their PoP is not used.

Considering that we do not use the exact PoP defined by the IETF spec, I think we should not claim to use the PoP ciphersuite anywhere.

Suggested change
We use the following Ciphersuite `BLS_SIG_BLS12381G2-SHA256-SSWU-RO_POP_`.
We use the following Ciphersuite `BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_NUL_`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should just use one ciphersuite for both PoP and regular signature validation.
The extra - after RO- is deliberate as that's how the examples were given in the IETF spec.

I agree with Carl, if we don't use the specified PoP we should not use that in our ciphersuite tag. However, I then ask why do we not use that standardized PoP?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extra - after RO- is deliberate as that's how the examples were given in the IETF spec.

Right :) The extra - were missing and added them in.

why do we not use that standardized PoP?

What is the difference between the standardized PoP and the currently specified PoP?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question,
The standardize PoP signs the message:
msg = bytes(public_key)

Where as we sign the message:
msg = signing_root(deposit.data)
Which contains withdrawal_credentials and amount along with the public_key.

Copy link
Contributor

@CarlBeek CarlBeek Nov 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standardize PoP signs the message:
msg = bytes(public_key)

Note that there is a specific domain separation tag just for signing pubkeys. (A third tag not mentioned here yet.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right sorry, I didn't notice the tag was slightly different between regular signatures and PoP.
PoP: BLS_POP_BLS12381G2-SHA256-SSWU-RO-_POP_
Regular Signature: BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_POP_

With the option of changing the last _POP_ to _NUL_ if required.

@kirk-baird
Copy link
Contributor Author

Closed in favour of #1532

@kirk-baird kirk-baird closed this Dec 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants