1 // Copyright (c) 2013-2014 The btcsuite developers
2 // Copyright (c) 2015-2023 The Decred developers
3 // Use of this source code is governed by an ISC
4 // license that can be found in the LICENSE file.
5 6 package secp256k1
7 8 import (
9 "crypto/rand"
10 "io"
11 )
12 13 // SecretKey provides facilities for working with secp256k1 secret keys within
14 // this package and includes functionality such as serializing and parsing them
15 // as well as computing their associated public key.
16 type SecretKey struct {
17 Key ModNScalar
18 }
19 20 // PrivateKey is a secret key.
21 //
22 // Deprecated: use SecretKey - secret = one person; private = two or more (you don't share secret keys!)
23 type PrivateKey = SecretKey
24 25 // NewSecretKey instantiates a new secret key from a scalar encoded as a big integer.
26 func NewSecretKey(key *ModNScalar) *SecretKey { return &SecretKey{Key: *key} }
27 28 // NewPrivateKey instantiates a new secret key from a scalar encoded as a big integer.
29 //
30 // Deprecated: use NewSecretKey - secret = one person; private = two or more (you don't share secret keys!)
31 func NewPrivateKey(key *ModNScalar) *SecretKey { return NewSecretKey(key) }
32 33 // SecKeyFromBytes returns a secret based on the provided byte slice which is
34 // interpreted as an unsigned 256-bit big-endian integer in the range [0, N-1],
35 // where N is the order of the curve.
36 //
37 // WARNING: This means passing a slice with more than 32 bytes is truncated and
38 // that truncated value is reduced modulo N. Further, 0 is not a valid secret
39 // key. It is up to the caller to provide a value in the appropriate range of
40 // [1, N-1]. Failure to do so will either result in an invalid secret key or
41 // potentially weak secret keys that have bias that could be exploited.
42 //
43 // This function primarily exists to provide a mechanism for converting
44 // serialized secret keys that are already known to be good.
45 //
46 // Typically, callers should make use of GenerateSecretKey or
47 // GenerateSecretKeyFromRand when creating secret keys since they properly
48 // handle generation of appropriate values.
49 func SecKeyFromBytes(secKeyBytes []byte) *SecretKey {
50 var secKey SecretKey
51 secKey.Key.SetByteSlice(secKeyBytes)
52 return &secKey
53 }
54 55 func PrivKeyFromBytes(secKeyBytes []byte) *SecretKey { return SecKeyFromBytes(secKeyBytes) }
56 57 // generateSecretKey generates and returns a new secret key that is suitable
58 // for use with secp256k1 using the provided reader as a source of entropy. The
59 // provided reader must be a source of cryptographically secure randomness to
60 // avoid weak secret keys.
61 func generateSecretKey(rand io.Reader) (*SecretKey, error) {
62 // The group order is close enough to 2^256 that there is only roughly a 1
63 // in 2^128 chance of generating an invalid secret key, so this loop will
64 // virtually never run more than a single iteration in practice.
65 var key SecretKey
66 var b32 [32]byte
67 for valid := false; !valid; {
68 if _, err := io.ReadFull(rand, b32[:]); err != nil {
69 return nil, err
70 }
71 // The secret key is only valid when it is in the range [1, N-1], where
72 // N is the order of the curve.
73 overflow := key.Key.SetBytes(&b32)
74 valid = (key.Key.IsZeroBit() | overflow) == 0
75 }
76 zeroArray32(&b32)
77 return &key, nil
78 }
79 80 // GenerateSecretKey generates and returns a new cryptographically secure secret key that is suitable for use with
81 // secp256k1.
82 func GenerateSecretKey() (*SecretKey, error) {
83 return generateSecretKey(rand.Reader())
84 }
85 86 // GeneratePrivateKey generates and returns a new cryptographically secure secret key that is suitable for use with
87 // secp256k1.
88 //
89 // Deprecated: use NewSecretKey - secret = one person; private = two or more (you don't share secret keys!)
90 func GeneratePrivateKey() (*SecretKey, error) { return GenerateSecretKey() }
91 92 // GenerateSecretKeyFromRand generates a secret key that is suitable for use with secp256k1 using the provided reader as
93 // a source of entropy. The provided reader must be a source of cryptographically secure randomness, such as
94 // [crypto/rand.Reader], to avoid weak secret keys.
95 func GenerateSecretKeyFromRand(rand io.Reader) (*SecretKey, error) {
96 return generateSecretKey(rand)
97 }
98 99 // GeneratePrivateKeyFromRand generates a secret key that is suitable for use with secp256k1 using the provided reader as
100 // a source of entropy. The provided reader must be a source of cryptographically secure randomness, such as
101 // [crypto/rand.Reader], to avoid weak secret keys.
102 //
103 // Deprecated: use GenerateSecretKeyFromRand - secret = one person; private = two or more (you don't share secret keys!)
104 func GeneratePrivateKeyFromRand(rand io.Reader) (*SecretKey, error) { return GenerateSecretKeyFromRand(rand) }
105 106 // PubKey computes and returns the public key corresponding to this secret key.
107 func (p *SecretKey) PubKey() *PublicKey {
108 var result JacobianPoint
109 ScalarBaseMultNonConst(&p.Key, &result)
110 result.ToAffine()
111 return NewPublicKey(&result.X, &result.Y)
112 }
113 114 // Zero manually clears the memory associated with the secret key. This can be
115 // used to explicitly clear key material from memory for enhanced security
116 // against memory scraping.
117 func (p *SecretKey) Zero() { p.Key.Zero() }
118 119 // SecKeyBytesLen defines the length in bytes of a serialized secret key.
120 const SecKeyBytesLen = 32
121 122 // Serialize returns the secret key as a 256-bit big-endian binary-encoded
123 // number, padded to a length of 32 bytes.
124 func (p *SecretKey) Serialize() []byte {
125 var secKeyBytes [SecKeyBytesLen]byte
126 p.Key.PutBytes(&secKeyBytes)
127 return secKeyBytes[:]
128 }
129