github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/btcutil/hdkeychain/extendedkey.go (about) 1 // Copyright (c) 2014-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package hdkeychain 6 7 // References: 8 // [BIP32]: BIP0032 - Hierarchical Deterministic Wallets 9 // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki 10 11 import ( 12 "bytes" 13 "crypto/hmac" 14 "crypto/rand" 15 "crypto/sha512" 16 "encoding/binary" 17 "errors" 18 "fmt" 19 "github.com/mit-dci/lit/btcutil" 20 "github.com/mit-dci/lit/btcutil/base58" 21 "github.com/mit-dci/lit/btcutil/chaincfg/chainhash" 22 "github.com/mit-dci/lit/coinparam" 23 "github.com/mit-dci/lit/crypto/koblitz" 24 "math/big" 25 ) 26 27 const ( 28 // RecommendedSeedLen is the recommended length in bytes for a seed 29 // to a master node. 30 RecommendedSeedLen = 32 // 256 bits 31 32 // HardenedKeyStart is the index at which a hardended key starts. Each 33 // extended key has 2^31 normal child keys and 2^31 hardned child keys. 34 // Thus the range for normal child keys is [0, 2^31 - 1] and the range 35 // for hardened child keys is [2^31, 2^32 - 1]. 36 HardenedKeyStart = 0x80000000 // 2^31 37 38 // MinSeedBytes is the minimum number of bytes allowed for a seed to 39 // a master node. 40 MinSeedBytes = 16 // 128 bits 41 42 // MaxSeedBytes is the maximum number of bytes allowed for a seed to 43 // a master node. 44 MaxSeedBytes = 64 // 512 bits 45 46 // serializedKeyLen is the length of a serialized public or private 47 // extended key. It consists of 4 bytes version, 1 byte depth, 4 bytes 48 // fingerprint, 4 bytes child number, 32 bytes chain code, and 33 bytes 49 // public/private key data. 50 serializedKeyLen = 4 + 1 + 4 + 4 + 32 + 33 // 78 bytes 51 ) 52 53 var ( 54 // ErrDeriveHardFromPublic describes an error in which the caller 55 // attempted to derive a hardened extended key from a public key. 56 ErrDeriveHardFromPublic = errors.New("cannot derive a hardened key " + 57 "from a public key") 58 59 // ErrNotPrivExtKey describes an error in which the caller attempted 60 // to extract a private key from a public extended key. 61 ErrNotPrivExtKey = errors.New("unable to create private keys from a " + 62 "public extended key") 63 64 // ErrInvalidChild describes an error in which the child at a specific 65 // index is invalid due to the derived key falling outside of the valid 66 // range for secp256k1 private keys. This error indicates the caller 67 // should simply ignore the invalid child extended key at this index and 68 // increment to the next index. 69 ErrInvalidChild = errors.New("the extended key at this index is invalid") 70 71 // ErrUnusableSeed describes an error in which the provided seed is not 72 // usable due to the derived key falling outside of the valid range for 73 // secp256k1 private keys. This error indicates the caller must choose 74 // another seed. 75 ErrUnusableSeed = errors.New("unusable seed") 76 77 // ErrInvalidSeedLen describes an error in which the provided seed or 78 // seed length is not in the allowed range. 79 ErrInvalidSeedLen = fmt.Errorf("seed length must be between %d and %d "+ 80 "bits", MinSeedBytes*8, MaxSeedBytes*8) 81 82 // ErrBadChecksum describes an error in which the checksum encoded with 83 // a serialized extended key does not match the calculated value. 84 ErrBadChecksum = errors.New("bad extended key checksum") 85 86 // ErrInvalidKeyLen describes an error in which the provided serialized 87 // key is not the expected length. 88 ErrInvalidKeyLen = errors.New("the provided serialized extended key " + 89 "length is invalid") 90 ) 91 92 // masterKey is the master key used along with a random seed used to generate 93 // the master node in the hierarchical tree. 94 var masterKey = []byte("Bitcoin seed") 95 96 // ExtendedKey houses all the information needed to support a hierarchical 97 // deterministic extended key. See the package overview documentation for 98 // more details on how to use extended keys. 99 type ExtendedKey struct { 100 key []byte // This will be the pubkey for extended pub keys 101 pubKey []byte // This will only be set for extended priv keys 102 chainCode []byte 103 depth uint16 104 parentFP []byte 105 childNum uint32 106 version []byte 107 isPrivate bool 108 } 109 110 // newExtendedKey returns a new instance of an extended key with the given 111 // fields. No error checking is performed here as it's only intended to be a 112 // convenience method used to create a populated struct. 113 func newExtendedKey(version, key, chainCode, parentFP []byte, depth uint16, 114 childNum uint32, isPrivate bool) *ExtendedKey { 115 116 // NOTE: The pubKey field is intentionally left nil so it is only 117 // computed and memoized as required. 118 return &ExtendedKey{ 119 key: key, 120 chainCode: chainCode, 121 depth: depth, 122 parentFP: parentFP, 123 childNum: childNum, 124 version: version, 125 isPrivate: isPrivate, 126 } 127 } 128 129 // pubKeyBytes returns bytes for the serialized compressed public key associated 130 // with this extended key in an efficient manner including memoization as 131 // necessary. 132 // 133 // When the extended key is already a public key, the key is simply returned as 134 // is since it's already in the correct form. However, when the extended key is 135 // a private key, the public key will be calculated and memoized so future 136 // accesses can simply return the cached result. 137 func (k *ExtendedKey) pubKeyBytes() []byte { 138 // Just return the key if it's already an extended public key. 139 if !k.isPrivate { 140 return k.key 141 } 142 143 // This is a private extended key, so calculate and memoize the public 144 // key if needed. 145 if len(k.pubKey) == 0 { 146 pkx, pky := koblitz.S256().ScalarBaseMult(k.key) 147 pubKey := koblitz.PublicKey{Curve: koblitz.S256(), X: pkx, Y: pky} 148 k.pubKey = pubKey.SerializeCompressed() 149 } 150 151 return k.pubKey 152 } 153 154 // IsPrivate returns whether or not the extended key is a private extended key. 155 // 156 // A private extended key can be used to derive both hardened and non-hardened 157 // child private and public extended keys. A public extended key can only be 158 // used to derive non-hardened child public extended keys. 159 func (k *ExtendedKey) IsPrivate() bool { 160 return k.isPrivate 161 } 162 163 // ParentFingerprint returns a fingerprint of the parent extended key from which 164 // this one was derived. 165 func (k *ExtendedKey) ParentFingerprint() uint32 { 166 return binary.BigEndian.Uint32(k.parentFP) 167 } 168 169 // Child returns a derived child extended key at the given index. When this 170 // extended key is a private extended key (as determined by the IsPrivate 171 // function), a private extended key will be derived. Otherwise, the derived 172 // extended key will be also be a public extended key. 173 // 174 // When the index is greater to or equal than the HardenedKeyStart constant, the 175 // derived extended key will be a hardened extended key. It is only possible to 176 // derive a hardended extended key from a private extended key. Consequently, 177 // this function will return ErrDeriveHardFromPublic if a hardened child 178 // extended key is requested from a public extended key. 179 // 180 // A hardened extended key is useful since, as previously mentioned, it requires 181 // a parent private extended key to derive. In other words, normal child 182 // extended public keys can be derived from a parent public extended key (no 183 // knowledge of the parent private key) whereas hardened extended keys may not 184 // be. 185 // 186 // NOTE: There is an extremely small chance (< 1 in 2^127) the specific child 187 // index does not derive to a usable child. The ErrInvalidChild error will be 188 // returned if this should occur, and the caller is expected to ignore the 189 // invalid child and simply increment to the next index. 190 func (k *ExtendedKey) Child(i uint32) (*ExtendedKey, error) { 191 // There are four scenarios that could happen here: 192 // 1) Private extended key -> Hardened child private extended key 193 // 2) Private extended key -> Non-hardened child private extended key 194 // 3) Public extended key -> Non-hardened child public extended key 195 // 4) Public extended key -> Hardened child public extended key (INVALID!) 196 197 // Case #4 is invalid, so error out early. 198 // A hardened child extended key may not be created from a public 199 // extended key. 200 isChildHardened := i >= HardenedKeyStart 201 if !k.isPrivate && isChildHardened { 202 return nil, ErrDeriveHardFromPublic 203 } 204 205 // The data used to derive the child key depends on whether or not the 206 // child is hardened per [BIP32]. 207 // 208 // For hardened children: 209 // 0x00 || ser256(parentKey) || ser32(i) 210 // 211 // For normal children: 212 // serP(parentPubKey) || ser32(i) 213 keyLen := 33 214 data := make([]byte, keyLen+4) 215 if isChildHardened { 216 // Case #1. 217 // When the child is a hardened child, the key is known to be a 218 // private key due to the above early return. Pad it with a 219 // leading zero as required by [BIP32] for deriving the child. 220 copy(data[1:], k.key) 221 } else { 222 // Case #2 or #3. 223 // This is either a public or private extended key, but in 224 // either case, the data which is used to derive the child key 225 // starts with the secp256k1 compressed public key bytes. 226 copy(data, k.pubKeyBytes()) 227 } 228 binary.BigEndian.PutUint32(data[keyLen:], i) 229 230 // Take the HMAC-SHA512 of the current key's chain code and the derived 231 // data: 232 // I = HMAC-SHA512(Key = chainCode, Data = data) 233 hmac512 := hmac.New(sha512.New, k.chainCode) 234 hmac512.Write(data) 235 ilr := hmac512.Sum(nil) 236 237 // Split "I" into two 32-byte sequences Il and Ir where: 238 // Il = intermediate key used to derive the child 239 // Ir = child chain code 240 il := ilr[:len(ilr)/2] 241 childChainCode := ilr[len(ilr)/2:] 242 243 // Both derived public or private keys rely on treating the left 32-byte 244 // sequence calculated above (Il) as a 256-bit integer that must be 245 // within the valid range for a secp256k1 private key. There is a small 246 // chance (< 1 in 2^127) this condition will not hold, and in that case, 247 // a child extended key can't be created for this index and the caller 248 // should simply increment to the next index. 249 ilNum := new(big.Int).SetBytes(il) 250 if ilNum.Cmp(koblitz.S256().N) >= 0 || ilNum.Sign() == 0 { 251 return nil, ErrInvalidChild 252 } 253 254 // The algorithm used to derive the child key depends on whether or not 255 // a private or public child is being derived. 256 // 257 // For private children: 258 // childKey = parse256(Il) + parentKey 259 // 260 // For public children: 261 // childKey = serP(point(parse256(Il)) + parentKey) 262 var isPrivate bool 263 var childKey []byte 264 if k.isPrivate { 265 // Case #1 or #2. 266 // Add the parent private key to the intermediate private key to 267 // derive the final child key. 268 // 269 // childKey = parse256(Il) + parenKey 270 keyNum := new(big.Int).SetBytes(k.key) 271 ilNum.Add(ilNum, keyNum) 272 ilNum.Mod(ilNum, koblitz.S256().N) 273 childKey = ilNum.Bytes() 274 isPrivate = true 275 } else { 276 // Case #3. 277 // Calculate the corresponding intermediate public key for 278 // intermediate private key. 279 ilx, ily := koblitz.S256().ScalarBaseMult(il) 280 if ilx.Sign() == 0 || ily.Sign() == 0 { 281 return nil, ErrInvalidChild 282 } 283 284 // Convert the serialized compressed parent public key into X 285 // and Y coordinates so it can be added to the intermediate 286 // public key. 287 pubKey, err := koblitz.ParsePubKey(k.key, koblitz.S256()) 288 if err != nil { 289 return nil, err 290 } 291 292 // Add the intermediate public key to the parent public key to 293 // derive the final child key. 294 // 295 // childKey = serP(point(parse256(Il)) + parentKey) 296 childX, childY := koblitz.S256().Add(ilx, ily, pubKey.X, pubKey.Y) 297 pk := koblitz.PublicKey{Curve: koblitz.S256(), X: childX, Y: childY} 298 childKey = pk.SerializeCompressed() 299 } 300 301 // The fingerprint of the parent for the derived child is the first 4 302 // bytes of the RIPEMD160(SHA256(parentPubKey)). 303 parentFP := btcutil.Hash160(k.pubKeyBytes())[:4] 304 return newExtendedKey(k.version, childKey, childChainCode, parentFP, 305 k.depth+1, i, isPrivate), nil 306 } 307 308 // Neuter returns a new extended public key from this extended private key. The 309 // same extended key will be returned unaltered if it is already an extended 310 // public key. 311 // 312 // As the name implies, an extended public key does not have access to the 313 // private key, so it is not capable of signing transactions or deriving 314 // child extended private keys. However, it is capable of deriving further 315 // child extended public keys. 316 func (k *ExtendedKey) Neuter() (*ExtendedKey, error) { 317 // Already an extended public key. 318 if !k.isPrivate { 319 return k, nil 320 } 321 322 // Get the associated public extended key version bytes. 323 version, err := coinparam.HDPrivateKeyToPublicKeyID(k.version) 324 if err != nil { 325 return nil, err 326 } 327 328 // Convert it to an extended public key. The key for the new extended 329 // key will simply be the pubkey of the current extended private key. 330 // 331 // This is the function N((k,c)) -> (K, c) from [BIP32]. 332 return newExtendedKey(version, k.pubKeyBytes(), k.chainCode, k.parentFP, 333 k.depth, k.childNum, false), nil 334 } 335 336 // ECPubKey converts the extended key to a koblitz public key and returns it. 337 func (k *ExtendedKey) ECPubKey() (*koblitz.PublicKey, error) { 338 return koblitz.ParsePubKey(k.pubKeyBytes(), koblitz.S256()) 339 } 340 341 // ECPrivKey converts the extended key to a koblitz private key and returns it. 342 // As you might imagine this is only possible if the extended key is a private 343 // extended key (as determined by the IsPrivate function). The ErrNotPrivExtKey 344 // error will be returned if this function is called on a public extended key. 345 func (k *ExtendedKey) ECPrivKey() (*koblitz.PrivateKey, error) { 346 if !k.isPrivate { 347 return nil, ErrNotPrivExtKey 348 } 349 350 privKey, _ := koblitz.PrivKeyFromBytes(koblitz.S256(), k.key) 351 return privKey, nil 352 } 353 354 // Address converts the extended key to a standard bitcoin pay-to-pubkey-hash 355 // address for the passed network. 356 func (k *ExtendedKey) Address(net *coinparam.Params) (*btcutil.AddressPubKeyHash, error) { 357 pkHash := btcutil.Hash160(k.pubKeyBytes()) 358 return btcutil.NewAddressPubKeyHash(pkHash, net) 359 } 360 361 // paddedAppend appends the src byte slice to dst, returning the new slice. 362 // If the length of the source is smaller than the passed size, leading zero 363 // bytes are appended to the dst slice before appending src. 364 func paddedAppend(size uint, dst, src []byte) []byte { 365 for i := 0; i < int(size)-len(src); i++ { 366 dst = append(dst, 0) 367 } 368 return append(dst, src...) 369 } 370 371 // String returns the extended key as a human-readable base58-encoded string. 372 func (k *ExtendedKey) String() string { 373 if len(k.key) == 0 { 374 return "zeroed extended key" 375 } 376 377 var childNumBytes [4]byte 378 depthByte := byte(k.depth % 256) 379 binary.BigEndian.PutUint32(childNumBytes[:], k.childNum) 380 381 // The serialized format is: 382 // version (4) || depth (1) || parent fingerprint (4)) || 383 // child num (4) || chain code (32) || key data (33) || checksum (4) 384 serializedBytes := make([]byte, 0, serializedKeyLen+4) 385 serializedBytes = append(serializedBytes, k.version...) 386 serializedBytes = append(serializedBytes, depthByte) 387 serializedBytes = append(serializedBytes, k.parentFP...) 388 serializedBytes = append(serializedBytes, childNumBytes[:]...) 389 serializedBytes = append(serializedBytes, k.chainCode...) 390 if k.isPrivate { 391 serializedBytes = append(serializedBytes, 0x00) 392 serializedBytes = paddedAppend(32, serializedBytes, k.key) 393 } else { 394 serializedBytes = append(serializedBytes, k.pubKeyBytes()...) 395 } 396 397 checkSum := chainhash.DoubleHashB(serializedBytes)[:4] 398 serializedBytes = append(serializedBytes, checkSum...) 399 return base58.Encode(serializedBytes) 400 } 401 402 // IsForNet returns whether or not the extended key is associated with the 403 // passed bitcoin network. 404 func (k *ExtendedKey) IsForNet(net *coinparam.Params) bool { 405 return bytes.Equal(k.version, net.HDPrivateKeyID[:]) || 406 bytes.Equal(k.version, net.HDPublicKeyID[:]) 407 } 408 409 // SetNet associates the extended key, and any child keys yet to be derived from 410 // it, with the passed network. 411 func (k *ExtendedKey) SetNet(net *coinparam.Params) { 412 if k.isPrivate { 413 k.version = net.HDPrivateKeyID[:] 414 } else { 415 k.version = net.HDPublicKeyID[:] 416 } 417 } 418 419 // zero sets all bytes in the passed slice to zero. This is used to 420 // explicitly clear private key material from memory. 421 func zero(b []byte) { 422 lenb := len(b) 423 for i := 0; i < lenb; i++ { 424 b[i] = 0 425 } 426 } 427 428 // Zero manually clears all fields and bytes in the extended key. This can be 429 // used to explicitly clear key material from memory for enhanced security 430 // against memory scraping. This function only clears this particular key and 431 // not any children that have already been derived. 432 func (k *ExtendedKey) Zero() { 433 zero(k.key) 434 zero(k.pubKey) 435 zero(k.chainCode) 436 zero(k.parentFP) 437 k.version = nil 438 k.key = nil 439 k.depth = 0 440 k.childNum = 0 441 k.isPrivate = false 442 } 443 444 // NewMaster creates a new master node for use in creating a hierarchical 445 // deterministic key chain. The seed must be between 128 and 512 bits and 446 // should be generated by a cryptographically secure random generation source. 447 // 448 // NOTE: There is an extremely small chance (< 1 in 2^127) the provided seed 449 // will derive to an unusable secret key. The ErrUnusable error will be 450 // returned if this should occur, so the caller must check for it and generate a 451 // new seed accordingly. 452 func NewMaster(seed []byte, net *coinparam.Params) (*ExtendedKey, error) { 453 // Per [BIP32], the seed must be in range [MinSeedBytes, MaxSeedBytes]. 454 if len(seed) < MinSeedBytes || len(seed) > MaxSeedBytes { 455 return nil, ErrInvalidSeedLen 456 } 457 458 // First take the HMAC-SHA512 of the master key and the seed data: 459 // I = HMAC-SHA512(Key = "Bitcoin seed", Data = S) 460 hmac512 := hmac.New(sha512.New, masterKey) 461 hmac512.Write(seed) 462 lr := hmac512.Sum(nil) 463 464 // Split "I" into two 32-byte sequences Il and Ir where: 465 // Il = master secret key 466 // Ir = master chain code 467 secretKey := lr[:len(lr)/2] 468 chainCode := lr[len(lr)/2:] 469 470 // Ensure the key in usable. 471 secretKeyNum := new(big.Int).SetBytes(secretKey) 472 if secretKeyNum.Cmp(koblitz.S256().N) >= 0 || secretKeyNum.Sign() == 0 { 473 return nil, ErrUnusableSeed 474 } 475 476 parentFP := []byte{0x00, 0x00, 0x00, 0x00} 477 return newExtendedKey(net.HDPrivateKeyID[:], secretKey, chainCode, 478 parentFP, 0, 0, true), nil 479 } 480 481 // NewKeyFromString returns a new extended key instance from a base58-encoded 482 // extended key. 483 func NewKeyFromString(key string) (*ExtendedKey, error) { 484 // The base58-decoded extended key must consist of a serialized payload 485 // plus an additional 4 bytes for the checksum. 486 decoded := base58.Decode(key) 487 if len(decoded) != serializedKeyLen+4 { 488 return nil, ErrInvalidKeyLen 489 } 490 491 // The serialized format is: 492 // version (4) || depth (1) || parent fingerprint (4)) || 493 // child num (4) || chain code (32) || key data (33) || checksum (4) 494 495 // Split the payload and checksum up and ensure the checksum matches. 496 payload := decoded[:len(decoded)-4] 497 checkSum := decoded[len(decoded)-4:] 498 expectedCheckSum := chainhash.DoubleHashB(payload)[:4] 499 if !bytes.Equal(checkSum, expectedCheckSum) { 500 return nil, ErrBadChecksum 501 } 502 503 // Deserialize each of the payload fields. 504 version := payload[:4] 505 depth := uint16(payload[4:5][0]) 506 parentFP := payload[5:9] 507 childNum := binary.BigEndian.Uint32(payload[9:13]) 508 chainCode := payload[13:45] 509 keyData := payload[45:78] 510 511 // The key data is a private key if it starts with 0x00. Serialized 512 // compressed pubkeys either start with 0x02 or 0x03. 513 isPrivate := keyData[0] == 0x00 514 if isPrivate { 515 // Ensure the private key is valid. It must be within the range 516 // of the order of the secp256k1 curve and not be 0. 517 keyData = keyData[1:] 518 keyNum := new(big.Int).SetBytes(keyData) 519 if keyNum.Cmp(koblitz.S256().N) >= 0 || keyNum.Sign() == 0 { 520 return nil, ErrUnusableSeed 521 } 522 } else { 523 // Ensure the public key parses correctly and is actually on the 524 // secp256k1 curve. 525 _, err := koblitz.ParsePubKey(keyData, koblitz.S256()) 526 if err != nil { 527 return nil, err 528 } 529 } 530 531 return newExtendedKey(version, keyData, chainCode, parentFP, depth, 532 childNum, isPrivate), nil 533 } 534 535 // GenerateSeed returns a cryptographically secure random seed that can be used 536 // as the input for the NewMaster function to generate a new master node. 537 // 538 // The length is in bytes and it must be between 16 and 64 (128 to 512 bits). 539 // The recommended length is 32 (256 bits) as defined by the RecommendedSeedLen 540 // constant. 541 func GenerateSeed(length uint8) ([]byte, error) { 542 // Per [BIP32], the seed must be in range [MinSeedBytes, MaxSeedBytes]. 543 if length < MinSeedBytes || length > MaxSeedBytes { 544 return nil, ErrInvalidSeedLen 545 } 546 547 buf := make([]byte, length) 548 _, err := rand.Read(buf) 549 if err != nil { 550 return nil, err 551 } 552 553 return buf, nil 554 }