1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package curve25519 provides an implementation of the X25519 function, which 6 // performs scalar multiplication on the elliptic curve known as Curve25519. 7 // See RFC 7748. 8 // 9 // This package is a wrapper for the X25519 implementation 10 // in the crypto/ecdh package. 11 package curve25519 12 13 import "crypto/ecdh" 14 15 // ScalarMult sets dst to the product scalar * point. 16 // 17 // Deprecated: when provided a low-order point, ScalarMult will set dst to all 18 // zeroes, irrespective of the scalar. Instead, use the X25519 function, which 19 // will return an error. 20 func ScalarMult(dst, scalar, point *[32]byte) { 21 if _, err := x25519(dst, scalar[:], point[:]); err != nil { 22 // The only error condition for x25519 when the inputs are 32 bytes long 23 // is if the output would have been the all-zero value. 24 for i := range dst { 25 dst[i] = 0 26 } 27 } 28 } 29 30 // ScalarBaseMult sets dst to the product scalar * base where base is the 31 // standard generator. 32 // 33 // It is recommended to use the X25519 function with Basepoint instead, as 34 // copying into fixed size arrays can lead to unexpected bugs. 35 func ScalarBaseMult(dst, scalar *[32]byte) { 36 curve := ecdh.X25519() 37 priv, err := curve.NewPrivateKey(scalar[:]) 38 if err != nil { 39 panic("curve25519: internal error: scalarBaseMult was not 32 bytes") 40 } 41 copy(dst[:], priv.PublicKey().Bytes()) 42 } 43 44 const ( 45 // ScalarSize is the size of the scalar input to X25519. 46 ScalarSize = 32 47 // PointSize is the size of the point input to X25519. 48 PointSize = 32 49 ) 50 51 // Basepoint is the canonical Curve25519 generator. 52 var Basepoint []byte 53 54 var basePoint = [32]byte{9} 55 56 func init() { Basepoint = basePoint[:] } 57 58 // X25519 returns the result of the scalar multiplication (scalar * point), 59 // according to RFC 7748, Section 5. scalar, point and the return value are 60 // slices of 32 bytes. 61 // 62 // scalar can be generated at random, for example with crypto/rand. point should 63 // be either Basepoint or the output of another X25519 call. 64 // 65 // If point is Basepoint (but not if it's a different slice with the same 66 // contents) a precomputed implementation might be used for performance. 67 func X25519(scalar, point []byte) ([]byte, error) { 68 // Outline the body of function, to let the allocation be inlined in the 69 // caller, and possibly avoid escaping to the heap. 70 var dst [32]byte 71 return x25519(&dst, scalar, point) 72 } 73 74 func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { 75 curve := ecdh.X25519() 76 pub, err := curve.NewPublicKey(point) 77 if err != nil { 78 return nil, err 79 } 80 priv, err := curve.NewPrivateKey(scalar) 81 if err != nil { 82 return nil, err 83 } 84 out, err := priv.ECDH(pub) 85 if err != nil { 86 return nil, err 87 } 88 copy(dst[:], out) 89 return dst[:], nil 90 } 91