9 "github.com/bytom/crypto/ed25519"
10 "github.com/bytom/crypto/ed25519/ecmath"
14 //XPrv external private key
16 //XPub external public key
20 // NewXPrv takes a source of random bytes and produces a new XPrv.
21 // If r is nil, crypto/rand.Reader is used.
22 func NewXPrv(r io.Reader) (xprv XPrv, err error) {
27 _, err = io.ReadFull(r, entropy[:])
31 return RootXPrv(entropy[:]), nil
34 // RootXPrv takes a seed binary string and produces a new xprv.
35 func RootXPrv(seed []byte) (xprv XPrv) {
36 h := hmac.New(sha512.New, []byte{'R', 'o', 'o', 't'})
39 pruneRootScalar(xprv[:32])
43 // XPub derives an extended public key from a given xprv.
44 func (xprv XPrv) XPub() (xpub XPub) {
45 var scalar ecmath.Scalar
46 copy(scalar[:], xprv[:32])
52 copy(xpub[:32], buf[:])
53 copy(xpub[32:], xprv[32:])
58 // Child derives a child xprv based on `selector` string and `hardened` flag.
59 // If `hardened` is false, child xpub can be derived independently
60 // from the parent xpub without using the parent xprv.
61 // If `hardened` is true, child key can only be derived from the parent xprv.
62 func (xprv XPrv) Child(sel []byte, hardened bool) XPrv {
64 return xprv.hardenedChild(sel)
66 return xprv.nonhardenedChild(sel)
69 func (xprv XPrv) hardenedChild(sel []byte) (res XPrv) {
70 h := hmac.New(sha512.New, xprv[32:])
75 pruneRootScalar(res[:32])
79 func (xprv XPrv) nonhardenedChild(sel []byte) (res XPrv) {
82 h := hmac.New(sha512.New, xpub[32:])
88 pruneIntermediateScalar(res[:32])
90 // Unrolled the following loop:
93 // for i := 0; i < 32; i++ {
94 // sum := int(xprv[i]) + int(res[i]) + carry
95 // res[i] = byte(sum & 0xff)
101 sum = int(xprv[0]) + int(res[0]) + (sum >> 8)
102 res[0] = byte(sum & 0xff)
103 sum = int(xprv[1]) + int(res[1]) + (sum >> 8)
104 res[1] = byte(sum & 0xff)
105 sum = int(xprv[2]) + int(res[2]) + (sum >> 8)
106 res[2] = byte(sum & 0xff)
107 sum = int(xprv[3]) + int(res[3]) + (sum >> 8)
108 res[3] = byte(sum & 0xff)
109 sum = int(xprv[4]) + int(res[4]) + (sum >> 8)
110 res[4] = byte(sum & 0xff)
111 sum = int(xprv[5]) + int(res[5]) + (sum >> 8)
112 res[5] = byte(sum & 0xff)
113 sum = int(xprv[6]) + int(res[6]) + (sum >> 8)
114 res[6] = byte(sum & 0xff)
115 sum = int(xprv[7]) + int(res[7]) + (sum >> 8)
116 res[7] = byte(sum & 0xff)
117 sum = int(xprv[8]) + int(res[8]) + (sum >> 8)
118 res[8] = byte(sum & 0xff)
119 sum = int(xprv[9]) + int(res[9]) + (sum >> 8)
120 res[9] = byte(sum & 0xff)
121 sum = int(xprv[10]) + int(res[10]) + (sum >> 8)
122 res[10] = byte(sum & 0xff)
123 sum = int(xprv[11]) + int(res[11]) + (sum >> 8)
124 res[11] = byte(sum & 0xff)
125 sum = int(xprv[12]) + int(res[12]) + (sum >> 8)
126 res[12] = byte(sum & 0xff)
127 sum = int(xprv[13]) + int(res[13]) + (sum >> 8)
128 res[13] = byte(sum & 0xff)
129 sum = int(xprv[14]) + int(res[14]) + (sum >> 8)
130 res[14] = byte(sum & 0xff)
131 sum = int(xprv[15]) + int(res[15]) + (sum >> 8)
132 res[15] = byte(sum & 0xff)
133 sum = int(xprv[16]) + int(res[16]) + (sum >> 8)
134 res[16] = byte(sum & 0xff)
135 sum = int(xprv[17]) + int(res[17]) + (sum >> 8)
136 res[17] = byte(sum & 0xff)
137 sum = int(xprv[18]) + int(res[18]) + (sum >> 8)
138 res[18] = byte(sum & 0xff)
139 sum = int(xprv[19]) + int(res[19]) + (sum >> 8)
140 res[19] = byte(sum & 0xff)
141 sum = int(xprv[20]) + int(res[20]) + (sum >> 8)
142 res[20] = byte(sum & 0xff)
143 sum = int(xprv[21]) + int(res[21]) + (sum >> 8)
144 res[21] = byte(sum & 0xff)
145 sum = int(xprv[22]) + int(res[22]) + (sum >> 8)
146 res[22] = byte(sum & 0xff)
147 sum = int(xprv[23]) + int(res[23]) + (sum >> 8)
148 res[23] = byte(sum & 0xff)
149 sum = int(xprv[24]) + int(res[24]) + (sum >> 8)
150 res[24] = byte(sum & 0xff)
151 sum = int(xprv[25]) + int(res[25]) + (sum >> 8)
152 res[25] = byte(sum & 0xff)
153 sum = int(xprv[26]) + int(res[26]) + (sum >> 8)
154 res[26] = byte(sum & 0xff)
155 sum = int(xprv[27]) + int(res[27]) + (sum >> 8)
156 res[27] = byte(sum & 0xff)
157 sum = int(xprv[28]) + int(res[28]) + (sum >> 8)
158 res[28] = byte(sum & 0xff)
159 sum = int(xprv[29]) + int(res[29]) + (sum >> 8)
160 res[29] = byte(sum & 0xff)
161 sum = int(xprv[30]) + int(res[30]) + (sum >> 8)
162 res[30] = byte(sum & 0xff)
163 sum = int(xprv[31]) + int(res[31]) + (sum >> 8)
164 res[31] = byte(sum & 0xff)
167 panic("sum does not fit in 256-bit int")
172 // Child derives a child xpub based on `selector` string.
173 // The corresponding child xprv can be derived from the parent xprv
174 // using non-hardened derivation: `parentxprv.Child(sel, false)`.
175 func (xpub XPub) Child(sel []byte) (res XPub) {
176 h := hmac.New(sha512.New, xpub[32:])
182 pruneIntermediateScalar(res[:32])
195 copy(pubkey[:], xpub[:32])
196 _, ok := P.Decode(pubkey)
198 panic("XPub should have been validated on initialization")
203 copy(res[:32], pubkey[:])
208 // Derive generates a child xprv by recursively deriving
209 // non-hardened child xprvs over the list of selectors:
210 // `Derive([a,b,c,...]) == Child(a).Child(b).Child(c)...`
211 func (xprv XPrv) Derive(path [][]byte) XPrv {
213 for _, p := range path {
214 res = res.Child(p, false)
219 // Derive generates a child xpub by recursively deriving
220 // non-hardened child xpubs over the list of selectors:
221 // `Derive([a,b,c,...]) == Child(a).Child(b).Child(c)...`
222 func (xpub XPub) Derive(path [][]byte) XPub {
224 for _, p := range path {
230 // Sign creates an EdDSA signature using expanded private key
231 // derived from the xprv.
232 func (xprv XPrv) Sign(msg []byte) []byte {
233 return Ed25519InnerSign(xprv.ExpandedPrivateKey(), msg)
236 // Verify checks an EdDSA signature using public key
237 // extracted from the first 32 bytes of the xpub.
238 func (xpub XPub) Verify(msg []byte, sig []byte) bool {
239 return ed25519.Verify(xpub.PublicKey(), msg, sig)
242 // ExpandedPrivateKey generates a 64-byte key where
243 // the first half is the scalar copied from xprv,
244 // and the second half is the `prefix` is generated via PRF
246 func (xprv XPrv) ExpandedPrivateKey() ExpandedPrivateKey {
248 h := hmac.New(sha512.New, []byte{'E', 'x', 'p', 'a', 'n', 'd'})
251 copy(res[:32], xprv[:32])
255 // PublicKey extracts the ed25519 public key from an xpub.
256 func (xpub XPub) PublicKey() ed25519.PublicKey {
257 return ed25519.PublicKey(xpub[:32])
260 // s must be >= 32 bytes long and gets rewritten in place.
261 // This is NOT the same pruning as in Ed25519: it additionally clears the third
262 // highest bit to ensure subkeys do not overflow the second highest bit.
263 func pruneRootScalar(s []byte) {
265 s[31] &= 31 // clear top 3 bits
266 s[31] |= 64 // set second highest bit
269 // Clears lowest 3 bits and highest 23 bits of `f`.
270 func pruneIntermediateScalar(f []byte) {
271 f[0] &= 248 // clear bottom 3 bits
272 f[29] &= 1 // clear 7 high bits
273 f[30] = 0 // clear 8 bits
274 f[31] = 0 // clear 8 bits