OSDN Git Service

feat: add processIssuing (#152)
[bytom/vapor.git] / vendor / github.com / bytom / crypto / ed25519 / ecmath / point.go
1 package ecmath
2
3 import (
4         "crypto/subtle"
5
6         "github.com/bytom/crypto/ed25519/internal/edwards25519"
7 )
8
9 // Point is a point on the ed25519 curve.
10 type Point edwards25519.ExtendedGroupElement
11
12 // ZeroPoint is the zero point on the ed25519 curve (not the zero value of Point).
13 var ZeroPoint Point
14
15 // Add adds the points in x and y, storing the result in z and
16 // returning that. Any or all of x, y, and z may be the same pointers.
17 func (z *Point) Add(x, y *Point) *Point {
18         var y2 edwards25519.CachedGroupElement
19         (*edwards25519.ExtendedGroupElement)(y).ToCached(&y2)
20
21         var z2 edwards25519.CompletedGroupElement
22         edwards25519.GeAdd(&z2, (*edwards25519.ExtendedGroupElement)(x), &y2)
23
24         z2.ToExtended((*edwards25519.ExtendedGroupElement)(z))
25         return z
26 }
27
28 // Sub subtracts y from x, storing the result in z and
29 // returning that. Any or all of x, y, and z may be the same pointers.
30 func (z *Point) Sub(x, y *Point) *Point {
31         var y2 edwards25519.CachedGroupElement
32         (*edwards25519.ExtendedGroupElement)(y).ToCached(&y2)
33
34         var z2 edwards25519.CompletedGroupElement
35         edwards25519.GeSub(&z2, (*edwards25519.ExtendedGroupElement)(x), &y2)
36
37         z2.ToExtended((*edwards25519.ExtendedGroupElement)(z))
38         return z
39 }
40
41 // ScMul multiplies the EC point x by the scalar y, placing the result
42 // in z and returning that. X and z may be the same pointer.
43 func (z *Point) ScMul(x *Point, y *Scalar) *Point {
44         return z.ScMulAdd(x, y, &Zero)
45 }
46
47 // ScMulBase multiplies the ed25519 base point by x and places the
48 // result in z, returning that.
49 func (z *Point) ScMulBase(x *Scalar) *Point {
50         edwards25519.GeScalarMultBase((*edwards25519.ExtendedGroupElement)(z), (*[32]byte)(x))
51         return z
52 }
53
54 // ScMulAdd computes xa+yB, where B is the ed25519 base point, and
55 // places the result in z, returning that.
56 func (z *Point) ScMulAdd(a *Point, x, y *Scalar) *Point {
57         // TODO: replace with constant-time implementation to avoid
58         // sidechannel attacks
59
60         var p edwards25519.ProjectiveGroupElement
61         edwards25519.GeDoubleScalarMultVartime(&p, (*[32]byte)(x), (*edwards25519.ExtendedGroupElement)(a), (*[32]byte)(y))
62
63         var buf [32]byte
64         p.ToBytes(&buf)
65         // TODO(bobg): double-check that it's OK to ignore the return value
66         // from ExtendedGroupElement.FromBytes here. (It's a bool indicating
67         // that its input represented a legal value.)
68         (*edwards25519.ExtendedGroupElement)(z).FromBytes(&buf)
69         return z
70 }
71
72 func (z *Point) Encode() [32]byte {
73         var e [32]byte
74         (*edwards25519.ExtendedGroupElement)(z).ToBytes(&e)
75         return e
76 }
77
78 func (z *Point) Decode(e [32]byte) (*Point, bool) {
79         ok := (*edwards25519.ExtendedGroupElement)(z).FromBytes(&e)
80         return z, ok
81 }
82
83 func (z *Point) ConstTimeEqual(x *Point) bool {
84         xe := x.Encode()
85         ze := z.Encode()
86         return subtle.ConstantTimeCompare(xe[:], ze[:]) == 1
87 }
88
89 func init() {
90         (*edwards25519.ExtendedGroupElement)(&ZeroPoint).Zero()
91 }