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