gtank / ristretto255

Implements ristretto255, a fast prime-order group.
https://ristretto.group
BSD 3-Clause "New" or "Revised" License
98 stars 22 forks source link

API differences with filippo.io/edwards25519 #36

Closed FiloSottile closed 3 years ago

FiloSottile commented 3 years ago

filippo.io/edwards25519 was a later attempt at building an API, and differences emerged in two parts.

First, instead of having identity and generator setters (called Base and Zero here, which I don't love), we have two separate New methods. I am not positive the new pattern is better, but I like the names better, and it avoids the "what does NewElement return?" question.

func NewElement() *Element
func (e *Element) Base() *Element
func (e *Element) Zero() *Element
// vs
func NewIdentityPoint() *Point
func NewGeneratorPoint() *Point

Then, the serialization and deserialization functions. This package has a Decode that can't be chained, a FromUniformBytes that panics, and an append-like Encode. The names map to the spec so they should probably stay (although I like the "set" verb better than the "from" preposition), but everything else is suboptimal. Decode should chain, Encode should be outline an allocation, and FromUniformBytes should return an error (matching Decode).

func (e *Element) Decode(in []byte) error
func (e *Element) Encode(b []byte) []byte
func (e *Element) FromUniformBytes(b []byte) *Element
// vs
func (v *Point) Bytes() []byte
func (v *Point) SetBytes(x []byte) (*Point, error)

The version is still v0, do we feel like breaking the API? Do we want to make the jump to v2?

FiloSottile commented 3 years ago

Similarly, Scalar has an extra func (s *Scalar) Zero() *Scalar setter, and the same serialization differences.

func (s *Scalar) Encode(b []byte) []byte
func (s *Scalar) Decode(x []byte) error
func (s *Scalar) FromUniformBytes(x []byte) *Scalar
// vs
func (s *Scalar) Bytes() []byte
func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error)
func (s *Scalar) SetUniformBytes(x []byte) *Scalar
gtank commented 3 years ago

I do slightly prefer FromUniformBytes here, since that's a derivation process (wide reduction) and not an assignment process. Was there a reason we changed it in fio/edwards25519? Consistency with SetCanonicalBytes (which I do think is better)?

FiloSottile commented 3 years ago

Consistency with SetCanonicalBytes, as well as keeping verbs in front for things that change the receiver: Add, Negate, Set... From?

gtank commented 3 years ago

Ah, good point about the verb idiom. ReduceUniformBytes? I don't feel strongly about it, but the Set- prefix suggests to me that the input isn't significantly transformed. Won't hold it up over this if you disagree or don't think it matters.

FiloSottile commented 3 years ago

I do like ReduceUniformBytes, but I am not sure it's worth deprecating SetUniformBytes in fio/edwards25519 for... and I like that all the various ways to set a value end up next to each other in the docs.