aboutsummaryrefslogtreecommitdiff
path: root/curve/ed25519.go
diff options
context:
space:
mode:
authorÖzgür Kesim <oec@codeblau.de>2024-03-21 19:02:20 +0100
committerÖzgür Kesim <oec@codeblau.de>2024-03-21 19:02:20 +0100
commit989d09c8511eb10f2af06977d210deff39b6ff9e (patch)
treed360f2e3aa06d0e6dc2eaaac62274ca602d8821c /curve/ed25519.go
parent458f9b7172148a272b23d61747f0758bf21dbf1f (diff)
veto, curve: Added an abstraction layer for elliptic curves
This will allow to easily swap various curves and implementations, for benchmarking, f.e.
Diffstat (limited to 'curve/ed25519.go')
-rw-r--r--curve/ed25519.go132
1 files changed, 132 insertions, 0 deletions
diff --git a/curve/ed25519.go b/curve/ed25519.go
new file mode 100644
index 0000000..e8e380d
--- /dev/null
+++ b/curve/ed25519.go
@@ -0,0 +1,132 @@
+// Implementation of a MultiplicateCurve, using filippo.io/edwards25519.
+// Note that the implementation in edwards25519 uses addition for the group operation,
+// while we are exposing a multiplicative version of it.
+package curve
+
+import (
+ "crypto/rand"
+ "encoding/base64"
+ "io"
+
+ ed "filippo.io/edwards25519"
+)
+
+var Curve25519 = &c25519{}
+
+type Curve25519Scalar = scalar
+type Curve25519Point = point
+
+type c25519 struct{}
+type scalar ed.Scalar
+type point ed.Point
+
+var _ MPoint[*scalar, *scalar, *point] = (*point)(nil)
+var _ MultiplicativeCurve[*scalar, *scalar, *point, *point] = Curve25519
+var _ SomeScalar[*scalar] = (*scalar)(nil)
+
+var b64 = base64.StdEncoding.WithPadding(base64.NoPadding)
+
+func (s *scalar) Bytes() []byte {
+ return ((*ed.Scalar)(s)).Bytes()
+}
+
+func (s *scalar) Equal(t *scalar) bool {
+ return ((*ed.Scalar)(s)).Equal((*ed.Scalar)(t)) == 1
+}
+
+func (s *scalar) String() string {
+ return b64.EncodeToString(s.Bytes())
+}
+
+func (s *scalar) Add(t *scalar) *scalar {
+ return (*scalar)(new(ed.Scalar).Add((*ed.Scalar)(s), (*ed.Scalar)(t)))
+}
+
+func (s *scalar) Sub(t *scalar) *scalar {
+ return (*scalar)(new(ed.Scalar).Subtract((*ed.Scalar)(s), (*ed.Scalar)(t)))
+}
+
+func (s *scalar) Mult(t *scalar) *scalar {
+ return (*scalar)(new(ed.Scalar).Multiply((*ed.Scalar)(s), (*ed.Scalar)(t)))
+}
+
+func (c *c25519) ScalarFromReader(random io.Reader) (*scalar, error) {
+ var buf [64]byte
+ if random == nil {
+ random = rand.Reader
+ }
+ random.Read(buf[:])
+ return c.ScalarFromBytes(buf[:])
+}
+
+func (c *c25519) RandomScalar() *scalar {
+ for i := 0; i < 3; i++ {
+ if s, e := c.ScalarFromReader(nil); e == nil {
+ return s
+ }
+ }
+ panic("couldn't generate scalar")
+}
+
+func (c *c25519) ScalarFromBytes(b []byte) (*scalar, error) {
+ s, e := new(ed.Scalar).SetUniformBytes(b)
+ return (*scalar)(s), e
+}
+
+func (c *c25519) Exp(s *scalar) *point {
+ p := new(ed.Point).ScalarBaseMult((*ed.Scalar)(s))
+ return (*point)(p)
+}
+
+func (c *c25519) Identity() *point {
+ return (*point)(ed.NewIdentityPoint())
+}
+
+func (c *c25519) Generator() *point {
+ return (*point)(ed.NewGeneratorPoint())
+}
+
+func (c *c25519) Product(pts []*point) (product *point) {
+ product = c.Identity()
+ for _, p := range pts {
+ product = product.Mult(p)
+ }
+ return product
+}
+
+// Return P^n , for n Sc, and P Pt
+func (p *point) Exp(s *scalar) *point {
+ r := new(ed.Point).ScalarMult((*ed.Scalar)(s), (*ed.Point)(p))
+ return (*point)(r)
+}
+
+func (p *point) Bytes() []byte {
+ return ((*ed.Point)(p)).Bytes()
+}
+
+// Return p (*) q in group
+func (p *point) Mult(q *point) *point {
+ r := new(ed.Point).Add((*ed.Point)(p), (*ed.Point)(q))
+ return (*point)(r)
+}
+
+// Return p (/) q in group
+func (p *point) Div(q *point) *point {
+ r := new(ed.Point).Subtract((*ed.Point)(p), (*ed.Point)(q))
+ return (*point)(r)
+}
+
+// Return p^(-1)
+func (p *point) Inv() *point {
+ n := new(ed.Point).Negate((*ed.Point)(p))
+ return (*point)(n)
+}
+
+func (p *point) Equal(q *point) bool {
+ return ((*ed.Point)(p)).Equal((*ed.Point)(q)) == 1
+
+}
+
+func (p *point) String() string {
+ return b64.EncodeToString(p.Bytes())
+}