github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/crypto/ed25519/ecmath/point.go (about) 1 package ecmath 2 3 import ( 4 "crypto/subtle" 5 6 "github.com/bytom/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 }