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

Adds point compression, point serialization and binary encoder for each curve #17

Merged
merged 14 commits into from
Nov 10, 2020

Conversation

gbotrel
Copy link
Collaborator

@gbotrel gbotrel commented Nov 10, 2020

G1Affine and G2Affine now exposes 3 methods:

  1. Bytes() [SizeOfG1Compressed]byte: returns an array of bytes with compressed binary representation of the point. For curves bls381, bls377 and bw761, as we have more than 3bits available on the most significant word of the coordinates, we follow BLS381 style encoding as specified in ZCash and draft IETF spec. That is:
  • The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form.
  • The second-most significant bit indicates that the point is at infinity. If this bit is set, the remaining bits of the group element's encoding should be set to zero.
  • The third-most significant bit is set if (and only if) this point is in compressed form and it is not the point at infinity and its y-coordinate is the lexicographically largest of the two associated with the encoded x-coordinate.

For bn256, as we only have 2 unused bits, we ignore the "uncompressed infinity" case:

// 00 -> uncompressed
// 10 -> compressed, use smallest lexicographically square root of Y^2
// 11 -> compressed, use largest lexicographically square root of Y^2
// 01 -> compressed infinity point
// the "uncompressed infinity point" will just have 00 (uncompressed) followed by zeroes (infinity = 0,0 in affine coordinates)
  1. RawBytes() [SizeOfG1Uncompressed]byte: returns an array of bytes with uncompressed binary representation of the point

  2. SetBytes([]byte): sets point coordinates from bytes (can be either compressed or uncompressed form) .


Similarly to field elements generated by goff, GT exposes Bytes() and SetBytes() .


Additionally, each curve now exposes a Encoder and Decoder object, with similar APIs to cbor.Encoder, gob.Encoder, json.Encoder, etc, in other go projects. This allows library users to write, for example:

// w io.Writer, r io.Reader
var point bn256.G1Affine
enc := curve.NewEncoder(w)
err := enc.Encode(&point)
// ...
dec := curve.NewDecoder(r)
err := dec.Decode(&point)

The encoder only supports curve objects (fr.Element, fp.Element, G1Affine, G2Affine,[]G1Affine, []G2Affine) and uint64 for convenience.


Notes:

  • Deserialization is not performing any checks (at the moment): IsOnCurve or IsInCorrectSubgroup
  • Memory allocations and performance will evolve. The most important issue is that e2.Sqrt() is slow and do few memory allocations, making deserializing from G2Affine compressed points sub-optimal.
  • closes Marshal/Unmarshal for G1 and G2 points #16

@CLAassistant
Copy link

CLAassistant commented Nov 10, 2020

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants