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  }