FiloSottile / edwards25519

filippo.io/edwards25519 — A safer, faster, and more powerful low-level edwards25519 Go implementation.
https://filippo.io/edwards25519
BSD 3-Clause "New" or "Revised" License
139 stars 30 forks source link

Add ability to chain call ECC operations to greatly improve readability of code. #29

Open WernerVasquez opened 2 years ago

WernerVasquez commented 2 years ago

I use your project in one of mine. But, like many other ed25519 implementation (and similar) in Go, the design produces needlessly difficult to read code (in the context of programming mathematical equations/expressions). When writing a single line from a basic equation such as a G + b B, there is so much going on, it is dangerously difficult to read and compare to the mathematical equation it came from. (And that is not even considering the error handling boilerplate which compounds the issue).

Naturally, I fix this when I import your package. See https://github.com/WernerVasquez/gomonero/blob/master/crypto/crypto.go

However, it would be wonderful if this were somehow natively an option with your work.

My basic design is to add an error field to the struct for both Point and Scalar. This removes the need to return an error and allows for a single return value. With a single return value, one can now chain call. Every operation first checks if the arguments or receiver have a non-nil error. If so, they set the error in they return immediately with the returning variable's error set accordingly.

The error field is public so that any code can at any time check to see if an error has occurred. It also allows for multiple ECC operations to be called in one line and then check for a resulting error to improve readability. This allows for single lines of code to match the single equations in the papers they come from.

Also, I do not modify the receivers or arguments. The reason for this is if an equation in a paper were P = a G + b B, a mathematician would not expect any variable on the right hand side to change. They would merely expect the left hand side to be assigned the correct value.

All of this allows for very readable, super easy to debug, mathematical statements.

For example:

    //Ke = ephemeral key (transaction public key)
    Ke = r.MultG()

    //Kss = Shared Secret = random scalar * public view key * 8
    Kss := r.MultPoint(a.Kv).MultByCofactor()

    //Ko = one time address = Hs(Kss) * G + Ks
    Ko = Kss.HashToScalar().MultG().Add(a.Ks)

https://github.com/WernerVasquez/gomonero/blob/c71ba7c8e5e7e2750c3a0e621aefc69d20ae9e90/address/standard_address.go#L64

I imagine this may need to be a separate repo which imports this one (as I have done). And while I can, and have, done it, I think it is useful to the broader community and would be much better coming from the maintainer of this library.

In summary, this allows programmers to write lines of code that match equations from papers in a very easy-to-see way. It allows the programmers to do a better job translating the math and it allows mathematicians to more easily read the code as math to look for issues.

While my project (linked above) is very much a work in progress, I do believe it already speaks for itself.